1 //===-- sanitizer_unwind_win.cc -------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// Sanitizer unwind Windows specific functions.
12 //===----------------------------------------------------------------------===//
14 #include "sanitizer_platform.h"
17 #define WIN32_LEAN_AND_MEAN
21 #include "sanitizer_dbghelp.h" // for StackWalk64
22 #include "sanitizer_stacktrace.h"
23 #include "sanitizer_symbolizer.h" // for InitializeDbgHelpIfNeeded
25 using namespace __sanitizer;
28 void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
29 CHECK_GE(max_depth, 2);
30 // FIXME: CaptureStackBackTrace might be too slow for us.
31 // FIXME: Compare with StackWalk64.
32 // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc
33 size = CaptureStackBackTrace(1, Min(max_depth, kStackTraceMax),
34 (void **)&trace_buffer[0], 0);
38 // Skip the RTL frames by searching for the PC in the stacktrace.
39 uptr pc_location = LocatePcInTrace(pc);
40 PopStackFrames(pc_location);
43 void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
45 CONTEXT ctx = *(CONTEXT *)context;
46 STACKFRAME64 stack_frame;
47 memset(&stack_frame, 0, sizeof(stack_frame));
49 InitializeDbgHelpIfNeeded();
53 int machine_type = IMAGE_FILE_MACHINE_AMD64;
54 stack_frame.AddrPC.Offset = ctx.Rip;
55 stack_frame.AddrFrame.Offset = ctx.Rbp;
56 stack_frame.AddrStack.Offset = ctx.Rsp;
58 int machine_type = IMAGE_FILE_MACHINE_I386;
59 stack_frame.AddrPC.Offset = ctx.Eip;
60 stack_frame.AddrFrame.Offset = ctx.Ebp;
61 stack_frame.AddrStack.Offset = ctx.Esp;
63 stack_frame.AddrPC.Mode = AddrModeFlat;
64 stack_frame.AddrFrame.Mode = AddrModeFlat;
65 stack_frame.AddrStack.Mode = AddrModeFlat;
66 while (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(),
67 &stack_frame, &ctx, NULL, SymFunctionTableAccess64,
68 SymGetModuleBase64, NULL) &&
69 size < Min(max_depth, kStackTraceMax)) {
70 trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset;
73 #endif // #if !SANITIZER_GO
75 #endif // SANITIZER_WINDOWS