Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bad9f5fd authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "Remove non-protobuf path."

parents adae7669 bdea3bb5
Loading
Loading
Loading
Loading
+211 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <dlfcn.h>
#include <err.h>
#include <fcntl.h>
#include <linux/prctl.h>
#include <malloc.h>
#include <stdlib.h>
#include <sys/capability.h>
@@ -31,6 +32,7 @@

#include <chrono>
#include <regex>
#include <set>
#include <string>
#include <thread>

@@ -54,6 +56,9 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <unwindstack/Elf.h>
#include <unwindstack/Memory.h>

#include <libminijail.h>
#include <scoped_minijail.h>

@@ -2227,3 +2232,209 @@ TEST_F(CrasherTest, verify_dex_pc_with_function_name) {
  // Now verify that the dex_pc frame includes a proper function name.
  ASSERT_MATCH(result, R"( \[anon:dex\] \(Main\.\<init\>\+2)");
}

static std::string format_map_pointer(uintptr_t ptr) {
#if defined(__LP64__)
  return android::base::StringPrintf("%08x'%08x", static_cast<uint32_t>(ptr >> 32),
                                     static_cast<uint32_t>(ptr & 0xffffffff));
#else
  return android::base::StringPrintf("%08x", ptr);
#endif
}

// Verify that map data is properly formatted.
TEST_F(CrasherTest, verify_map_format) {
  // Create multiple maps to make sure that the map data is formatted properly.
  void* none_map = mmap(nullptr, getpagesize(), 0, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  ASSERT_NE(MAP_FAILED, none_map);
  void* r_map = mmap(nullptr, getpagesize(), PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  ASSERT_NE(MAP_FAILED, r_map);
  void* w_map = mmap(nullptr, getpagesize(), PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  ASSERT_NE(MAP_FAILED, w_map);
  void* x_map = mmap(nullptr, getpagesize(), PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  ASSERT_NE(MAP_FAILED, x_map);

  TemporaryFile tf;
  ASSERT_EQ(0x2000, lseek(tf.fd, 0x2000, SEEK_SET));
  char c = 'f';
  ASSERT_EQ(1, write(tf.fd, &c, 1));
  ASSERT_EQ(0x5000, lseek(tf.fd, 0x5000, SEEK_SET));
  ASSERT_EQ(1, write(tf.fd, &c, 1));
  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
  void* file_map = mmap(nullptr, 0x3001, PROT_READ, MAP_PRIVATE, tf.fd, 0x2000);
  ASSERT_NE(MAP_FAILED, file_map);

  StartProcess([]() { abort(); });

  ASSERT_EQ(0, munmap(none_map, getpagesize()));
  ASSERT_EQ(0, munmap(r_map, getpagesize()));
  ASSERT_EQ(0, munmap(w_map, getpagesize()));
  ASSERT_EQ(0, munmap(x_map, getpagesize()));
  ASSERT_EQ(0, munmap(file_map, 0x3001));

  unique_fd output_fd;
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  int intercept_result;
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);

  std::string match_str;
  // Verify none.
  match_str = android::base::StringPrintf(
      "    %s-%s ---         0      1000\\n",
      format_map_pointer(reinterpret_cast<uintptr_t>(none_map)).c_str(),
      format_map_pointer(reinterpret_cast<uintptr_t>(none_map) + getpagesize() - 1).c_str());
  ASSERT_MATCH(result, match_str);

  // Verify read-only.
  match_str = android::base::StringPrintf(
      "    %s-%s r--         0      1000\\n",
      format_map_pointer(reinterpret_cast<uintptr_t>(r_map)).c_str(),
      format_map_pointer(reinterpret_cast<uintptr_t>(r_map) + getpagesize() - 1).c_str());
  ASSERT_MATCH(result, match_str);

  // Verify write-only.
  match_str = android::base::StringPrintf(
      "    %s-%s -w-         0      1000\\n",
      format_map_pointer(reinterpret_cast<uintptr_t>(w_map)).c_str(),
      format_map_pointer(reinterpret_cast<uintptr_t>(w_map) + getpagesize() - 1).c_str());
  ASSERT_MATCH(result, match_str);

  // Verify exec-only.
  match_str = android::base::StringPrintf(
      "    %s-%s --x         0      1000\\n",
      format_map_pointer(reinterpret_cast<uintptr_t>(x_map)).c_str(),
      format_map_pointer(reinterpret_cast<uintptr_t>(x_map) + getpagesize() - 1).c_str());
  ASSERT_MATCH(result, match_str);

  // Verify file map with non-zero offset and a name.
  match_str = android::base::StringPrintf(
      "    %s-%s r--      2000      4000  %s\\n",
      format_map_pointer(reinterpret_cast<uintptr_t>(file_map)).c_str(),
      format_map_pointer(reinterpret_cast<uintptr_t>(file_map) + 0x3fff).c_str(), tf.path);
  ASSERT_MATCH(result, match_str);
}

// Verify that the tombstone map data is correct.
TEST_F(CrasherTest, verify_header) {
  StartProcess([]() { abort(); });

  unique_fd output_fd;
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  int intercept_result;
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);

  std::string match_str = android::base::StringPrintf(
      "Build fingerprint: '%s'\\nRevision: '%s'\\n",
      android::base::GetProperty("ro.build.fingerprint", "unknown").c_str(),
      android::base::GetProperty("ro.revision", "unknown").c_str());
  match_str += android::base::StringPrintf("ABI: '%s'\n", ABI_STRING);
  ASSERT_MATCH(result, match_str);
}

// Verify that the thread header is formatted properly.
TEST_F(CrasherTest, verify_thread_header) {
  void* shared_map =
      mmap(nullptr, sizeof(pid_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  ASSERT_NE(MAP_FAILED, shared_map);
  memset(shared_map, 0, sizeof(pid_t));

  StartProcess([&shared_map]() {
    std::atomic_bool tid_written;
    std::thread thread([&tid_written, &shared_map]() {
      pid_t tid = gettid();
      memcpy(shared_map, &tid, sizeof(pid_t));
      tid_written = true;
      volatile bool done = false;
      while (!done)
        ;
    });
    thread.detach();
    while (!tid_written.load(std::memory_order_acquire))
      ;
    abort();
  });

  pid_t primary_pid = crasher_pid;

  unique_fd output_fd;
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  int intercept_result;
  FinishIntercept(&intercept_result);
  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  // Read the tid data out.
  pid_t tid;
  memcpy(&tid, shared_map, sizeof(pid_t));
  ASSERT_NE(0, tid);

  ASSERT_EQ(0, munmap(shared_map, sizeof(pid_t)));

  std::string result;
  ConsumeFd(std::move(output_fd), &result);

  // Verify that there are two headers, one where the tid is "primary_pid"
  // and the other where the tid is "tid".
  std::string match_str = android::base::StringPrintf("pid: %d, tid: %d, name: .*  >>> .* <<<\\n",
                                                      primary_pid, primary_pid);
  ASSERT_MATCH(result, match_str);

  match_str =
      android::base::StringPrintf("pid: %d, tid: %d, name: .*  >>> .* <<<\\n", primary_pid, tid);
  ASSERT_MATCH(result, match_str);
}

// Verify that there is a BuildID present in the map section and set properly.
TEST_F(CrasherTest, verify_build_id) {
  StartProcess([]() { abort(); });

  unique_fd output_fd;
  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  int intercept_result;
  FinishIntercept(&intercept_result);
  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);

  // Find every /system or /apex lib and verify the BuildID is displayed
  // properly.
  bool found_valid_elf = false;
  std::smatch match;
  std::regex build_id_regex(R"(  ((/system/|/apex/)\S+) \(BuildId: ([^\)]+)\))");
  for (std::string prev_file; std::regex_search(result, match, build_id_regex);
       result = match.suffix()) {
    if (prev_file == match[1]) {
      // Already checked this file.
      continue;
    }

    prev_file = match[1];
    unwindstack::Elf elf(unwindstack::Memory::CreateFileMemory(prev_file, 0).release());
    if (!elf.Init() || !elf.valid()) {
      // Skipping invalid elf files.
      continue;
    }
    ASSERT_EQ(match[3], elf.GetPrintableBuildID());

    found_valid_elf = true;
  }
  ASSERT_TRUE(found_valid_elf) << "Did not find any elf files with valid BuildIDs to check.";
}
+0 −281
Original line number Diff line number Diff line
@@ -32,9 +32,6 @@
#include "host_signal_fixup.h"
#include "log_fake.h"

// Include tombstone.cpp to define log_tag before GWP-ASan includes log.
#include "tombstone.cpp"

#include "gwp_asan.cpp"

using ::testing::MatchesRegex;
@@ -82,283 +79,6 @@ class TombstoneTest : public ::testing::Test {
  std::string amfd_data_;
};

TEST_F(TombstoneTest, single_map) {
#if defined(__LP64__)
  unwinder_mock_->MockAddMap(0x123456789abcd000UL, 0x123456789abdf000UL, 0, 0, "", 0);
#else
  unwinder_mock_->MockAddMap(0x1234000, 0x1235000, 0, 0, "", 0);
#endif

  dump_all_maps(&log_, unwinder_mock_.get(), 0);

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
  const char* expected_dump = \
"\nmemory map (1 entry):\n"
#if defined(__LP64__)
"    12345678'9abcd000-12345678'9abdefff ---         0     12000\n";
#else
"    01234000-01234fff ---         0      1000\n";
#endif
  ASSERT_STREQ(expected_dump, tombstone_contents.c_str());

  ASSERT_STREQ("", amfd_data_.c_str());

  // Verify that the log buf is empty, and no error messages.
  ASSERT_STREQ("", getFakeLogBuf().c_str());
  ASSERT_STREQ("", getFakeLogPrint().c_str());
}

TEST_F(TombstoneTest, single_map_elf_build_id) {
  uint64_t build_id_offset;
#if defined(__LP64__)
  build_id_offset = 0x123456789abcd000UL;
  unwinder_mock_->MockAddMap(build_id_offset, 0x123456789abdf000UL, 0, PROT_READ,
                             "/system/lib/libfake.so", 0);
#else
  build_id_offset = 0x1234000;
  unwinder_mock_->MockAddMap(0x1234000, 0x1235000, 0, PROT_READ, "/system/lib/libfake.so", 0);
#endif

  unwinder_mock_->MockSetBuildID(
      build_id_offset,
      std::string{static_cast<char>(0xab), static_cast<char>(0xcd), static_cast<char>(0xef),
                  static_cast<char>(0x12), static_cast<char>(0x34), static_cast<char>(0x56),
                  static_cast<char>(0x78), static_cast<char>(0x90), static_cast<char>(0xab),
                  static_cast<char>(0xcd), static_cast<char>(0xef), static_cast<char>(0x12),
                  static_cast<char>(0x34), static_cast<char>(0x56), static_cast<char>(0x78),
                  static_cast<char>(0x90)});
  dump_all_maps(&log_, unwinder_mock_.get(), 0);

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
  const char* expected_dump = \
"\nmemory map (1 entry):\n"
#if defined(__LP64__)
"    12345678'9abcd000-12345678'9abdefff r--         0     12000  /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
#else
"    01234000-01234fff r--         0      1000  /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
#endif
  ASSERT_STREQ(expected_dump, tombstone_contents.c_str());

  ASSERT_STREQ("", amfd_data_.c_str());

  // Verify that the log buf is empty, and no error messages.
  ASSERT_STREQ("", getFakeLogBuf().c_str());
  ASSERT_STREQ("", getFakeLogPrint().c_str());
}

TEST_F(TombstoneTest, multiple_maps) {
  unwinder_mock_->MockAddMap(0xa234000, 0xa235000, 0, 0, "", 0);
  unwinder_mock_->MockAddMap(0xa334000, 0xa335000, 0xf000, PROT_READ, "", 0);
  unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
  unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
  unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
                             "/system/lib/fake.so", 0);

  dump_all_maps(&log_, unwinder_mock_.get(), 0);

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
  const char* expected_dump =
      "\nmemory map (5 entries):\n"
#if defined(__LP64__)
      "    00000000'0a234000-00000000'0a234fff ---         0      1000\n"
      "    00000000'0a334000-00000000'0a334fff r--      f000      1000\n"
      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
#else
      "    0a234000-0a234fff ---         0      1000\n"
      "    0a334000-0a334fff r--      f000      1000\n"
      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "    0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
#endif
  ASSERT_STREQ(expected_dump, tombstone_contents.c_str());

  ASSERT_STREQ("", amfd_data_.c_str());

  // Verify that the log buf is empty, and no error messages.
  ASSERT_STREQ("", getFakeLogBuf().c_str());
  ASSERT_STREQ("", getFakeLogPrint().c_str());
}

TEST_F(TombstoneTest, multiple_maps_fault_address_before) {
  unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
  unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
  unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
                             "/system/lib/fake.so", 0);

  dump_all_maps(&log_, unwinder_mock_.get(), 0x1000);

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
  const char* expected_dump =
      "\nmemory map (3 entries):\n"
#if defined(__LP64__)
      "--->Fault address falls at 00000000'00001000 before any mapped regions\n"
      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
#else
      "--->Fault address falls at 00001000 before any mapped regions\n"
      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "    0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
#endif
  ASSERT_STREQ(expected_dump, tombstone_contents.c_str());

  ASSERT_STREQ("", amfd_data_.c_str());

  // Verify that the log buf is empty, and no error messages.
  ASSERT_STREQ("", getFakeLogBuf().c_str());
  ASSERT_STREQ("", getFakeLogPrint().c_str());
}

TEST_F(TombstoneTest, multiple_maps_fault_address_between) {
  unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
  unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
  unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
                             "/system/lib/fake.so", 0);

  dump_all_maps(&log_, unwinder_mock_.get(), 0xa533000);

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
  const char* expected_dump =
      "\nmemory map (3 entries): (fault address prefixed with --->)\n"
#if defined(__LP64__)
      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "--->Fault address falls at 00000000'0a533000 between mapped regions\n"
      "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
#else
      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "--->Fault address falls at 0a533000 between mapped regions\n"
      "    0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
#endif
  ASSERT_STREQ(expected_dump, tombstone_contents.c_str());

  ASSERT_STREQ("", amfd_data_.c_str());

  // Verify that the log buf is empty, and no error messages.
  ASSERT_STREQ("", getFakeLogBuf().c_str());
  ASSERT_STREQ("", getFakeLogPrint().c_str());
}

TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) {
  unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
  unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
  unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
                             "/system/lib/fake.so", 0);

  dump_all_maps(&log_, unwinder_mock_.get(), 0xa534040);

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
  const char* expected_dump =
      "\nmemory map (3 entries): (fault address prefixed with --->)\n"
#if defined(__LP64__)
      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "--->00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
#else
      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "--->0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
#endif
  ASSERT_STREQ(expected_dump, tombstone_contents.c_str());

  ASSERT_STREQ("", amfd_data_.c_str());

  // Verify that the log buf is empty, and no error messages.
  ASSERT_STREQ("", getFakeLogBuf().c_str());
  ASSERT_STREQ("", getFakeLogPrint().c_str());
}

TEST_F(TombstoneTest, multiple_maps_fault_address_after) {
  unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
  unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
  unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
                             "/system/lib/fake.so", 0);

#if defined(__LP64__)
  uint64_t addr = 0x12345a534040UL;
#else
  uint64_t addr = 0xf534040UL;
#endif
  dump_all_maps(&log_, unwinder_mock_.get(), addr);

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
  const char* expected_dump =
      "\nmemory map (3 entries): (fault address prefixed with --->)\n"
#if defined(__LP64__)
      "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n"
      "--->Fault address falls at 00001234'5a534040 after any mapped regions\n";
