diff --git a/compiler-rt/lib/asan/asan_flags.cpp b/compiler-rt/lib/asan/asan_flags.cpp index 190a89345dd18..f222ec04a7728 100644 --- a/compiler-rt/lib/asan/asan_flags.cpp +++ b/compiler-rt/lib/asan/asan_flags.cpp @@ -241,6 +241,8 @@ void InitializeFlags() { InitializeDefaultFlags(); ProcessFlags(); ApplyFlags(); + if (!common_flags()->symbolize) + Symbolizer::ClearTools(); }); # if CAN_SANITIZE_UB diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h index bd89dc4e302fc..a98194c81d157 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h @@ -136,6 +136,8 @@ class Symbolizer final { /// (if it wasn't already initialized). static Symbolizer *GetOrInit(); static void LateInitialize(); + static void ClearTools(); + // Returns a list of symbolized frames for a given address (containing // all inlined functions, if necessary). SymbolizedStack *SymbolizePC(uptr address); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp index 565701c85d978..ce3890e06e64d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp @@ -26,6 +26,16 @@ Symbolizer *Symbolizer::GetOrInit() { return symbolizer_; } +// If the 'symbolize' flag is set to 0, it clears the tools +// associated with the symbolizer to prevent unnecessary symbolization and +// resource usage. This is necessary because of the late binding of the +// overridden method, __asan_default_options(). +void Symbolizer::ClearTools() { + SpinMutexLock l(&init_mu_); + if (symbolizer_) + symbolizer_->tools_.clear(); +} + // See sanitizer_symbolizer_markup.cpp. #if !SANITIZER_SYMBOLIZER_MARKUP diff --git a/compiler-rt/test/asan/TestCases/Windows/symbolize.cpp b/compiler-rt/test/asan/TestCases/Windows/symbolize.cpp new file mode 100644 index 0000000000000..5e0b1a4c40dd5 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Windows/symbolize.cpp @@ -0,0 +1,38 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: %env_asan_opts=symbolize=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SYMBOLIZE-OFF +// RUN: %env_asan_opts=symbolize=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SYMBOLIZE-ON + +// RUN: %clangxx_asan -O0 %s -o %t -DUSER_FUNCTION_OFF +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SYMBOLIZE-OFF +// RUN: %env_asan_opts=symbolize=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SYMBOLIZE-OFF +// RUN: %env_asan_opts=symbolize=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SYMBOLIZE-ON + +// RUN: %clangxx_asan -O0 %s -o %t -DUSER_FUNCTION_ON +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SYMBOLIZE-ON +// RUN: %env_asan_opts=symbolize=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SYMBOLIZE-OFF +// RUN: %env_asan_opts=symbolize=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SYMBOLIZE-ON +#if USER_FUNCTION_OFF + +extern "C" __declspec(dllexport) extern const char *__asan_default_options() { + return "symbolize=0"; +} + +#endif + +#if USER_FUNCTION_ON + +extern "C" __declspec(dllexport) extern const char *__asan_default_options() { + return "symbolize=1"; +} + +#endif + +#include +#include + +volatile static int heapBufferOverflowValue = 10; +int main() { + int *array = new int[10]; + heapBufferOverflowValue = array[10]; // CHECK-SYMBOLIZE-ON: symbolize.cpp:36 + return 0; // CHECK-SYMBOLIZE-OFF: symbolize.cpp.tmp+0x +}