Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 43 additions & 6 deletions compiler-rt/lib/sanitizer_common/sanitizer_unwind_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,47 @@ void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
trace_buffer[0] = pc;
}

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wframe-larger-than="
#endif
PVOID CALLBACK FallbackFunctionTableAccess(HANDLE hProcess,
DWORD64 dwAddrBase) {
// First try DbgHelp's function.
if (PVOID pResult =
__sanitizer::SymFunctionTableAccess64(hProcess, dwAddrBase)) {
return pResult;
}

// Fall back to RtlLookupFunctionEntry for dynamic code.
// Function registered with RtlAddFunctionTable is not necessarily registered
// with DbgHelp, so this is required to cover some edge cases (e.g. JIT
// compilers can use Rtl* functions).
# if SANITIZER_WINDOWS64
DWORD64 dw64ImageBase = 0;
return RtlLookupFunctionEntry(dwAddrBase, &dw64ImageBase, nullptr);
# else
return nullptr;
# endif
}

DWORD64 CALLBACK FallbackGetModuleBase(HANDLE hProcess, DWORD64 dwAddr) {
if (DWORD64 dwResult = __sanitizer::SymGetModuleBase64(hProcess, dwAddr)) {
return dwResult;
}

// Both GetModuleBase and FunctionTableAccess must provide this fallback,
// otherwise dynamic functions won't be properly unwound.
# if SANITIZER_WINDOWS64
DWORD64 dw64ImageBase = 0;
if (RtlLookupFunctionEntry(dwAddr, &dw64ImageBase, nullptr)) {
return dw64ImageBase;
}
# endif

return 0;
}

# ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wframe-larger-than="
# endif
void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
CHECK(context);
CHECK_GE(max_depth, 2);
Expand Down Expand Up @@ -91,8 +128,8 @@ void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
stack_frame.AddrFrame.Mode = AddrModeFlat;
stack_frame.AddrStack.Mode = AddrModeFlat;
while (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(),
&stack_frame, &ctx, NULL, SymFunctionTableAccess64,
SymGetModuleBase64, NULL) &&
&stack_frame, &ctx, NULL, FallbackFunctionTableAccess,
FallbackGetModuleBase, NULL) &&
size < Min(max_depth, kStackTraceMax)) {
trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset;
}
Expand Down