Skip to content

Commit 5c3b5d4

Browse files
committed
1) Use a native Windows way to determine the stacktrace; 2) Fix a use of uninitialized bytes in pecoff.c; 3) Fix a use of undefined memory in pecoff.c
1) Note: as we target MINGW here, we still want to look up the symbols via the DWARF method (the native Windows way would be to call the SymFromAddr() function, but that would require .pdb files which MINGW does not produce). Signed-off-by: Johannes Schindelin <[email protected]> 2) This updates the local declaration of `str_size` to always be 4 bytes instead of platform-dependent as its initialization later on only fills in 4 bytes instead of all the bytes of `size_t`. Originally reported as rust-lang/rust#28447 this was fixed in rust-lang/rust#30908 3) In rust-lang/rust#39468 it was discovered that this could cause a crash in libbacktrace due to freeing uninitialized memory, and this specific instance was fixed in rust-lang/rust#39509
1 parent a63d260 commit 5c3b5d4

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

backtrace.c

+40
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,43 @@ unwind (struct _Unwind_Context *context, void *vdata)
9696
return _URC_NO_REASON;
9797
}
9898

99+
#if NATIVE_WIN32_STACKTRACE
100+
static int win32_unwind(struct backtrace_data *bdata)
101+
{
102+
static int initialized;
103+
static USHORT (*RtlCaptureStackBackTrace)(ULONG, ULONG, PVOID*, PULONG);
104+
void *pcs[62];
105+
int i, count;
106+
107+
if (!initialized) {
108+
HMODULE kernel32 =
109+
LoadLibraryExW(L"kernel32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
110+
if (kernel32)
111+
RtlCaptureStackBackTrace =
112+
(void *)GetProcAddress(kernel32, "RtlCaptureStackBackTrace");
113+
initialized = 1;
114+
if (!RtlCaptureStackBackTrace)
115+
return -1;
116+
}
117+
118+
count = RtlCaptureStackBackTrace(2,
119+
sizeof(pcs) / sizeof(pcs[0]), pcs, NULL);
120+
for (i = 0; i < count; i++) {
121+
uintptr_t pc = (uintptr_t)pcs[i];
122+
123+
if (!bdata->can_alloc)
124+
bdata->ret = bdata->callback (bdata->data, pc, NULL, 0, NULL);
125+
else
126+
bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
127+
bdata->error_callback, bdata->data);
128+
if (bdata->ret != 0)
129+
return _URC_END_OF_STACK;
130+
}
131+
132+
return _URC_NO_REASON;
133+
}
134+
#endif
135+
99136
/* Get a stack backtrace. */
100137

101138
int __attribute__((noinline))
@@ -124,6 +161,9 @@ backtrace_full (struct backtrace_state *state, int skip,
124161
bdata.can_alloc = 1;
125162
}
126163

164+
#if NATIVE_WIN32_STACKTRACE
165+
if (win32_unwind(&bdata) < 0)
166+
#endif
127167
_Unwind_Backtrace (unwind, &bdata);
128168
return bdata.ret;
129169
}

fileline.c

+22
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,30 @@ POSSIBILITY OF SUCH DAMAGE. */
5151
#include "internal.h"
5252

5353
#ifndef HAVE_GETEXECNAME
54+
#if defined(__WIN32__) && !defined(__MSYS__) && !defined(__CYGWIN__)
55+
/*
56+
* Windows-specific implementation of getexecname();
57+
* MSYS/Cygwin want to fall back to /proc/self/exe instead.
58+
*/
59+
#define WIN32_LEAN_AND_MEAN
60+
#include <windows.h>
61+
62+
static inline const char *getexecname(void)
63+
{
64+
static char path[32768]; /* Allow for long paths, i.e. do not use MAX_PATH */
65+
66+
switch (GetModuleFileNameA(NULL, path, sizeof(path))) {
67+
case 0:
68+
case sizeof(path):
69+
return NULL;
70+
}
71+
72+
return path;
73+
}
74+
#else
5475
#define getexecname() NULL
5576
#endif
77+
#endif
5678

5779
#if !defined (HAVE_KERN_PROC_ARGS) && !defined (HAVE_KERN_PROC)
5880

internal.h

+6
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ POSSIBILITY OF SUCH DAMAGE. */
6464
# endif
6565
#endif
6666

67+
#if defined(__WIN32__) && !defined(__MSYS__) && !defined(__CYGWIN__)
68+
#define NATIVE_WIN32_STACKTRACE 1
69+
#else
70+
#define NATIVE_WIN32_STACKTRACE 0
71+
#endif
72+
6773
#ifndef HAVE_SYNC_FUNCTIONS
6874

6975
/* Define out the sync functions. These should never be called if

pecoff.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,9 @@ coff_add (struct backtrace_state *state, int descriptor,
595595
const b_coff_section_header *sects;
596596
struct backtrace_view str_view;
597597
int str_view_valid;
598-
size_t str_size;
598+
uint32_t str_size;
599599
off_t str_off;
600-
struct backtrace_view syms_view;
600+
struct backtrace_view syms_view = {0};
601601
off_t syms_off;
602602
size_t syms_size;
603603
int syms_view_valid;

0 commit comments

Comments
 (0)