1 //===-- asan_win.cc -------------------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of AddressSanitizer, an address sanity checker.
10 // Windows-specific details.
11 //===----------------------------------------------------------------------===//
18 #include "asan_interceptors.h"
19 #include "asan_internal.h"
20 #include "asan_thread.h"
21 #include "sanitizer_common/sanitizer_libc.h"
22 #include "sanitizer_common/sanitizer_mutex.h"
26 // ---------------------- Stacktraces, symbols, etc. ---------------- {{{1
27 static BlockingMutex
dbghelp_lock(LINKER_INITIALIZED
);
28 static bool dbghelp_initialized
= false;
29 #pragma comment(lib, "dbghelp.lib")
31 void GetStackTrace(StackTrace
*stack
, uptr max_s
, uptr pc
, uptr bp
, bool fast
) {
33 stack
->max_size
= max_s
;
34 void *tmp
[kStackTraceMax
];
36 // FIXME: CaptureStackBackTrace might be too slow for us.
37 // FIXME: Compare with StackWalk64.
38 // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc
39 uptr cs_ret
= CaptureStackBackTrace(1, stack
->max_size
, tmp
, 0);
41 // Skip the RTL frames by searching for the PC in the stacktrace.
42 // FIXME: this doesn't work well for the malloc/free stacks yet.
43 for (uptr i
= 0; i
< cs_ret
; i
++) {
44 if (pc
!= (uptr
)tmp
[i
])
50 stack
->size
= cs_ret
- offset
;
51 for (uptr i
= 0; i
< stack
->size
; i
++)
52 stack
->trace
[i
] = (uptr
)tmp
[i
+ offset
];
55 // ---------------------- TSD ---------------- {{{1
56 static bool tsd_key_inited
= false;
58 static __declspec(thread
) void *fake_tsd
= 0;
60 void AsanTSDInit(void (*destructor
)(void *tsd
)) {
61 // FIXME: we're ignoring the destructor for now.
62 tsd_key_inited
= true;
66 CHECK(tsd_key_inited
);
70 void AsanTSDSet(void *tsd
) {
71 CHECK(tsd_key_inited
);
75 // ---------------------- Various stuff ---------------- {{{1
77 // No need to re-exec on Windows.
80 void *AsanDoesNotSupportStaticLinkage() {
82 #error Please build the runtime with a non-debug CRT: /MD or /MT
87 void SetAlternateSignalStack() {
88 // FIXME: Decide what to do on Windows.
91 void UnsetAlternateSignalStack() {
92 // FIXME: Decide what to do on Windows.
95 void InstallSignalHandlers() {
96 // FIXME: Decide what to do on Windows.
99 void AsanPlatformThreadInit() {
100 // Nothing here for now.
103 void ReadContextStack(void *context
, uptr
*stack
, uptr
*ssize
) {
107 } // namespace __asan
109 // ---------------------- Interface ---------------- {{{1
110 using namespace __asan
; // NOLINT
113 SANITIZER_INTERFACE_ATTRIBUTE NOINLINE
114 bool __asan_symbolize(const void *addr
, char *out_buffer
, int buffer_size
) {
115 BlockingMutexLock
lock(&dbghelp_lock
);
116 if (!dbghelp_initialized
) {
117 SymSetOptions(SYMOPT_DEFERRED_LOADS
|
120 CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE
));
121 // FIXME: We don't call SymCleanup() on exit yet - should we?
122 dbghelp_initialized
= true;
125 // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx
126 char buffer
[sizeof(SYMBOL_INFO
) + MAX_SYM_NAME
* sizeof(CHAR
)];
127 PSYMBOL_INFO symbol
= (PSYMBOL_INFO
)buffer
;
128 symbol
->SizeOfStruct
= sizeof(SYMBOL_INFO
);
129 symbol
->MaxNameLen
= MAX_SYM_NAME
;
131 BOOL got_objname
= SymFromAddr(GetCurrentProcess(),
132 (DWORD64
)addr
, &offset
, symbol
);
137 IMAGEHLP_LINE64 info
;
138 info
.SizeOfStruct
= sizeof(IMAGEHLP_LINE64
);
139 BOOL got_fileline
= SymGetLineFromAddr64(GetCurrentProcess(),
140 (DWORD64
)addr
, &unused
, &info
);
142 out_buffer
[0] = '\0';
143 // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too.
145 written
+= internal_snprintf(out_buffer
+ written
, buffer_size
- written
,
146 " %s %s:%d", symbol
->Name
,
147 info
.FileName
, info
.LineNumber
);
149 written
+= internal_snprintf(out_buffer
+ written
, buffer_size
- written
,
150 " %s+0x%p", symbol
->Name
, offset
);