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 
dump_registers(log_t *,pid_t)39 void dump_registers(log_t*, pid_t) {
40 }
41 
dump_memory_and_code(log_t *,Backtrace *)42 void dump_memory_and_code(log_t*, Backtrace*) {
43 }
44 
dump_backtrace_to_log(Backtrace *,log_t *,char const *)45 void dump_backtrace_to_log(Backtrace*, log_t*, char const*) {
46 }
47 
48 class TombstoneTest : public ::testing::Test {
49  protected:
SetUp()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 
TearDown()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 
TEST_F(TombstoneTest,single_map)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 
TEST_F(TombstoneTest,single_map_elf_build_id)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.
TEST_F(TombstoneTest,single_map_no_build_id)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 
TEST_F(TombstoneTest,multiple_maps)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 
TEST_F(TombstoneTest,multiple_maps_fault_address_before)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 
TEST_F(TombstoneTest,multiple_maps_fault_address_between)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 
TEST_F(TombstoneTest,multiple_maps_fault_address_in_map)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 
TEST_F(TombstoneTest,multiple_maps_fault_address_after)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 
TEST_F(TombstoneTest,multiple_maps_getsiginfo_fail)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 
TEST_F(TombstoneTest,multiple_maps_check_signal_has_si_addr)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 
TEST_F(TombstoneTest,dump_signal_info_error)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 
TEST_F(TombstoneTest,dump_log_file_error)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 
TEST_F(TombstoneTest,dump_header_info)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