Snap for 8564071 from 08d235034c8721d98a323ebad3af1329c58e62ec to mainline-os-statsd-release

Change-Id: Ie68f0942ca97e1c1e865a42b7cb1fab780beccdb
diff --git a/Android.bp b/Android.bp
index 4b57e62..5f8c925 100644
--- a/Android.bp
+++ b/Android.bp
@@ -71,7 +71,12 @@
 
     // GWP-ASan is used by bionic libc, and should have no libc/libc++
     // dependencies.
-    system_shared_libs: [],
+    target: {
+        bionic: {
+            system_shared_libs: [],
+            header_libs: ["libc_headers"],
+        },
+    },
     stl: "none",
 }
 
@@ -95,6 +100,7 @@
         "com.android.art.debug",
         "com.android.media",
         "com.android.media.swcodec",
+        "com.android.virt",
     ],
 }
 
@@ -104,7 +110,6 @@
     defaults: ["gwp_asan_no_libs_defaults"],
     header_libs: [
         "gwp_asan_headers",
-        "libc_headers", // Required for pthread.h in mutex.h.
     ],
     srcs: [
         "gwp_asan/common.cpp",
@@ -139,7 +144,6 @@
     defaults: ["gwp_asan_defaults"],
     header_libs: [
         "gwp_asan_headers",
-        "libc_headers", // Required for assert.h
     ],
     srcs: [
         "gwp_asan/common.cpp",
@@ -222,9 +226,5 @@
         // Ensure that the helper functions in test/backtrace.cpp don't get
         // tail-call optimised, as this breaks the unwind chain.
         "-fno-optimize-sibling-calls",
-
-        // The experimental pass manager seems to kill __attribute__((optnone)),
-        // and so we disable it (as we rely on optnone for tests/backtrace.cpp).
-        "-fno-experimental-new-pass-manager",
     ],
 }
