diff options
Diffstat (limited to 'lib/asan/asan_win.cc')
-rw-r--r-- | lib/asan/asan_win.cc | 154 |
1 files changed, 66 insertions, 88 deletions
diff --git a/lib/asan/asan_win.cc b/lib/asan/asan_win.cc index 9e899d5865fa..d8ce050641bc 100644 --- a/lib/asan/asan_win.cc +++ b/lib/asan/asan_win.cc @@ -17,30 +17,29 @@ #include <dbghelp.h> #include <stdlib.h> -#include <new> // FIXME: temporarily needed for placement new in AsanLock. - #include "asan_interceptors.h" #include "asan_internal.h" -#include "asan_lock.h" #include "asan_thread.h" #include "sanitizer_common/sanitizer_libc.h" +#include "sanitizer_common/sanitizer_mutex.h" namespace __asan { // ---------------------- Stacktraces, symbols, etc. ---------------- {{{1 -static AsanLock dbghelp_lock(LINKER_INITIALIZED); +static BlockingMutex dbghelp_lock(LINKER_INITIALIZED); static bool dbghelp_initialized = false; #pragma comment(lib, "dbghelp.lib") -void AsanStackTrace::GetStackTrace(uptr max_s, uptr pc, uptr bp) { - max_size = max_s; +void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) { + (void)fast; + stack->max_size = max_s; void *tmp[kStackTraceMax]; // FIXME: CaptureStackBackTrace might be too slow for us. // FIXME: Compare with StackWalk64. // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc - uptr cs_ret = CaptureStackBackTrace(1, max_size, tmp, 0), - offset = 0; + uptr cs_ret = CaptureStackBackTrace(1, stack->max_size, tmp, 0); + uptr offset = 0; // Skip the RTL frames by searching for the PC in the stacktrace. // FIXME: this doesn't work well for the malloc/free stacks yet. for (uptr i = 0; i < cs_ret; i++) { @@ -50,86 +49,9 @@ void AsanStackTrace::GetStackTrace(uptr max_s, uptr pc, uptr bp) { break; } - size = cs_ret - offset; - for (uptr i = 0; i < size; i++) - trace[i] = (uptr)tmp[i + offset]; -} - -bool __asan_WinSymbolize(const void *addr, char *out_buffer, int buffer_size) { - ScopedLock lock(&dbghelp_lock); - if (!dbghelp_initialized) { - SymSetOptions(SYMOPT_DEFERRED_LOADS | - SYMOPT_UNDNAME | - SYMOPT_LOAD_LINES); - CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE)); - // FIXME: We don't call SymCleanup() on exit yet - should we? - dbghelp_initialized = true; - } - - // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx - char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)]; - PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = MAX_SYM_NAME; - DWORD64 offset = 0; - BOOL got_objname = SymFromAddr(GetCurrentProcess(), - (DWORD64)addr, &offset, symbol); - if (!got_objname) - return false; - - DWORD unused; - IMAGEHLP_LINE64 info; - info.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), - (DWORD64)addr, &unused, &info); - int written = 0; - out_buffer[0] = '\0'; - // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too. - if (got_fileline) { - written += internal_snprintf(out_buffer + written, buffer_size - written, - " %s %s:%d", symbol->Name, - info.FileName, info.LineNumber); - } else { - written += internal_snprintf(out_buffer + written, buffer_size - written, - " %s+0x%p", symbol->Name, offset); - } - return true; -} - -// ---------------------- AsanLock ---------------- {{{1 -enum LockState { - LOCK_UNINITIALIZED = 0, - LOCK_READY = -1, -}; - -AsanLock::AsanLock(LinkerInitialized li) { - // FIXME: see comments in AsanLock::Lock() for the details. - CHECK(li == LINKER_INITIALIZED || owner_ == LOCK_UNINITIALIZED); - - CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_)); - InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_); - owner_ = LOCK_READY; -} - -void AsanLock::Lock() { - if (owner_ == LOCK_UNINITIALIZED) { - // FIXME: hm, global AsanLock objects are not initialized?!? - // This might be a side effect of the clang+cl+link Frankenbuild... - new(this) AsanLock((LinkerInitialized)(LINKER_INITIALIZED + 1)); - - // FIXME: If it turns out the linker doesn't invoke our - // constructors, we should probably manually Lock/Unlock all the global - // locks while we're starting in one thread to avoid double-init races. - } - EnterCriticalSection((LPCRITICAL_SECTION)opaque_storage_); - CHECK(owner_ == LOCK_READY); - owner_ = GetThreadSelf(); -} - -void AsanLock::Unlock() { - CHECK(owner_ == GetThreadSelf()); - owner_ = LOCK_READY; - LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_); + stack->size = cs_ret - offset; + for (uptr i = 0; i < stack->size; i++) + stack->trace[i] = (uptr)tmp[i + offset]; } // ---------------------- TSD ---------------- {{{1 @@ -153,6 +75,10 @@ void AsanTSDSet(void *tsd) { } // ---------------------- Various stuff ---------------- {{{1 +void MaybeReexec() { + // No need to re-exec on Windows. +} + void *AsanDoesNotSupportStaticLinkage() { #if defined(_DEBUG) #error Please build the runtime with a non-debug CRT: /MD or /MT @@ -176,6 +102,58 @@ void AsanPlatformThreadInit() { // Nothing here for now. } +void ReadContextStack(void *context, uptr *stack, uptr *ssize) { + UNIMPLEMENTED(); +} + } // namespace __asan +// ---------------------- Interface ---------------- {{{1 +using namespace __asan; // NOLINT + +extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE NOINLINE +bool __asan_symbolize(const void *addr, char *out_buffer, int buffer_size) { + BlockingMutexLock lock(&dbghelp_lock); + if (!dbghelp_initialized) { + SymSetOptions(SYMOPT_DEFERRED_LOADS | + SYMOPT_UNDNAME | + SYMOPT_LOAD_LINES); + CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE)); + // FIXME: We don't call SymCleanup() on exit yet - should we? + dbghelp_initialized = true; + } + + // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)]; + PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol->MaxNameLen = MAX_SYM_NAME; + DWORD64 offset = 0; + BOOL got_objname = SymFromAddr(GetCurrentProcess(), + (DWORD64)addr, &offset, symbol); + if (!got_objname) + return false; + + DWORD unused; + IMAGEHLP_LINE64 info; + info.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), + (DWORD64)addr, &unused, &info); + int written = 0; + out_buffer[0] = '\0'; + // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too. + if (got_fileline) { + written += internal_snprintf(out_buffer + written, buffer_size - written, + " %s %s:%d", symbol->Name, + info.FileName, info.LineNumber); + } else { + written += internal_snprintf(out_buffer + written, buffer_size - written, + " %s+0x%p", symbol->Name, offset); + } + return true; +} +} // extern "C" + + #endif // _WIN32 |