Skip to content

[ASan] Ensure Symbolize Flag setting on Windows through __asan_default_options() is maintained throughout runtime #132811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 9, 2025
Merged
2 changes: 2 additions & 0 deletions compiler-rt/lib/asan/asan_flags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ void InitializeFlags() {
InitializeDefaultFlags();
ProcessFlags();
ApplyFlags();
if (!common_flags()->symbolize)
Symbolizer::ClearTools();
});

# if CAN_SANITIZE_UB
Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ class Symbolizer final {
/// (if it wasn't already initialized).
static Symbolizer *GetOrInit();
static void LateInitialize();
#if SANITIZER_WINDOWS
static void UpdateSymbolizerTools();
#endif
// Returns a list of symbolized frames for a given address (containing
// all inlined functions, if necessary).
SymbolizedStack *SymbolizePC(uptr address);
Expand Down
13 changes: 13 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ Symbolizer *Symbolizer::GetOrInit() {
return symbolizer_;
}

#if SANITIZER_WINDOWS
// 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::UpdateSymbolizerTools() {
SpinMutexLock l(&init_mu_);
if (!common_flags()->symbolize) {
symbolizer_->tools_.clear();
}
}
#endif

// See sanitizer_symbolizer_markup.cpp.
#if !SANITIZER_SYMBOLIZER_MARKUP

Expand Down
38 changes: 38 additions & 0 deletions compiler-rt/test/asan/TestCases/Windows/symbolize.cpp
Original file line number Diff line number Diff line change
@@ -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 <cstdio>
#include <cstdlib>

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
}