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