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 //===----------------------------------------------------------------------===//
13 #include "sanitizer_common/sanitizer_platform.h"
20 #include "asan_interceptors.h"
21 #include "asan_internal.h"
22 #include "asan_thread.h"
23 #include "sanitizer_common/sanitizer_libc.h"
24 #include "sanitizer_common/sanitizer_mutex.h"
27 SANITIZER_INTERFACE_ATTRIBUTE
28 int __asan_should_detect_stack_use_after_return() {
30 return __asan_option_detect_stack_use_after_return
;
36 // ---------------------- Stacktraces, symbols, etc. ---------------- {{{1
37 static BlockingMutex
dbghelp_lock(LINKER_INITIALIZED
);
38 static bool dbghelp_initialized
= false;
39 #pragma comment(lib, "dbghelp.lib")
41 // ---------------------- TSD ---------------- {{{1
42 static bool tsd_key_inited
= false;
44 static __declspec(thread
) void *fake_tsd
= 0;
46 void AsanTSDInit(void (*destructor
)(void *tsd
)) {
47 // FIXME: we're ignoring the destructor for now.
48 tsd_key_inited
= true;
52 CHECK(tsd_key_inited
);
56 void AsanTSDSet(void *tsd
) {
57 CHECK(tsd_key_inited
);
61 void PlatformTSDDtor(void *tsd
) {
62 AsanThread::TSDDtor(tsd
);
64 // ---------------------- Various stuff ---------------- {{{1
66 // No need to re-exec on Windows.
69 void *AsanDoesNotSupportStaticLinkage() {
71 #error Please build the runtime with a non-debug CRT: /MD or /MT
76 void SetAlternateSignalStack() {
77 // FIXME: Decide what to do on Windows.
80 void UnsetAlternateSignalStack() {
81 // FIXME: Decide what to do on Windows.
84 void InstallSignalHandlers() {
85 // FIXME: Decide what to do on Windows.
88 void AsanPlatformThreadInit() {
89 // Nothing here for now.
92 void ReadContextStack(void *context
, uptr
*stack
, uptr
*ssize
) {
98 // ---------------------- Interface ---------------- {{{1
99 using namespace __asan
; // NOLINT
102 SANITIZER_INTERFACE_ATTRIBUTE NOINLINE
103 bool __asan_symbolize(const void *addr
, char *out_buffer
, int buffer_size
) {
104 BlockingMutexLock
lock(&dbghelp_lock
);
105 if (!dbghelp_initialized
) {
106 SymSetOptions(SYMOPT_DEFERRED_LOADS
|
109 CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE
));
110 // FIXME: We don't call SymCleanup() on exit yet - should we?
111 dbghelp_initialized
= true;
114 // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx
115 char buffer
[sizeof(SYMBOL_INFO
) + MAX_SYM_NAME
* sizeof(CHAR
)];
116 PSYMBOL_INFO symbol
= (PSYMBOL_INFO
)buffer
;
117 symbol
->SizeOfStruct
= sizeof(SYMBOL_INFO
);
118 symbol
->MaxNameLen
= MAX_SYM_NAME
;
120 BOOL got_objname
= SymFromAddr(GetCurrentProcess(),
121 (DWORD64
)addr
, &offset
, symbol
);
126 IMAGEHLP_LINE64 info
;
127 info
.SizeOfStruct
= sizeof(IMAGEHLP_LINE64
);
128 BOOL got_fileline
= SymGetLineFromAddr64(GetCurrentProcess(),
129 (DWORD64
)addr
, &unused
, &info
);
131 out_buffer
[0] = '\0';
132 // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too.
134 written
+= internal_snprintf(out_buffer
+ written
, buffer_size
- written
,
135 " %s %s:%d", symbol
->Name
,
136 info
.FileName
, info
.LineNumber
);
138 written
+= internal_snprintf(out_buffer
+ written
, buffer_size
- written
,
139 " %s+0x%p", symbol
->Name
, offset
);