Index: lib/sanitizer_common/sanitizer_symbolizer_win.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_win.cc +++ lib/sanitizer_common/sanitizer_symbolizer_win.cc @@ -32,11 +32,17 @@ BlockingMutexLock l(&dbghelp_mu_); if (!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? + if (!TrySymInitialize()) { + // OK, maybe the client app has called SymInitialize already. + // That's a bit unfortunate for us as all the DbgHelp functions are + // single-threaded and we can't coordinate with the app. + // FIXME: Can we stop the other threads at this point? + // Anyways, we have to reconfigure stuff to make sure that SymInitialize + // has all the appropriate options set. + // Cross our fingers and reinitialize DbgHelp. + CHECK(SymCleanup(GetCurrentProcess())); + CHECK(TrySymInitialize()); + } initialized_ = true; } @@ -92,6 +98,12 @@ // FIXME: Implement GetModuleNameAndOffsetForPC(). private: + bool TrySymInitialize() { + SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES); + return SymInitialize(GetCurrentProcess(), 0, TRUE); + // FIXME: We don't call SymCleanup() on exit yet - should we? + } + // All DbgHelp functions are single threaded, so we should use a mutex to // serialize accesses. BlockingMutex dbghelp_mu_; Index: test/asan/TestCases/Windows/report_after_syminitialize.cc =================================================================== --- test/asan/TestCases/Windows/report_after_syminitialize.cc +++ test/asan/TestCases/Windows/report_after_syminitialize.cc @@ -0,0 +1,18 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s + +#include +#include + +int main() { + // Make sure the RTL recovers from "no options enabled" dbghelp setup. + SymSetOptions(0); + + // Make sure the RTL recovers from "fInvadeProcess=FALSE". + if (!SymInitialize(GetCurrentProcess(), 0, FALSE)) + return 42; + + *(int*)0 = 42; + // CHECK: ERROR: AddressSanitizer: access-violation on unknown address + // CHECK-NEXT: {{#0 0x.* in main.*report_after_syminitialize.cc:}}[[@LINE-2]] + // CHECK: AddressSanitizer can not provide additional info. +}