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