Index: compiler-rt/trunk/lib/gwp_asan/optional/backtrace.h =================================================================== --- compiler-rt/trunk/lib/gwp_asan/optional/backtrace.h +++ compiler-rt/trunk/lib/gwp_asan/optional/backtrace.h @@ -17,7 +17,9 @@ // and backtrace printing functions when RTGwpAsanBacktraceLibc or // RTGwpAsanBacktraceSanitizerCommon are linked. Use these functions to get the // backtrace function for populating the Options::Backtrace and -// Options::PrintBacktrace when initialising the GuardedPoolAllocator. +// Options::PrintBacktrace when initialising the GuardedPoolAllocator. Please +// note any thread-safety descriptions for the implementation of these functions +// that you use. Backtrace_t getBacktraceFunction(); PrintBacktrace_t getPrintBacktraceFunction(); } // namespace options Index: compiler-rt/trunk/lib/gwp_asan/optional/backtrace_sanitizer_common.cpp =================================================================== --- compiler-rt/trunk/lib/gwp_asan/optional/backtrace_sanitizer_common.cpp +++ compiler-rt/trunk/lib/gwp_asan/optional/backtrace_sanitizer_common.cpp @@ -13,6 +13,9 @@ #include "gwp_asan/optional/backtrace.h" #include "gwp_asan/options.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_flag_parser.h" +#include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_stacktrace.h" void __sanitizer::BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, @@ -58,7 +61,18 @@ namespace gwp_asan { namespace options { -Backtrace_t getBacktraceFunction() { return Backtrace; } +// This function is thread-compatible. It must be synchronised in respect to any +// other calls to getBacktraceFunction(), calls to getPrintBacktraceFunction(), +// and calls to either of the functions that they return. Furthermore, this may +// require synchronisation with any calls to sanitizer_common that use flags. +// Generally, this function will be called during the initialisation of the +// allocator, which is done in a thread-compatible manner. +Backtrace_t getBacktraceFunction() { + // The unwinder requires the default flags to be set. + __sanitizer::SetCommonFlagsDefaults(); + __sanitizer::InitializeCommonFlags(); + return Backtrace; +} PrintBacktrace_t getPrintBacktraceFunction() { return PrintBacktrace; } } // namespace options } // namespace gwp_asan Index: compiler-rt/trunk/lib/gwp_asan/options.h =================================================================== --- compiler-rt/trunk/lib/gwp_asan/options.h +++ compiler-rt/trunk/lib/gwp_asan/options.h @@ -25,6 +25,7 @@ // 2. pointers: "%p" // 3. strings: "%[-]([0-9]*)?(\\.\\*)?s" // 4. chars: "%c" +// This function must be implemented in a signal-safe manner. // =================================== Notes =================================== // This function has a slightly different signature than the C standard // library's printf(). Notably, it returns 'void' rather than 'int'. Index: compiler-rt/trunk/lib/gwp_asan/tests/CMakeLists.txt =================================================================== --- compiler-rt/trunk/lib/gwp_asan/tests/CMakeLists.txt +++ compiler-rt/trunk/lib/gwp_asan/tests/CMakeLists.txt @@ -8,7 +8,17 @@ -g) file(GLOB GWP_ASAN_HEADERS ../*.h) -file(GLOB GWP_ASAN_UNITTESTS *.cpp) +set(GWP_ASAN_UNITTESTS + optional/printf_sanitizer_common.cpp + alignment.cpp + backtrace.cpp + basic.cpp + compression.cpp + driver.cpp + mutex_test.cpp + slot_reuse.cpp + thread_contention.cpp) + set(GWP_ASAN_UNIT_TEST_HEADERS ${GWP_ASAN_HEADERS} harness.h) @@ -28,11 +38,9 @@ set(GWP_ASAN_TEST_RUNTIME RTGwpAsanTest.${arch}) - # RTSanitizerCommonNoTermination(NoLibc) required for __sanitizer::Printf. set(GWP_ASAN_TEST_RUNTIME_OBJECTS $ $ - $ $ $ $) Index: compiler-rt/trunk/lib/gwp_asan/tests/harness.h =================================================================== --- compiler-rt/trunk/lib/gwp_asan/tests/harness.h +++ compiler-rt/trunk/lib/gwp_asan/tests/harness.h @@ -9,18 +9,24 @@ #ifndef GWP_ASAN_TESTS_HARNESS_H_ #define GWP_ASAN_TESTS_HARNESS_H_ -#include "gtest/gtest.h" +#include -// Include sanitizer_common first as gwp_asan/guarded_pool_allocator.h -// transiently includes definitions.h, which overwrites some of the definitions -// in sanitizer_common. -#include "sanitizer_common/sanitizer_common.h" +#include "gtest/gtest.h" #include "gwp_asan/guarded_pool_allocator.h" #include "gwp_asan/optional/backtrace.h" -#include "gwp_asan/optional/options_parser.h" #include "gwp_asan/options.h" +namespace gwp_asan { +namespace test { +// This printf-function getter allows other platforms (e.g. Android) to define +// their own signal-safe Printf function. In LLVM, we use +// `optional/printf_sanitizer_common.cpp` which supplies the __sanitizer::Printf +// for this purpose. +options::Printf_t getPrintfFunction(); +}; // namespace test +}; // namespace gwp_asan + class DefaultGuardedPoolAllocator : public ::testing::Test { public: DefaultGuardedPoolAllocator() { @@ -28,7 +34,7 @@ Opts.setDefaults(); MaxSimultaneousAllocations = Opts.MaxSimultaneousAllocations; - Opts.Printf = __sanitizer::Printf; + Opts.Printf = gwp_asan::test::getPrintfFunction(); GPA.init(Opts); } @@ -49,7 +55,7 @@ Opts.MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg; MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg; - Opts.Printf = __sanitizer::Printf; + Opts.Printf = gwp_asan::test::getPrintfFunction(); GPA.init(Opts); } @@ -62,15 +68,10 @@ class BacktraceGuardedPoolAllocator : public ::testing::Test { public: BacktraceGuardedPoolAllocator() { - // Call initOptions to initialise the internal sanitizer_common flags. These - // flags are referenced by the sanitizer_common unwinder, and if left - // uninitialised, they'll unintentionally crash the program. - gwp_asan::options::initOptions(); - gwp_asan::options::Options Opts; Opts.setDefaults(); - Opts.Printf = __sanitizer::Printf; + Opts.Printf = gwp_asan::test::getPrintfFunction(); Opts.Backtrace = gwp_asan::options::getBacktraceFunction(); Opts.PrintBacktrace = gwp_asan::options::getPrintBacktraceFunction(); GPA.init(Opts); Index: compiler-rt/trunk/lib/gwp_asan/tests/optional/printf_sanitizer_common.cpp =================================================================== --- compiler-rt/trunk/lib/gwp_asan/tests/optional/printf_sanitizer_common.cpp +++ compiler-rt/trunk/lib/gwp_asan/tests/optional/printf_sanitizer_common.cpp @@ -0,0 +1,22 @@ +//===-- printf_sanitizer_common.cpp -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_common.h" +#include "gwp_asan/options.h" + +namespace gwp_asan { +namespace test { +// This printf-function getter allows other platforms (e.g. Android) to define +// their own signal-safe Printf function. In LLVM, we use +// `optional/printf_sanitizer_common.cpp` which supplies the __sanitizer::Printf +// for this purpose. +options::Printf_t getPrintfFunction() { + return __sanitizer::Printf; +} +}; // namespace test +}; // namespace gwp_asan