Skip to content

Commit d811bc0

Browse files
committed
Use the native Windows way to determine the stacktrace
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]>
1 parent 817ac63 commit d811bc0

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

backtrace.c

Lines changed: 40 additions & 0 deletions
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
}

internal.h

Lines changed: 6 additions & 0 deletions
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

0 commit comments

Comments
 (0)