diff --git a/android/test_backtrace.cpp b/android/test_backtrace.cpp
index 4a6d20d..0d397fd 100644
--- a/android/test_backtrace.cpp
+++ b/android/test_backtrace.cpp
@@ -18,7 +18,10 @@
 #include "gwp_asan/optional/backtrace.h"
 #include "gwp_asan/optional/segv_handler.h"
 
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Maps.h>
+#include <unwindstack/Memory.h>
+#include <unwindstack/Regs.h>
+#include <unwindstack/RegsGetLocal.h>
 #include <unwindstack/Unwinder.h>
 
 namespace {
@@ -32,19 +35,21 @@
 // potentially more detailed stack frames in the allocation/deallocation traces
 // (as we don't use the production unwinder), but that's fine for test-only.
 size_t BacktraceUnwindstack(uintptr_t *TraceBuffer, size_t Size) {
-  unwindstack::LocalUnwinder unwinder;
-  if (!unwinder.Init()) {
+  unwindstack::LocalMaps maps;
+  if (!maps.Parse()) {
     return 0;
   }
-  std::vector<unwindstack::LocalFrameData> frames;
-  if (!unwinder.Unwind(&frames, Size)) {
-    return 0;
-  }
-  for (const auto &frame : frames) {
+
+  auto process_memory = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
+  std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
+  unwindstack::RegsGetLocal(regs.get());
+  unwindstack::Unwinder unwinder(Size, &maps, regs.get(), process_memory);
+  unwinder.Unwind();
+  for (const auto &frame : unwinder.frames()) {
     *TraceBuffer = frame.pc;
     TraceBuffer++;
   }
-  return frames.size();
+  return unwinder.NumFrames();
 }
 
 // We don't need any custom handling for the Segv backtrace - the unwindstack
diff --git a/gwp_asan/common.h b/gwp_asan/common.h
index 7ce367e..6b238ad 100644
--- a/gwp_asan/common.h
+++ b/gwp_asan/common.h
@@ -19,7 +19,28 @@
 #include <stdint.h>
 
 namespace gwp_asan {
-enum class Error {
+
+// Magic header that resides in the AllocatorState so that GWP-ASan bugreports
+// can be understood by tools at different versions. Out-of-process crash
+// handlers, like crashpad on Fuchsia, take the raw contents of the
+// AllocationMetatada array and the AllocatorState, and shove them into the
+// minidump. Online unpacking of these structs needs to know from which version
+// of GWP-ASan it's extracting the information, as the structures are not
+// stable.
+struct AllocatorVersionMagic {
+  // The values are copied into the structure at runtime, during
+  // `GuardedPoolAllocator::init()` so that GWP-ASan remains completely in the
+  // `.bss` segment.
+  static constexpr uint8_t kAllocatorVersionMagic[4] = {'A', 'S', 'A', 'N'};
+  uint8_t Magic[4] = {};
+  // Update the version number when the AllocatorState or AllocationMetadata
+  // change.
+  static constexpr uint16_t kAllocatorVersion = 1;
+  uint16_t Version = 0;
+  uint16_t Reserved = 0;
+};
+
+enum class Error : uint8_t {
   UNKNOWN,
   USE_AFTER_FREE,
   DOUBLE_FREE,
@@ -84,6 +105,7 @@
 // set of information required for understanding a GWP-ASan crash.
 struct AllocatorState {
   constexpr AllocatorState() {}
+  AllocatorVersionMagic VersionMagic{};
 
   // Returns whether the provided pointer is a current sampled allocation that
   // is owned by this pool.
@@ -123,5 +145,38 @@
   uintptr_t FailureAddress = 0;
 };
 
+// Below are various compile-time checks that the layout of the internal
+// GWP-ASan structures are undisturbed. If they are disturbed, the version magic
+// number needs to be increased by one, and the asserts need to be updated.
+// Out-of-process crash handlers, like breakpad/crashpad, may copy the internal
+// GWP-ASan structures into a minidump for offline reconstruction of the crash.
+// In order to accomplish this, the offline reconstructor needs to know the
+// version of GWP-ASan internal structures that it's unpacking (along with the
+// architecture-specific layout info, which is left as an exercise to the crash
+// handler).
+static_assert(offsetof(AllocatorState, VersionMagic) == 0, "");
+static_assert(sizeof(AllocatorVersionMagic) == 8, "");
+#if defined(__x86_64__)
+static_assert(sizeof(AllocatorState) == 56, "");
+static_assert(offsetof(AllocatorState, FailureAddress) == 48, "");
+static_assert(sizeof(AllocationMetadata) == 568, "");
+static_assert(offsetof(AllocationMetadata, IsDeallocated) == 560, "");
+#elif defined(__aarch64__)
+static_assert(sizeof(AllocatorState) == 56, "");
+static_assert(offsetof(AllocatorState, FailureAddress) == 48, "");
+static_assert(sizeof(AllocationMetadata) == 568, "");
+static_assert(offsetof(AllocationMetadata, IsDeallocated) == 560, "");
+#elif defined(__i386__)
+static_assert(sizeof(AllocatorState) == 32, "");
+static_assert(offsetof(AllocatorState, FailureAddress) == 28, "");
+static_assert(sizeof(AllocationMetadata) == 548, "");
+static_assert(offsetof(AllocationMetadata, IsDeallocated) == 544, "");
+#elif defined(__arm__)
+static_assert(sizeof(AllocatorState) == 32, "");
+static_assert(offsetof(AllocatorState, FailureAddress) == 28, "");
+static_assert(sizeof(AllocationMetadata) == 560, "");
+static_assert(offsetof(AllocationMetadata, IsDeallocated) == 552, "");
+#endif // defined($ARCHITECTURE)
+
 } // namespace gwp_asan
 #endif // GWP_ASAN_COMMON_H_
diff --git a/gwp_asan/guarded_pool_allocator.cpp b/gwp_asan/guarded_pool_allocator.cpp
index d784927..7096b42 100644
--- a/gwp_asan/guarded_pool_allocator.cpp
+++ b/gwp_asan/guarded_pool_allocator.cpp
@@ -59,6 +59,13 @@
   SingletonPtr = this;
   Backtrace = Opts.Backtrace;
 
+  State.VersionMagic = {{AllocatorVersionMagic::kAllocatorVersionMagic[0],
+                         AllocatorVersionMagic::kAllocatorVersionMagic[1],
+                         AllocatorVersionMagic::kAllocatorVersionMagic[2],
+                         AllocatorVersionMagic::kAllocatorVersionMagic[3]},
+                        AllocatorVersionMagic::kAllocatorVersion,
+                        0};
+
   State.MaxSimultaneousAllocations = Opts.MaxSimultaneousAllocations;
 
   const size_t PageSize = getPlatformPageSize();
@@ -258,7 +265,10 @@
   // Raise a SEGV by touching first guard page.
   volatile char *p = reinterpret_cast<char *>(State.GuardedPagePool);
   *p = 0;
-  __builtin_unreachable();
+  // Normally, would be __builtin_unreachable(), but because of
+  // https://bugs.llvm.org/show_bug.cgi?id=47480, unreachable will DCE the
+  // volatile store above, even though it has side effects.
+  __builtin_trap();
 }
 
 void GuardedPoolAllocator::stop() {
diff --git a/gwp_asan/scripts/symbolize.sh b/gwp_asan/scripts/symbolize.sh
index fad9620..0027fa0 100755
--- a/gwp_asan/scripts/symbolize.sh
+++ b/gwp_asan/scripts/symbolize.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 
 # The lines that we're looking to symbolize look like this:
   #0 ./a.out(_foo+0x3e6) [0x55a52e64c696]
@@ -25,7 +25,7 @@
 
   if [ -z "$function_name" ]; then
     # If the offset is binary-relative, just resolve that.
-    symbolized="$(echo $function_offset | addr2line -e $binary_name)"
+    symbolized="$(echo $function_offset | addr2line -ie $binary_name)"
   else
     # Otherwise, the offset is function-relative. Get the address of the
     # function, and add it to the offset, then symbolize.
@@ -41,7 +41,7 @@
 
     # 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)"
+    symbolized="$(echo $binary_offset | addr2line -ie $binary_name)"
   fi
 
   # Check that it symbolized properly. If it didn't, output the old line.
@@ -52,4 +52,4 @@
   else
     echo "${frame_number}${symbolized}"
   fi
-done
+done 2> >(grep -v "addr2line: DWARF error: could not find variable specification")
diff --git a/gwp_asan/tests/alignment.cpp b/gwp_asan/tests/alignment.cpp
index 5f24a9a..6d1e912 100644
--- a/gwp_asan/tests/alignment.cpp
+++ b/gwp_asan/tests/alignment.cpp
@@ -34,81 +34,81 @@
 // numerics of the testing.
 TEST(AlignmentTest, LeftAlignedAllocs) {
   // Alignment < Page Size.
-  EXPECT_EQ(0x4000, AlignmentTestGPA::alignUp(
+  EXPECT_EQ(0x4000u, AlignmentTestGPA::alignUp(
                         /* Ptr */ 0x4000, /* Alignment */ 0x1));
   // Alignment == Page Size.
-  EXPECT_EQ(0x4000, AlignmentTestGPA::alignUp(
+  EXPECT_EQ(0x4000u, AlignmentTestGPA::alignUp(
                         /* Ptr */ 0x4000, /* Alignment */ 0x1000));
   // Alignment > Page Size.
-  EXPECT_EQ(0x4000, AlignmentTestGPA::alignUp(
+  EXPECT_EQ(0x4000u, AlignmentTestGPA::alignUp(
                         /* Ptr */ 0x4000, /* Alignment */ 0x4000));
 }
 
 TEST(AlignmentTest, SingleByteAllocs) {
   // Alignment < Page Size.
-  EXPECT_EQ(0x1,
+  EXPECT_EQ(0x1u,
             AlignmentTestGPA::getRequiredBackingSize(
                 /* Size */ 0x1, /* Alignment */ 0x1, /* PageSize */ 0x1000));
-  EXPECT_EQ(0x7fff, AlignmentTestGPA::alignDown(
+  EXPECT_EQ(0x7fffu, AlignmentTestGPA::alignDown(
                         /* Ptr */ 0x8000 - 0x1, /* Alignment */ 0x1));
 
   // Alignment == Page Size.
-  EXPECT_EQ(0x1,
+  EXPECT_EQ(0x1u,
             AlignmentTestGPA::getRequiredBackingSize(
                 /* Size */ 0x1, /* Alignment */ 0x1000, /* PageSize */ 0x1000));
-  EXPECT_EQ(0x7000, AlignmentTestGPA::alignDown(
+  EXPECT_EQ(0x7000u, AlignmentTestGPA::alignDown(
                         /* Ptr */ 0x8000 - 0x1, /* Alignment */ 0x1000));
 
   // Alignment > Page Size.
-  EXPECT_EQ(0x3001,
+  EXPECT_EQ(0x3001u,
             AlignmentTestGPA::getRequiredBackingSize(
                 /* Size */ 0x1, /* Alignment */ 0x4000, /* PageSize */ 0x1000));
-  EXPECT_EQ(0x4000, AlignmentTestGPA::alignDown(
+  EXPECT_EQ(0x4000u, AlignmentTestGPA::alignDown(
                         /* Ptr */ 0x8000 - 0x1, /* Alignment */ 0x4000));
 }
 
 TEST(AlignmentTest, PageSizedAllocs) {
   // Alignment < Page Size.
-  EXPECT_EQ(0x1000,
+  EXPECT_EQ(0x1000u,
             AlignmentTestGPA::getRequiredBackingSize(
                 /* Size */ 0x1000, /* Alignment */ 0x1, /* PageSize */ 0x1000));
-  EXPECT_EQ(0x7000, AlignmentTestGPA::alignDown(
+  EXPECT_EQ(0x7000u, AlignmentTestGPA::alignDown(
                         /* Ptr */ 0x8000 - 0x1000, /* Alignment */ 0x1));
 
   // Alignment == Page Size.
-  EXPECT_EQ(0x1000, AlignmentTestGPA::getRequiredBackingSize(
+  EXPECT_EQ(0x1000u, AlignmentTestGPA::getRequiredBackingSize(
                         /* Size */ 0x1000, /* Alignment */ 0x1000,
                         /* PageSize */ 0x1000));
-  EXPECT_EQ(0x7000, AlignmentTestGPA::alignDown(
+  EXPECT_EQ(0x7000u, AlignmentTestGPA::alignDown(
                         /* Ptr */ 0x8000 - 0x1000, /* Alignment */ 0x1000));
 
   // Alignment > Page Size.
-  EXPECT_EQ(0x4000, AlignmentTestGPA::getRequiredBackingSize(
+  EXPECT_EQ(0x4000u, AlignmentTestGPA::getRequiredBackingSize(
                         /* Size */ 0x1000, /* Alignment */ 0x4000,
                         /* PageSize */ 0x1000));
-  EXPECT_EQ(0x4000, AlignmentTestGPA::alignDown(
+  EXPECT_EQ(0x4000u, AlignmentTestGPA::alignDown(
                         /* Ptr */ 0x8000 - 0x1000, /* Alignment */ 0x4000));
 }
 
 TEST(AlignmentTest, MoreThanPageAllocs) {
   // Alignment < Page Size.
-  EXPECT_EQ(0x2fff,
+  EXPECT_EQ(0x2fffu,
             AlignmentTestGPA::getRequiredBackingSize(
                 /* Size */ 0x2fff, /* Alignment */ 0x1, /* PageSize */ 0x1000));
-  EXPECT_EQ(0x5001, AlignmentTestGPA::alignDown(
+  EXPECT_EQ(0x5001u, AlignmentTestGPA::alignDown(
                         /* Ptr */ 0x8000 - 0x2fff, /* Alignment */ 0x1));
 
   // Alignment == Page Size.
-  EXPECT_EQ(0x2fff, AlignmentTestGPA::getRequiredBackingSize(
+  EXPECT_EQ(0x2fffu, AlignmentTestGPA::getRequiredBackingSize(
                         /* Size */ 0x2fff, /* Alignment */ 0x1000,
                         /* PageSize */ 0x1000));
-  EXPECT_EQ(0x5000, AlignmentTestGPA::alignDown(
+  EXPECT_EQ(0x5000u, AlignmentTestGPA::alignDown(
                         /* Ptr */ 0x8000 - 0x2fff, /* Alignment */ 0x1000));
 
   // Alignment > Page Size.
-  EXPECT_EQ(0x5fff, AlignmentTestGPA::getRequiredBackingSize(
+  EXPECT_EQ(0x5fffu, AlignmentTestGPA::getRequiredBackingSize(
                         /* Size */ 0x2fff, /* Alignment */ 0x4000,
                         /* PageSize */ 0x1000));
-  EXPECT_EQ(0x4000, AlignmentTestGPA::alignDown(
+  EXPECT_EQ(0x4000u, AlignmentTestGPA::alignDown(
                         /* Ptr */ 0x8000 - 0x2fff, /* Alignment */ 0x4000));
 }
diff --git a/gwp_asan/tests/backtrace.cpp b/gwp_asan/tests/backtrace.cpp
index 9515065..a4eb8eb 100644
--- a/gwp_asan/tests/backtrace.cpp
+++ b/gwp_asan/tests/backtrace.cpp
@@ -30,7 +30,7 @@
   *(reinterpret_cast<volatile char *>(Ptr)) = 7;
 }
 
-TEST_F(BacktraceGuardedPoolAllocator, DoubleFree) {
+TEST_F(BacktraceGuardedPoolAllocatorDeathTest, DoubleFree) {
   void *Ptr = AllocateMemory(GPA);
   DeallocateMemory(GPA, Ptr);
 
@@ -45,7 +45,12 @@
   ASSERT_DEATH(DeallocateMemory2(GPA, Ptr), DeathRegex);
 }
 
-TEST_F(BacktraceGuardedPoolAllocator, UseAfterFree) {
+TEST_F(BacktraceGuardedPoolAllocatorDeathTest, UseAfterFree) {
+#if defined(__linux__) && __ARM_ARCH == 7
+  // Incomplete backtrace on Armv7 Linux
+  GTEST_SKIP();
+#endif
+
   void *Ptr = AllocateMemory(GPA);
   DeallocateMemory(GPA, Ptr);
 
diff --git a/gwp_asan/tests/enable_disable.cpp b/gwp_asan/tests/enable_disable.cpp
index 2c6ba51..98da591 100644
--- a/gwp_asan/tests/enable_disable.cpp
+++ b/gwp_asan/tests/enable_disable.cpp
@@ -10,7 +10,7 @@
 
 constexpr size_t Size = 100;
 
-TEST_F(DefaultGuardedPoolAllocator, Fork) {
+TEST_F(DefaultGuardedPoolAllocatorDeathTest, Fork) {
   void *P;
   pid_t Pid = fork();
   EXPECT_GE(Pid, 0);
diff --git a/gwp_asan/tests/harness.h b/gwp_asan/tests/harness.h
index a61b856..ed91e64 100644
--- a/gwp_asan/tests/harness.h
+++ b/gwp_asan/tests/harness.h
@@ -106,4 +106,9 @@
   gwp_asan::GuardedPoolAllocator GPA;
 };
 
+// https://github.com/google/googletest/blob/master/docs/advanced.md#death-tests-and-threads
+using DefaultGuardedPoolAllocatorDeathTest = DefaultGuardedPoolAllocator;
+using CustomGuardedPoolAllocatorDeathTest = CustomGuardedPoolAllocator;
+using BacktraceGuardedPoolAllocatorDeathTest = BacktraceGuardedPoolAllocator;
+
 #endif // GWP_ASAN_TESTS_HARNESS_H_
diff --git a/gwp_asan/tests/iterate.cpp b/gwp_asan/tests/iterate.cpp
index 2b8635d..49953f3 100644
--- a/gwp_asan/tests/iterate.cpp
+++ b/gwp_asan/tests/iterate.cpp
@@ -8,6 +8,7 @@
 
 #include "gwp_asan/tests/harness.h"
 
+#include <algorithm>
 #include <set>
 #include <vector>