#else
      "    0a434000-0a434fff -w-      1000      1000  (load bias 0xd000)\n"
      "    0a534000-0a534fff --x      3000      1000  (load bias 0x2000)\n"
      "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n"
      "--->Fault address falls at 0f534040 after any mapped regions\n";
#endif
  ASSERT_STREQ(expected_dump, tombstone_contents.c_str());

  ASSERT_STREQ("", amfd_data_.c_str());

  // Verify that the log buf is empty, and no error messages.
  ASSERT_STREQ("", getFakeLogBuf().c_str());
  ASSERT_STREQ("", getFakeLogPrint().c_str());
}

TEST_F(TombstoneTest, dump_log_file_error) {
  log_.should_retrieve_logcat = true;
  dump_log_file(&log_, 123, "/fake/filename", 10);

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
  ASSERT_STREQ("", tombstone_contents.c_str());

  ASSERT_STREQ("", getFakeLogBuf().c_str());
  ASSERT_STREQ("6 DEBUG Unable to open /fake/filename: Permission denied\n\n",
               getFakeLogPrint().c_str());

  ASSERT_STREQ("", amfd_data_.c_str());
}

TEST_F(TombstoneTest, dump_header_info) {
  dump_header_info(&log_);

  std::string expected = android::base::StringPrintf(
      "Build fingerprint: '%s'\nRevision: '%s'\n",
      android::base::GetProperty("ro.build.fingerprint", "unknown").c_str(),
      android::base::GetProperty("ro.revision", "unknown").c_str());
  expected += android::base::StringPrintf("ABI: '%s'\n", ABI_STRING);
  ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
}

TEST_F(TombstoneTest, dump_thread_info_uid) {
  std::vector<std::string> cmdline = {"some_process"};
  dump_thread_info(
      &log_,
      ThreadInfo{
          .uid = 1, .tid = 3, .thread_name = "some_thread", .pid = 2, .command_line = cmdline});
  std::string expected = "pid: 2, tid: 3, name: some_thread  >>> some_process <<<\nuid: 1\n";
  ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
}

class GwpAsanCrashDataTest : public GwpAsanCrashData {
public:
  GwpAsanCrashDataTest(
@@ -483,4 +203,3 @@ TEST_F(TombstoneTest, gwp_asan_cause_invalid_free_outside) {
          "Cause: \\[GWP-ASan\\]: Invalid \\(Wild\\) Free, 33 bytes right of a 32-byte "
          "allocation at 0x[a-fA-F0-9]+\n"));
}
+5 −571

File changed.

Preview size limit exceeded, changes collapsed.