Skip to content

Commit 575e1e3

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 0293022 commit 575e1e3

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
@@ -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
@@ -56,6 +56,12 @@ POSSIBILITY OF SUCH DAMAGE. */
5656
# endif
5757
#endif
5858

59+
#if defined(__WIN32__) && !defined(__MSYS__) && !defined(__CYGWIN__)
60+
#define NATIVE_WIN32_STACKTRACE 1
61+
#else
62+
#define NATIVE_WIN32_STACKTRACE 0
63+
#endif
64+
5965
#ifndef HAVE_SYNC_FUNCTIONS
6066

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

0 commit comments

Comments
 (0)