Merge "Update for accurate unreadable elf files." am: 95c777072f

Original change: https://android-review.googlesource.com/c/platform/system/core/+/2025823

Change-Id: Iad34080b458d7ec6060936f6d2594d9950bfd7cd
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 85adbea..a5e2413 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -1825,9 +1825,9 @@
 TEST_F(CrasherTest, unreadable_elf) {
   int intercept_result;
   unique_fd output_fd;
-  StartProcess([]() {
+  std::string tmp_so_name;
+  StartProcess([&tmp_so_name]() {
     TemporaryDir td;
-    std::string tmp_so_name;
     if (!CopySharedLibrary(td.path, &tmp_so_name)) {
       _exit(1);
     }
@@ -1857,6 +1857,8 @@
   std::string result;
   ConsumeFd(std::move(output_fd), &result);
   ASSERT_MATCH(result, R"(NOTE: Function names and BuildId information is missing )");
+  std::string match_str = "NOTE:   " + tmp_so_name;
+  ASSERT_MATCH(result, match_str);
 }
 
 TEST(tombstoned, proto) {
diff --git a/debuggerd/libdebuggerd/tombstone_proto.cpp b/debuggerd/libdebuggerd/tombstone_proto.cpp
index 3e31bb7..bee4a67 100644
--- a/debuggerd/libdebuggerd/tombstone_proto.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto.cpp
@@ -35,6 +35,7 @@
 
 #include <memory>
 #include <optional>
+#include <set>
 #include <string>
 
 #include <async_safe/log.h>
@@ -419,18 +420,29 @@
     return;
   }
 
-  if (unwinder->elf_from_memory_not_file()) {
+  unwinder->SetDisplayBuildID(true);
+  std::set<std::string> unreadable_elf_files;
+  for (const auto& frame : unwinder->frames()) {
+    BacktraceFrame* f = thread.add_current_backtrace();
+    fill_in_backtrace_frame(f, frame);
+    if (frame.map_info != nullptr && frame.map_info->ElfFileNotReadable()) {
+      unreadable_elf_files.emplace(frame.map_info->name());
+    }
+  }
+
+  if (!unreadable_elf_files.empty()) {
+    auto unreadable_elf_files_proto = thread.mutable_unreadable_elf_files();
     auto backtrace_note = thread.mutable_backtrace_note();
     *backtrace_note->Add() =
         "Function names and BuildId information is missing for some frames due";
     *backtrace_note->Add() = "to unreadable libraries. For unwinds of apps, only shared libraries";
     *backtrace_note->Add() = "found under the lib/ directory are readable.";
     *backtrace_note->Add() = "On this device, run setenforce 0 to make the libraries readable.";
-  }
-  unwinder->SetDisplayBuildID(true);
-  for (const auto& frame : unwinder->frames()) {
-    BacktraceFrame* f = thread.add_current_backtrace();
-    fill_in_backtrace_frame(f, frame);
+    *backtrace_note->Add() = "Unreadable libraries:";
+    for (auto& name : unreadable_elf_files) {
+      *backtrace_note->Add() = "  " + name;
+      *unreadable_elf_files_proto->Add() = name;
+    }
   }
 }
 
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index 543a67c..ecd98a4 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -28,6 +28,7 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <set>
 #include <string>
 
 #include <android-base/properties.h>
@@ -483,7 +484,16 @@
 }
 
 void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
-  if (unwinder->elf_from_memory_not_file()) {
+  std::set<std::string> unreadable_elf_files;
+  unwinder->SetDisplayBuildID(true);
+  for (const auto& frame : unwinder->frames()) {
+    if (frame.map_info != nullptr && frame.map_info->ElfFileNotReadable()) {
+      unreadable_elf_files.emplace(frame.map_info->name());
+    }
+  }
+
+  // Put the preamble ahead of the backtrace.
+  if (!unreadable_elf_files.empty()) {
     _LOG(log, logtype::BACKTRACE,
          "%sNOTE: Function names and BuildId information is missing for some frames due\n", prefix);
     _LOG(log, logtype::BACKTRACE,
@@ -493,10 +503,13 @@
     _LOG(log, logtype::BACKTRACE,
          "%sNOTE: On this device, run setenforce 0 to make the libraries readable.\n", prefix);
 #endif
+    _LOG(log, logtype::BACKTRACE, "%sNOTE: Unreadable libraries:\n", prefix);
+    for (auto& name : unreadable_elf_files) {
+      _LOG(log, logtype::BACKTRACE, "%sNOTE:   %s\n", prefix, name.c_str());
+    }
   }
 
-  unwinder->SetDisplayBuildID(true);
-  for (size_t i = 0; i < unwinder->NumFrames(); i++) {
-    _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(i).c_str());
+  for (const auto& frame : unwinder->frames()) {
+    _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(frame).c_str());
   }
 }
diff --git a/debuggerd/proto/tombstone.proto b/debuggerd/proto/tombstone.proto
index 40a942e..a0f2f82 100644
--- a/debuggerd/proto/tombstone.proto
+++ b/debuggerd/proto/tombstone.proto
@@ -123,12 +123,13 @@
   string name = 2;
   repeated Register registers = 3;
   repeated string backtrace_note = 7;
+  repeated string unreadable_elf_files = 9;
   repeated BacktraceFrame current_backtrace = 4;
   repeated MemoryDump memory_dump = 5;
   int64 tagged_addr_ctrl = 6;
   int64 pac_enabled_keys = 8;
 
-  reserved 9 to 999;
+  reserved 10 to 999;
 }
 
 message BacktraceFrame {