Improvements to tombstone output.

- Use "likelihood" instead of "probability" since that has connotations
  of being less precise, and our probability ordering isn't very precise
  anyway.

- Hide the fault address with SEGV_MTEAERR because it is not available.

- Pad the fault address with leading zeroes to make it clearer which
  bits of the top byte (and any following bytes such as PAC signature
  bits) are set.

Bug: 206015287
Change-Id: I5e1e99b7f3e967c44781d8550bbd7158eb421b64
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 4394274..a4bb8b5 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -340,7 +340,12 @@
 
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
-  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0xdead)");
+#ifdef __LP64__
+  ASSERT_MATCH(result,
+               R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x000000000000dead)");
+#else
+  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0000dead)");
+#endif
 
   if (mte_supported()) {
     // Test that the default TAGGED_ADDR_CTRL value is set.
@@ -370,8 +375,7 @@
 
   // The address can either be tagged (new kernels) or untagged (old kernels).
   ASSERT_MATCH(
-      result,
-      R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr (0x100000000000dead|0xdead))");
+      result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x[01]00000000000dead)");
 }
 
 // Marked as weak to prevent the compiler from removing the malloc in the caller. In theory, the
@@ -422,6 +426,12 @@
     abort();
   }
 }
+
+static void SetTagCheckingLevelAsync() {
+  if (mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, M_HEAP_TAGGING_LEVEL_ASYNC) == 0) {
+    abort();
+  }
+}
 #endif
 
 // Number of iterations required to reliably guarantee a GWP-ASan crash.
@@ -653,6 +663,36 @@
 #endif
 }
 
+TEST_F(CrasherTest, mte_async) {
+#if defined(__aarch64__)
+  if (!mte_supported()) {
+    GTEST_SKIP() << "Requires MTE";
+  }
+
+  int intercept_result;
+  unique_fd output_fd;
+  StartProcess([&]() {
+    SetTagCheckingLevelAsync();
+    volatile int* p = (volatile int*)malloc(16);
+    p[-1] = 42;
+  });
+
+  StartIntercept(&output_fd);
+  FinishCrasher();
+  AssertDeath(SIGSEGV);
+  FinishIntercept(&intercept_result);
+
+  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
+
+  std::string result;
+  ConsumeFd(std::move(output_fd), &result);
+
+  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 8 \(SEGV_MTEAERR\), fault addr --------)");
+#else
+  GTEST_SKIP() << "Requires aarch64";
+#endif
+}
+
 TEST_F(CrasherTest, mte_multiple_causes) {
 #if defined(__aarch64__)
   if (!mte_supported()) {
@@ -703,7 +743,7 @@
   for (const auto& result : log_sources) {
     ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
     ASSERT_THAT(result, HasSubstr("Note: multiple potential causes for this crash were detected, "
-                                  "listing them in decreasing order of probability."));
+                                  "listing them in decreasing order of likelihood."));
     // Adjacent untracked allocations may cause us to see the wrong underflow here (or only
     // overflows), so we can't match explicitly for an underflow message.
     ASSERT_MATCH(result,
@@ -890,7 +930,7 @@
 
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
-  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0xdead)");
+  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0+dead)");
 }
 
 TEST_F(CrasherTest, abort) {
@@ -1940,7 +1980,7 @@
 
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
-  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x1024)");
+  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0+1024)");
 
   ASSERT_MATCH(result, R"(\nmemory map \(.*\):\n)");
 
@@ -1970,8 +2010,8 @@
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
 
-  std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr )";
-  match_str += android::base::StringPrintf("0x%" PRIxPTR, crash_uptr);
+  std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x)";
+  match_str += format_full_pointer(crash_uptr);
   ASSERT_MATCH(result, match_str);
 
   ASSERT_MATCH(result, R"(\nmemory map \(.*\): \(fault address prefixed with --->)\n)");
@@ -2018,8 +2058,8 @@
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
 
-  std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr )";
-  match_str += android::base::StringPrintf("%p", middle_ptr);
+  std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x)";
+  match_str += format_full_pointer(reinterpret_cast<uintptr_t>(middle_ptr));
   ASSERT_MATCH(result, match_str);
 
   ASSERT_MATCH(result, R"(\nmemory map \(.*\): \(fault address prefixed with --->)\n)");
@@ -2056,8 +2096,8 @@
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
 
-  std::string match_str = R"(signal 11 \(SIGSEGV\), code 2 \(SEGV_ACCERR\), fault addr )";
-  match_str += android::base::StringPrintf("%p", ptr);
+  std::string match_str = R"(signal 11 \(SIGSEGV\), code 2 \(SEGV_ACCERR\), fault addr 0x)";
+  match_str += format_full_pointer(reinterpret_cast<uintptr_t>(ptr));
   ASSERT_MATCH(result, match_str);
 
   ASSERT_MATCH(result, R"(\nmemory map \(.*\): \(fault address prefixed with --->)\n)");
@@ -2181,7 +2221,7 @@
   ConsumeFd(std::move(output_fd), &result);
 
   // Verify the process crashed properly.
-  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0)");
+  ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0*)");
 
   // Now verify that the dex_pc frame includes a proper function name.
   ASSERT_MATCH(result, R"( \[anon:dex\] \(Main\.\<init\>\+2)");