Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdlib.h>
     18 
     19 #include <memory>
     20 #include <string>
     21 
     22 #include <gtest/gtest.h>
     23 #include <android-base/file.h>
     24 
     25 #include "utility.h"
     26 
     27 #include "BacktraceMock.h"
     28 #include "elf_fake.h"
     29 #include "host_signal_fixup.h"
     30 #include "log_fake.h"
     31 #include "ptrace_fake.h"
     32 
     33 // In order to test this code, we need to include the tombstone.cpp code.
     34 // Including it, also allows us to override the ptrace function.
     35 #define ptrace ptrace_fake
     36 
     37 #include "tombstone.cpp"
     38 
     39 void dump_registers(log_t*, pid_t) {
     40 }
     41 
     42 void dump_memory_and_code(log_t*, Backtrace*) {
     43 }
     44 
     45 void dump_backtrace_to_log(Backtrace*, log_t*, char const*) {
     46 }
     47 
     48 class TombstoneTest : public ::testing::Test {
     49  protected:
     50   virtual void SetUp() {
     51     map_mock_.reset(new BacktraceMapMock());
     52     backtrace_mock_.reset(new BacktraceMock(map_mock_.get()));
     53 
     54     char tmp_file[256];
     55     const char data_template[] = "/data/local/tmp/debuggerd_memory_testXXXXXX";
     56     memcpy(tmp_file, data_template, sizeof(data_template));
     57     int tombstone_fd = mkstemp(tmp_file);
     58     if (tombstone_fd == -1) {
     59       const char tmp_template[] = "/tmp/debuggerd_memory_testXXXXXX";
     60       memcpy(tmp_file, tmp_template, sizeof(tmp_template));
     61       tombstone_fd = mkstemp(tmp_file);
     62       if (tombstone_fd == -1) {
     63         abort();
     64       }
     65     }
     66     if (unlink(tmp_file) == -1) {
     67       abort();
     68     }
     69 
     70     log_.tfd = tombstone_fd;
     71     amfd_data_.clear();
     72     log_.amfd_data = &amfd_data_;
     73     log_.crashed_tid = 12;
     74     log_.current_tid = 12;
     75     log_.should_retrieve_logcat = false;
     76 
     77     resetLogs();
     78     elf_set_fake_build_id("");
     79     siginfo_t si;
     80     memset(&si, 0, sizeof(si));
     81     si.si_signo = SIGABRT;
     82     si.si_code = SI_KERNEL;
     83     ptrace_set_fake_getsiginfo(si);
     84   }
     85 
     86   virtual void TearDown() {
     87     if (log_.tfd >= 0) {
     88       close(log_.tfd);
     89     }
     90   }
     91 
     92   std::unique_ptr<BacktraceMapMock> map_mock_;
     93   std::unique_ptr<BacktraceMock> backtrace_mock_;
     94 
     95   log_t log_;
     96   std::string amfd_data_;
     97 };
     98 
     99 TEST_F(TombstoneTest, single_map) {
    100   backtrace_map_t map;
    101 #if defined(__LP64__)
    102   map.start = 0x123456789abcd000UL;
    103   map.end = 0x123456789abdf000UL;
    104 #else
    105   map.start = 0x1234000;
    106   map.end = 0x1235000;
    107 #endif
    108   map_mock_->AddMap(map);
    109 
    110   dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    111 
    112   std::string tombstone_contents;
    113   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    114   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    115   const char* expected_dump = \
    116 "\nmemory map:\n"
    117 #if defined(__LP64__)
    118 "    12345678'9abcd000-12345678'9abdefff ---         0     12000\n";
    119 #else
    120 "    01234000-01234fff ---         0      1000\n";
    121 #endif
    122   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
    123 
    124   ASSERT_STREQ("", amfd_data_.c_str());
    125 
    126   // Verify that the log buf is empty, and no error messages.
    127   ASSERT_STREQ("", getFakeLogBuf().c_str());
    128   ASSERT_STREQ("", getFakeLogPrint().c_str());
    129 }
    130 
    131 TEST_F(TombstoneTest, single_map_elf_build_id) {
    132   backtrace_map_t map;
    133 #if defined(__LP64__)
    134   map.start = 0x123456789abcd000UL;
    135   map.end = 0x123456789abdf000UL;
    136 #else
    137   map.start = 0x1234000;
    138   map.end = 0x1235000;
    139 #endif
    140   map.flags = PROT_READ;
    141   map.name = "/system/lib/libfake.so";
    142   map_mock_->AddMap(map);
    143 
    144   elf_set_fake_build_id("abcdef1234567890abcdef1234567890");
    145   dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    146 
    147   std::string tombstone_contents;
    148   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    149   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    150   const char* expected_dump = \
    151 "\nmemory map:\n"
    152 #if defined(__LP64__)
    153 "    12345678'9abcd000-12345678'9abdefff r--         0     12000  /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
    154 #else
    155 "    01234000-01234fff r--         0      1000  /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
    156 #endif
    157   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
    158 
    159   ASSERT_STREQ("", amfd_data_.c_str());
    160 
    161   // Verify that the log buf is empty, and no error messages.
    162   ASSERT_STREQ("", getFakeLogBuf().c_str());
    163   ASSERT_STREQ("", getFakeLogPrint().c_str());
    164 }
    165 
    166 // Even though build id is present, it should not be printed in either of
    167 // these cases.
    168 TEST_F(TombstoneTest, single_map_no_build_id) {
    169   backtrace_map_t map;
    170 #if defined(__LP64__)
    171   map.start = 0x123456789abcd000UL;
    172   map.end = 0x123456789abdf000UL;
    173 #else
    174   map.start = 0x1234000;
    175   map.end = 0x1235000;
    176 #endif
    177   map.flags = PROT_WRITE;
    178   map_mock_->AddMap(map);
    179 
    180   map.name = "/system/lib/libfake.so";
    181   map_mock_->AddMap(map);
    182 
    183   elf_set_fake_build_id("abcdef1234567890abcdef1234567890");
    184   dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    185 
    186   std::string tombstone_contents;
    187   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    188   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    189   const char* expected_dump = \
    190 "\nmemory map:\n"
    191 #if defined(__LP64__)
    192 "    12345678'9abcd000-12345678'9abdefff -w-         0     12000\n"
    193 "    12345678'9abcd000-12345678'9abdefff -w-         0     12000  /system/lib/libfake.so\n";
    194 #else
    195 "    01234000-01234fff -w-         0      1000\n"
    196 "    01234000-01234fff -w-         0      1000  /system/lib/libfake.so\n";
    197 #endif
    198   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
    199 
    200   ASSERT_STREQ("", amfd_data_.c_str());
    201 
    202   // Verify that the log buf is empty, and no error messages.
    203   ASSERT_STREQ("", getFakeLogBuf().c_str());
    204   ASSERT_STREQ("", getFakeLogPrint().c_str());
    205 }
    206 
    207 TEST_F(TombstoneTest, multiple_maps) {
    208   backtrace_map_t map;
    209 
    210   map.start = 0xa234000;
    211   map.end = 0xa235000;
    212   map_mock_->AddMap(map);
    213 
    214   map.start = 0xa334000;
    215   map.end = 0xa335000;
    216   map.offset = 0xf000;
    217   map.flags = PROT_READ;
    218   map_mock_->AddMap(map);
    219 
    220   map.start = 0xa434000;
    221   map.end = 0xa435000;
    222   map.offset = 0x1000;
    223   map.load_base = 0xd000;
    224   map.flags = PROT_WRITE;
    225   map_mock_->AddMap(map);
    226 
    227   map.start = 0xa534000;
    228   map.end = 0xa535000;
    229   map.offset = 0x3000;
    230   map.load_base = 0x2000;
    231   map.flags = PROT_EXEC;
    232   map_mock_->AddMap(map);
    233 
    234   map.start = 0xa634000;
    235   map.end = 0xa635000;
    236   map.offset = 0;
    237   map.load_base = 0;
    238   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
    239   map.name = "/system/lib/fake.so";
    240   map_mock_->AddMap(map);
    241 
    242   dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    243 
    244   std::string tombstone_contents;
    245   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    246   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    247   const char* expected_dump = \
    248 "\nmemory map:\n"
    249 #if defined(__LP64__)
    250 "    00000000'0a234000-00000000'0a234fff ---         0      1000\n"
    251 "    00000000'0a334000-00000000'0a334fff r--      f000      1000\n"
    252 "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
    253 "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
    254 "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
    255 #else
    256 "    0a234000-0a234fff ---         0      1000\n"
    257 "    0a334000-0a334fff r--      f000      1000\n"
    258 "    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
    259 "    0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
    260 "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
    261 #endif
    262   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
    263 
    264   ASSERT_STREQ("", amfd_data_.c_str());
    265 
    266   // Verify that the log buf is empty, and no error messages.
    267   ASSERT_STREQ("", getFakeLogBuf().c_str());
    268   ASSERT_STREQ("", getFakeLogPrint().c_str());
    269 }
    270 
    271 TEST_F(TombstoneTest, multiple_maps_fault_address_before) {
    272   backtrace_map_t map;
    273 
    274   map.start = 0xa434000;
    275   map.end = 0xa435000;
    276   map.offset = 0x1000;
    277   map.load_base = 0xd000;
    278   map.flags = PROT_WRITE;
    279   map_mock_->AddMap(map);
    280 
    281   map.start = 0xa534000;
    282   map.end = 0xa535000;
    283   map.offset = 0x3000;
    284   map.load_base = 0x2000;
    285   map.flags = PROT_EXEC;
    286   map_mock_->AddMap(map);
    287 
    288   map.start = 0xa634000;
    289   map.end = 0xa635000;
    290   map.offset = 0;
    291   map.load_base = 0;
    292   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
    293   map.name = "/system/lib/fake.so";
    294   map_mock_->AddMap(map);
    295 
    296   siginfo_t si;
    297   memset(&si, 0, sizeof(si));
    298   si.si_signo = SIGBUS;
    299   si.si_code = SI_KERNEL;
    300   si.si_addr = reinterpret_cast<void*>(0x1000);
    301   ptrace_set_fake_getsiginfo(si);
    302   dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    303 
    304   std::string tombstone_contents;
    305   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    306   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    307   const char* expected_dump = \
    308 "\nmemory map: (fault address prefixed with --->)\n"
    309 #if defined(__LP64__)
    310 "--->Fault address falls at 00000000'00001000 before any mapped regions\n"
    311 "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
    312 "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
    313 "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
    314 #else
    315 "--->Fault address falls at 00001000 before any mapped regions\n"
    316 "    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
    317 "    0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
    318 "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
    319 #endif
    320   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
    321 
    322   ASSERT_STREQ("", amfd_data_.c_str());
    323 
    324   // Verify that the log buf is empty, and no error messages.
    325   ASSERT_STREQ("", getFakeLogBuf().c_str());
    326   ASSERT_STREQ("", getFakeLogPrint().c_str());
    327 }
    328 
    329 TEST_F(TombstoneTest, multiple_maps_fault_address_between) {
    330   backtrace_map_t map;
    331 
    332   map.start = 0xa434000;
    333   map.end = 0xa435000;
    334   map.offset = 0x1000;
    335   map.load_base = 0xd000;
    336   map.flags = PROT_WRITE;
    337   map_mock_->AddMap(map);
    338 
    339   map.start = 0xa534000;
    340   map.end = 0xa535000;
    341   map.offset = 0x3000;
    342   map.load_base = 0x2000;
    343   map.flags = PROT_EXEC;
    344   map_mock_->AddMap(map);
    345 
    346   map.start = 0xa634000;
    347   map.end = 0xa635000;
    348   map.offset = 0;
    349   map.load_base = 0;
    350   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
    351   map.name = "/system/lib/fake.so";
    352   map_mock_->AddMap(map);
    353 
    354   siginfo_t si;
    355   memset(&si, 0, sizeof(si));
    356   si.si_signo = SIGBUS;
    357   si.si_code = SI_KERNEL;
    358   si.si_addr = reinterpret_cast<void*>(0xa533000);
    359   ptrace_set_fake_getsiginfo(si);
    360   dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    361 
    362   std::string tombstone_contents;
    363   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    364   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    365   const char* expected_dump = \
    366 "\nmemory map: (fault address prefixed with --->)\n"
    367 #if defined(__LP64__)
    368 "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
    369 "--->Fault address falls at 00000000'0a533000 between mapped regions\n"
    370 "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
    371 "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
    372 #else
    373 "    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
    374 "--->Fault address falls at 0a533000 between mapped regions\n"
    375 "    0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
    376 "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
    377 #endif
    378   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
    379 
    380   ASSERT_STREQ("", amfd_data_.c_str());
    381 
    382   // Verify that the log buf is empty, and no error messages.
    383   ASSERT_STREQ("", getFakeLogBuf().c_str());
    384   ASSERT_STREQ("", getFakeLogPrint().c_str());
    385 }
    386 
    387 TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) {
    388   backtrace_map_t map;
    389 
    390   map.start = 0xa434000;
    391   map.end = 0xa435000;
    392   map.offset = 0x1000;
    393   map.load_base = 0xd000;
    394   map.flags = PROT_WRITE;
    395   map_mock_->AddMap(map);
    396 
    397   map.start = 0xa534000;
    398   map.end = 0xa535000;
    399   map.offset = 0x3000;
    400   map.load_base = 0x2000;
    401   map.flags = PROT_EXEC;
    402   map_mock_->AddMap(map);
    403 
    404   map.start = 0xa634000;
    405   map.end = 0xa635000;
    406   map.offset = 0;
    407   map.load_base = 0;
    408   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
    409   map.name = "/system/lib/fake.so";
    410   map_mock_->AddMap(map);
    411 
    412   siginfo_t si;
    413   memset(&si, 0, sizeof(si));
    414   si.si_signo = SIGBUS;
    415   si.si_code = SI_KERNEL;
    416   si.si_addr = reinterpret_cast<void*>(0xa534040);
    417   ptrace_set_fake_getsiginfo(si);
    418   dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    419 
    420   std::string tombstone_contents;
    421   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    422   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    423   const char* expected_dump = \
    424 "\nmemory map: (fault address prefixed with --->)\n"
    425 #if defined(__LP64__)
    426 "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
    427 "--->00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
    428 "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n";
    429 #else
    430 "    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
    431 "--->0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
    432 "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n";
    433 #endif
    434   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
    435 
    436   ASSERT_STREQ("", amfd_data_.c_str());
    437 
    438   // Verify that the log buf is empty, and no error messages.
    439   ASSERT_STREQ("", getFakeLogBuf().c_str());
    440   ASSERT_STREQ("", getFakeLogPrint().c_str());
    441 }
    442 
    443 TEST_F(TombstoneTest, multiple_maps_fault_address_after) {
    444   backtrace_map_t map;
    445 
    446   map.start = 0xa434000;
    447   map.end = 0xa435000;
    448   map.offset = 0x1000;
    449   map.load_base = 0xd000;
    450   map.flags = PROT_WRITE;
    451   map_mock_->AddMap(map);
    452 
    453   map.start = 0xa534000;
    454   map.end = 0xa535000;
    455   map.offset = 0x3000;
    456   map.load_base = 0x2000;
    457   map.flags = PROT_EXEC;
    458   map_mock_->AddMap(map);
    459 
    460   map.start = 0xa634000;
    461   map.end = 0xa635000;
    462   map.offset = 0;
    463   map.load_base = 0;
    464   map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
    465   map.name = "/system/lib/fake.so";
    466   map_mock_->AddMap(map);
    467 
    468   siginfo_t si;
    469   memset(&si, 0, sizeof(si));
    470   si.si_signo = SIGBUS;
    471   si.si_code = SI_KERNEL;
    472 #if defined(__LP64__)
    473   si.si_addr = reinterpret_cast<void*>(0x12345a534040UL);
    474 #else
    475   si.si_addr = reinterpret_cast<void*>(0xf534040UL);
    476 #endif
    477   ptrace_set_fake_getsiginfo(si);
    478   dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    479 
    480   std::string tombstone_contents;
    481   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    482   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    483   const char* expected_dump = \
    484 "\nmemory map: (fault address prefixed with --->)\n"
    485 #if defined(__LP64__)
    486 "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n"
    487 "    00000000'0a534000-00000000'0a534fff --x      3000      1000  (load base 0x2000)\n"
    488 "    00000000'0a634000-00000000'0a634fff rwx         0      1000  /system/lib/fake.so\n"
    489 "--->Fault address falls at 00001234'5a534040 after any mapped regions\n";
    490 #else
    491 "    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n"
    492 "    0a534000-0a534fff --x      3000      1000  (load base 0x2000)\n"
    493 "    0a634000-0a634fff rwx         0      1000  /system/lib/fake.so\n"
    494 "--->Fault address falls at 0f534040 after any mapped regions\n";
    495 #endif
    496   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
    497 
    498   ASSERT_STREQ("", amfd_data_.c_str());
    499 
    500   // Verify that the log buf is empty, and no error messages.
    501   ASSERT_STREQ("", getFakeLogBuf().c_str());
    502   ASSERT_STREQ("", getFakeLogPrint().c_str());
    503 }
    504 
    505 TEST_F(TombstoneTest, multiple_maps_getsiginfo_fail) {
    506   backtrace_map_t map;
    507 
    508   map.start = 0xa434000;
    509   map.end = 0xa435000;
    510   map.offset = 0x1000;
    511   map.load_base = 0xd000;
    512   map.flags = PROT_WRITE;
    513   map_mock_->AddMap(map);
    514 
    515   siginfo_t si;
    516   memset(&si, 0, sizeof(si));
    517   ptrace_set_fake_getsiginfo(si);
    518   dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    519 
    520   std::string tombstone_contents;
    521   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    522   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    523   const char* expected_dump = \
    524 "\nmemory map:\n"
    525 #if defined(__LP64__)
    526 "    00000000'0a434000-00000000'0a434fff -w-      1000      1000  (load base 0xd000)\n";
    527 #else
    528 "    0a434000-0a434fff -w-      1000      1000  (load base 0xd000)\n";
    529 #endif
    530   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
    531 
    532   ASSERT_STREQ("", amfd_data_.c_str());
    533 
    534   // Verify that the log buf is empty, and no error messages.
    535   ASSERT_STREQ("", getFakeLogBuf().c_str());
    536   ASSERT_STREQ("6 DEBUG Cannot get siginfo for 100: Bad address\n\n", getFakeLogPrint().c_str());
    537 }
    538 
    539 TEST_F(TombstoneTest, multiple_maps_check_signal_has_si_addr) {
    540   backtrace_map_t map;
    541 
    542   map.start = 0xa434000;
    543   map.end = 0xa435000;
    544   map.flags = PROT_WRITE;
    545   map_mock_->AddMap(map);
    546 
    547   for (int i = 1; i < 255; i++) {
    548     ASSERT_TRUE(ftruncate(log_.tfd, 0) == 0);
    549     ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    550 
    551     siginfo_t si;
    552     memset(&si, 0, sizeof(si));
    553     si.si_signo = i;
    554     si.si_code = SI_KERNEL;
    555     si.si_addr = reinterpret_cast<void*>(0x1000);
    556     ptrace_set_fake_getsiginfo(si);
    557     dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
    558 
    559     std::string tombstone_contents;
    560     ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    561     ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    562     bool has_addr = false;
    563     switch (si.si_signo) {
    564     case SIGBUS:
    565     case SIGFPE:
    566     case SIGILL:
    567     case SIGSEGV:
    568     case SIGTRAP:
    569       has_addr = true;
    570       break;
    571     }
    572 
    573     const char* expected_addr_dump = \
    574 "\nmemory map: (fault address prefixed with --->)\n"
    575 #if defined(__LP64__)
    576 "--->Fault address falls at 00000000'00001000 before any mapped regions\n"
    577 "    00000000'0a434000-00000000'0a434fff -w-         0      1000\n";
    578 #else
    579 "--->Fault address falls at 00001000 before any mapped regions\n"
    580 "    0a434000-0a434fff -w-         0      1000\n";
    581 #endif
    582     const char* expected_dump = \
    583 "\nmemory map:\n"
    584 #if defined(__LP64__)
    585 "    00000000'0a434000-00000000'0a434fff -w-         0      1000\n";
    586 #else
    587 "    0a434000-0a434fff -w-         0      1000\n";
    588 #endif
    589     if (has_addr) {
    590       ASSERT_STREQ(expected_addr_dump, tombstone_contents.c_str())
    591         << "Signal " << si.si_signo << " expected to include an address.";
    592     } else {
    593       ASSERT_STREQ(expected_dump, tombstone_contents.c_str())
    594         << "Signal " << si.si_signo << " is not expected to include an address.";
    595     }
    596 
    597     ASSERT_STREQ("", amfd_data_.c_str());
    598 
    599     // Verify that the log buf is empty, and no error messages.
    600     ASSERT_STREQ("", getFakeLogBuf().c_str());
    601     ASSERT_STREQ("", getFakeLogPrint().c_str());
    602   }
    603 }
    604 
    605 TEST_F(TombstoneTest, dump_signal_info_error) {
    606   siginfo_t si;
    607   memset(&si, 0, sizeof(si));
    608   ptrace_set_fake_getsiginfo(si);
    609 
    610   dump_signal_info(&log_, 123);
    611 
    612   std::string tombstone_contents;
    613   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    614   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    615   ASSERT_STREQ("", tombstone_contents.c_str());
    616 
    617   ASSERT_STREQ("", getFakeLogBuf().c_str());
    618   ASSERT_STREQ("6 DEBUG cannot get siginfo: Bad address\n\n", getFakeLogPrint().c_str());
    619 
    620   ASSERT_STREQ("", amfd_data_.c_str());
    621 }
    622 
    623 TEST_F(TombstoneTest, dump_log_file_error) {
    624   log_.should_retrieve_logcat = true;
    625   dump_log_file(&log_, 123, "/fake/filename", 10);
    626 
    627   std::string tombstone_contents;
    628   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
    629   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
    630   ASSERT_STREQ("", tombstone_contents.c_str());
    631 
    632   ASSERT_STREQ("", getFakeLogBuf().c_str());
    633   ASSERT_STREQ("6 DEBUG Unable to open /fake/filename: Permission denied\n\n",
    634                getFakeLogPrint().c_str());
    635 
    636   ASSERT_STREQ("", amfd_data_.c_str());
    637 }
    638 
    639 TEST_F(TombstoneTest, dump_header_info) {
    640   dump_header_info(&log_);
    641 
    642   std::string expected = "Build fingerprint: 'unknown'\nRevision: 'unknown'\n";
    643   expected += android::base::StringPrintf("ABI: '%s'\n", ABI_STRING);
    644   ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
    645 }
    646