[GWP-ASan] Split options_parser and backtrace_sanitizer_common.

Summary:
optional/options_parser and optional/backtrace_sanitizer_common are logically
separate components. They both use sanitizer-common to power their
functionality, but there was an unstated implicit dependency that in order for
backtrace_sanitizer_common to function correctly, one had to also use
options_parser.

This was because options_parser called __sanitizer::InitialiseCommonFlags. This
is a requirement for backtrace_sanitizer_common to work, as the sanitizer
unwinder uses the sanitizer_common flags and will SEGV on a null page if
they're not initialised correctly.

This patch removes this hidden dependency. You can now use
backtrace_sanitizer_common without the requirements of options_parser.

This patch also makes the GWP-ASan unit tests only have a soft dependency on
sanitizer-common. The unit tests previously explicitly used
__sanitizer::Printf, which is now provided under
tests/optional/printf_sanitizer_common. This allows Android to build the unit
tests using their own signal-safe printf().

Reviewers: eugenis

Reviewed By: eugenis

Subscribers: srhines, mgorny, #sanitizers, llvm-commits, vlad.tsyrklevich, morehouse

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D66684

llvm-svn: 369825
GitOrigin-RevId: 27d69b2f4f6bf9b09755ae2428a4703eb4a4663b
diff --git a/optional/backtrace.h b/optional/backtrace.h
index 3aad9ea..6c9ee9f 100644
--- a/optional/backtrace.h
+++ b/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
diff --git a/optional/backtrace_sanitizer_common.cpp b/optional/backtrace_sanitizer_common.cpp
index 427ac77..5e07fd6 100644
--- a/optional/backtrace_sanitizer_common.cpp
+++ b/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
diff --git a/options.h b/options.h
index 67a6129..ae3f3d4 100644
--- a/options.h
+++ b/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'.
diff --git a/tests/harness.h b/tests/harness.h
index 136e566..77f7b51 100644
--- a/tests/harness.h
+++ b/tests/harness.h
@@ -9,18 +9,24 @@
 #ifndef GWP_ASAN_TESTS_HARNESS_H_
 #define GWP_ASAN_TESTS_HARNESS_H_
 
-#include "gtest/gtest.h"
+#include <stdarg.h>
 
-// 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);
diff --git a/tests/optional/printf_sanitizer_common.cpp b/tests/optional/printf_sanitizer_common.cpp
new file mode 100644
index 0000000..e823aeb
--- /dev/null
+++ b/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