Merge "Update Android.bp to point to fuzz target."
diff --git a/gwp_asan/optional/backtrace.h b/gwp_asan/optional/backtrace.h
index 3aad9ea..6c9ee9f 100644
--- a/gwp_asan/optional/backtrace.h
+++ b/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
diff --git a/gwp_asan/optional/backtrace_sanitizer_common.cpp b/gwp_asan/optional/backtrace_sanitizer_common.cpp
index 427ac77..5e07fd6 100644
--- a/gwp_asan/optional/backtrace_sanitizer_common.cpp
+++ b/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
diff --git a/gwp_asan/options.h b/gwp_asan/options.h
index 67a6129..ae3f3d4 100644
--- a/gwp_asan/options.h
+++ b/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'.
diff --git a/gwp_asan/options.inc b/gwp_asan/options.inc
index 9042b11..df6c46e 100644
--- a/gwp_asan/options.inc
+++ b/gwp_asan/options.inc
@@ -21,9 +21,9 @@
     "byte buffer-overflows for multibyte allocations at the cost of "
     "performance, and may be incompatible with some architectures.")
 
-GWP_ASAN_OPTION(
-    int, MaxSimultaneousAllocations, 16,
-    "Number of usable guarded slots in the allocation pool. Defaults to 16.")
+GWP_ASAN_OPTION(int, MaxSimultaneousAllocations, 16,
+                "Number of simultaneously-guarded allocations available in the "
+                "pool. Defaults to 16.")
 
 GWP_ASAN_OPTION(int, SampleRate, 5000,
                 "The probability (1 / SampleRate) that an allocation is "
diff --git a/gwp_asan/scripts/symbolize.sh b/gwp_asan/scripts/symbolize.sh
new file mode 100755
index 0000000..fad9620
--- /dev/null
+++ b/gwp_asan/scripts/symbolize.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# The lines that we're looking to symbolize look like this:
+  #0 ./a.out(_foo+0x3e6) [0x55a52e64c696]
+# ... which come from the backtrace_symbols() symbolisation function used by
+# default in Scudo's implementation of GWP-ASan.
+
+while read -r line; do
+  # Check that this line needs symbolization.
+  should_symbolize="$(echo $line |\
+     grep -E '^[ ]*\#.*\(.*\+0x[0-9a-f]+\) \[0x[0-9a-f]+\]$')"
+
+  if [ -z "$should_symbolize" ]; then
+    echo "$line"
+    continue
+  fi
+
+  # Carve up the input line into sections.
+  binary_name="$(echo $line | grep -oE ' .*\(' | rev | cut -c2- | rev |\
+      cut -c2-)"
+  function_name="$(echo $line | grep -oE '\([^+]*' | cut -c2-)"
+  function_offset="$(echo $line | grep -oE '\(.*\)' | grep -oE '\+.*\)' |\
+      cut -c2- | rev | cut -c2- | rev)"
+  frame_number="$(echo $line | grep -oE '\#[0-9]+ ')"
+
+  if [ -z "$function_name" ]; then
+    # If the offset is binary-relative, just resolve that.
+    symbolized="$(echo $function_offset | addr2line -e $binary_name)"
+  else
+    # Otherwise, the offset is function-relative. Get the address of the
+    # function, and add it to the offset, then symbolize.
+    function_addr="0x$(echo $function_offset |\
+       nm --defined-only $binary_name 2> /dev/null |\
+       grep -E " $function_name$" | cut -d' ' -f1)"
+
+    # Check that we could get the function address from nm.
+    if [ -z "$function_addr" ]; then
+      echo "$line"
+      continue
+    fi
+
+    # Add the function address and offset to get the offset into the binary.
+    binary_offset="$(printf "0x%X" "$((function_addr+function_offset))")"
+    symbolized="$(echo $binary_offset | addr2line -e $binary_name)"
+  fi
+
+  # Check that it symbolized properly. If it didn't, output the old line.
+  echo $symbolized | grep -E ".*\?.*:" > /dev/null
+  if [ "$?" -eq "0" ]; then
+    echo "$line"
+    continue
+  else
+    echo "${frame_number}${symbolized}"
+  fi
+done
diff --git a/gwp_asan/tests/harness.h b/gwp_asan/tests/harness.h
index 136e566..77f7b51 100644
--- a/gwp_asan/tests/harness.h
+++ b/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 <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/gwp_asan/tests/optional/printf_sanitizer_common.cpp b/gwp_asan/tests/optional/printf_sanitizer_common.cpp
new file mode 100644
index 0000000..e823aeb
--- /dev/null
+++ b/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
diff --git a/gwp_asan/stack_trace_compressor_fuzzer.cpp b/tools/stack_trace_compressor_fuzzer.cpp
similarity index 100%
rename from gwp_asan/stack_trace_compressor_fuzzer.cpp
rename to tools/stack_trace_compressor_fuzzer.cpp