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 si.si_signo = SIGABRT;
81 ptrace_set_fake_getsiginfo(si);
82 }
83
TearDown()84 virtual void TearDown() {
85 if (log_.tfd >= 0) {
86 close(log_.tfd);
87 }
88 }
89
90 std::unique_ptr<BacktraceMapMock> map_mock_;
91 std::unique_ptr<BacktraceMock> backtrace_mock_;
92
93 log_t log_;
94 std::string amfd_data_;
95 };
96
TEST_F(TombstoneTest,single_map)97 TEST_F(TombstoneTest, single_map) {
98 backtrace_map_t map;
99 #if defined(__LP64__)
100 map.start = 0x123456789abcd000UL;
101 map.end = 0x123456789abdf000UL;
102 #else
103 map.start = 0x1234000;
104 map.end = 0x1235000;
105 #endif
106 map_mock_->AddMap(map);
107
108 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
109
110 std::string tombstone_contents;
111 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
112 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
113 const char* expected_dump = \
114 "\nmemory map:\n"
115 #if defined(__LP64__)
116 " 12345678'9abcd000-12345678'9abdefff --- 0 12000\n";
117 #else
118 " 01234000-01234fff --- 0 1000\n";
119 #endif
120 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
121
122 ASSERT_STREQ("", amfd_data_.c_str());
123
124 // Verify that the log buf is empty, and no error messages.
125 ASSERT_STREQ("", getFakeLogBuf().c_str());
126 ASSERT_STREQ("", getFakeLogPrint().c_str());
127 }
128
TEST_F(TombstoneTest,single_map_elf_build_id)129 TEST_F(TombstoneTest, single_map_elf_build_id) {
130 backtrace_map_t map;
131 #if defined(__LP64__)
132 map.start = 0x123456789abcd000UL;
133 map.end = 0x123456789abdf000UL;
134 #else
135 map.start = 0x1234000;
136 map.end = 0x1235000;
137 #endif
138 map.flags = PROT_READ;
139 map.name = "/system/lib/libfake.so";
140 map_mock_->AddMap(map);
141
142 elf_set_fake_build_id("abcdef1234567890abcdef1234567890");
143 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
144
145 std::string tombstone_contents;
146 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
147 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
148 const char* expected_dump = \
149 "\nmemory map:\n"
150 #if defined(__LP64__)
151 " 12345678'9abcd000-12345678'9abdefff r-- 0 12000 /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
152 #else
153 " 01234000-01234fff r-- 0 1000 /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
154 #endif
155 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
156
157 ASSERT_STREQ("", amfd_data_.c_str());
158
159 // Verify that the log buf is empty, and no error messages.
160 ASSERT_STREQ("", getFakeLogBuf().c_str());
161 ASSERT_STREQ("", getFakeLogPrint().c_str());
162 }
163
164 // Even though build id is present, it should not be printed in either of
165 // these cases.
TEST_F(TombstoneTest,single_map_no_build_id)166 TEST_F(TombstoneTest, single_map_no_build_id) {
167 backtrace_map_t map;
168 #if defined(__LP64__)
169 map.start = 0x123456789abcd000UL;
170 map.end = 0x123456789abdf000UL;
171 #else
172 map.start = 0x1234000;
173 map.end = 0x1235000;
174 #endif
175 map.flags = PROT_WRITE;
176 map_mock_->AddMap(map);
177
178 map.name = "/system/lib/libfake.so";
179 map_mock_->AddMap(map);
180
181 elf_set_fake_build_id("abcdef1234567890abcdef1234567890");
182 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
183
184 std::string tombstone_contents;
185 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
186 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
187 const char* expected_dump = \
188 "\nmemory map:\n"
189 #if defined(__LP64__)
190 " 12345678'9abcd000-12345678'9abdefff -w- 0 12000\n"
191 " 12345678'9abcd000-12345678'9abdefff -w- 0 12000 /system/lib/libfake.so\n";
192 #else
193 " 01234000-01234fff -w- 0 1000\n"
194 " 01234000-01234fff -w- 0 1000 /system/lib/libfake.so\n";
195 #endif
196 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
197
198 ASSERT_STREQ("", amfd_data_.c_str());
199
200 // Verify that the log buf is empty, and no error messages.
201 ASSERT_STREQ("", getFakeLogBuf().c_str());
202 ASSERT_STREQ("", getFakeLogPrint().c_str());
203 }
204
TEST_F(TombstoneTest,multiple_maps)205 TEST_F(TombstoneTest, multiple_maps) {
206 backtrace_map_t map;
207
208 map.start = 0xa234000;
209 map.end = 0xa235000;
210 map_mock_->AddMap(map);
211
212 map.start = 0xa334000;
213 map.end = 0xa335000;
214 map.offset = 0xf000;
215 map.flags = PROT_READ;
216 map_mock_->AddMap(map);
217
218 map.start = 0xa434000;
219 map.end = 0xa435000;
220 map.offset = 0x1000;
221 map.load_base = 0xd000;
222 map.flags = PROT_WRITE;
223 map_mock_->AddMap(map);
224
225 map.start = 0xa534000;
226 map.end = 0xa535000;
227 map.offset = 0x3000;
228 map.load_base = 0x2000;
229 map.flags = PROT_EXEC;
230 map_mock_->AddMap(map);
231
232 map.start = 0xa634000;
233 map.end = 0xa635000;
234 map.offset = 0;
235 map.load_base = 0;
236 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
237 map.name = "/system/lib/fake.so";
238 map_mock_->AddMap(map);
239
240 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
241
242 std::string tombstone_contents;
243 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
244 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
245 const char* expected_dump = \
246 "\nmemory map:\n"
247 #if defined(__LP64__)
248 " 00000000'0a234000-00000000'0a234fff --- 0 1000\n"
249 " 00000000'0a334000-00000000'0a334fff r-- f000 1000\n"
250 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
251 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
252 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
253 #else
254 " 0a234000-0a234fff --- 0 1000\n"
255 " 0a334000-0a334fff r-- f000 1000\n"
256 " 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
257 " 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
258 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
259 #endif
260 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
261
262 ASSERT_STREQ("", amfd_data_.c_str());
263
264 // Verify that the log buf is empty, and no error messages.
265 ASSERT_STREQ("", getFakeLogBuf().c_str());
266 ASSERT_STREQ("", getFakeLogPrint().c_str());
267 }
268
TEST_F(TombstoneTest,multiple_maps_fault_address_before)269 TEST_F(TombstoneTest, multiple_maps_fault_address_before) {
270 backtrace_map_t map;
271
272 map.start = 0xa434000;
273 map.end = 0xa435000;
274 map.offset = 0x1000;
275 map.load_base = 0xd000;
276 map.flags = PROT_WRITE;
277 map_mock_->AddMap(map);
278
279 map.start = 0xa534000;
280 map.end = 0xa535000;
281 map.offset = 0x3000;
282 map.load_base = 0x2000;
283 map.flags = PROT_EXEC;
284 map_mock_->AddMap(map);
285
286 map.start = 0xa634000;
287 map.end = 0xa635000;
288 map.offset = 0;
289 map.load_base = 0;
290 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
291 map.name = "/system/lib/fake.so";
292 map_mock_->AddMap(map);
293
294 siginfo_t si;
295 si.si_signo = SIGBUS;
296 si.si_addr = reinterpret_cast<void*>(0x1000);
297 ptrace_set_fake_getsiginfo(si);
298 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
299
300 std::string tombstone_contents;
301 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
302 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
303 const char* expected_dump = \
304 "\nmemory map: (fault address prefixed with --->)\n"
305 #if defined(__LP64__)
306 "--->Fault address falls at 00000000'00001000 before any mapped regions\n"
307 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
308 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
309 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
310 #else
311 "--->Fault address falls at 00001000 before any mapped regions\n"
312 " 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
313 " 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
314 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
315 #endif
316 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
317
318 ASSERT_STREQ("", amfd_data_.c_str());
319
320 // Verify that the log buf is empty, and no error messages.
321 ASSERT_STREQ("", getFakeLogBuf().c_str());
322 ASSERT_STREQ("", getFakeLogPrint().c_str());
323 }
324
TEST_F(TombstoneTest,multiple_maps_fault_address_between)325 TEST_F(TombstoneTest, multiple_maps_fault_address_between) {
326 backtrace_map_t map;
327
328 map.start = 0xa434000;
329 map.end = 0xa435000;
330 map.offset = 0x1000;
331 map.load_base = 0xd000;
332 map.flags = PROT_WRITE;
333 map_mock_->AddMap(map);
334
335 map.start = 0xa534000;
336 map.end = 0xa535000;
337 map.offset = 0x3000;
338 map.load_base = 0x2000;
339 map.flags = PROT_EXEC;
340 map_mock_->AddMap(map);
341
342 map.start = 0xa634000;
343 map.end = 0xa635000;
344 map.offset = 0;
345 map.load_base = 0;
346 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
347 map.name = "/system/lib/fake.so";
348 map_mock_->AddMap(map);
349
350 siginfo_t si;
351 si.si_signo = SIGBUS;
352 si.si_addr = reinterpret_cast<void*>(0xa533000);
353 ptrace_set_fake_getsiginfo(si);
354 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
355
356 std::string tombstone_contents;
357 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
358 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
359 const char* expected_dump = \
360 "\nmemory map: (fault address prefixed with --->)\n"
361 #if defined(__LP64__)
362 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
363 "--->Fault address falls at 00000000'0a533000 between mapped regions\n"
364 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
365 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
366 #else
367 " 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
368 "--->Fault address falls at 0a533000 between mapped regions\n"
369 " 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
370 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
371 #endif
372 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
373
374 ASSERT_STREQ("", amfd_data_.c_str());
375
376 // Verify that the log buf is empty, and no error messages.
377 ASSERT_STREQ("", getFakeLogBuf().c_str());
378 ASSERT_STREQ("", getFakeLogPrint().c_str());
379 }
380
TEST_F(TombstoneTest,multiple_maps_fault_address_in_map)381 TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) {
382 backtrace_map_t map;
383
384 map.start = 0xa434000;
385 map.end = 0xa435000;
386 map.offset = 0x1000;
387 map.load_base = 0xd000;
388 map.flags = PROT_WRITE;
389 map_mock_->AddMap(map);
390
391 map.start = 0xa534000;
392 map.end = 0xa535000;
393 map.offset = 0x3000;
394 map.load_base = 0x2000;
395 map.flags = PROT_EXEC;
396 map_mock_->AddMap(map);
397
398 map.start = 0xa634000;
399 map.end = 0xa635000;
400 map.offset = 0;
401 map.load_base = 0;
402 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
403 map.name = "/system/lib/fake.so";
404 map_mock_->AddMap(map);
405
406 siginfo_t si;
407 si.si_signo = SIGBUS;
408 si.si_addr = reinterpret_cast<void*>(0xa534040);
409 ptrace_set_fake_getsiginfo(si);
410 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
411
412 std::string tombstone_contents;
413 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
414 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
415 const char* expected_dump = \
416 "\nmemory map: (fault address prefixed with --->)\n"
417 #if defined(__LP64__)
418 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
419 "--->00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
420 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
421 #else
422 " 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
423 "--->0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
424 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
425 #endif
426 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
427
428 ASSERT_STREQ("", amfd_data_.c_str());
429
430 // Verify that the log buf is empty, and no error messages.
431 ASSERT_STREQ("", getFakeLogBuf().c_str());
432 ASSERT_STREQ("", getFakeLogPrint().c_str());
433 }
434
TEST_F(TombstoneTest,multiple_maps_fault_address_after)435 TEST_F(TombstoneTest, multiple_maps_fault_address_after) {
436 backtrace_map_t map;
437
438 map.start = 0xa434000;
439 map.end = 0xa435000;
440 map.offset = 0x1000;
441 map.load_base = 0xd000;
442 map.flags = PROT_WRITE;
443 map_mock_->AddMap(map);
444
445 map.start = 0xa534000;
446 map.end = 0xa535000;
447 map.offset = 0x3000;
448 map.load_base = 0x2000;
449 map.flags = PROT_EXEC;
450 map_mock_->AddMap(map);
451
452 map.start = 0xa634000;
453 map.end = 0xa635000;
454 map.offset = 0;
455 map.load_base = 0;
456 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
457 map.name = "/system/lib/fake.so";
458 map_mock_->AddMap(map);
459
460 siginfo_t si;
461 si.si_signo = SIGBUS;
462 #if defined(__LP64__)
463 si.si_addr = reinterpret_cast<void*>(0x12345a534040UL);
464 #else
465 si.si_addr = reinterpret_cast<void*>(0xf534040UL);
466 #endif
467 ptrace_set_fake_getsiginfo(si);
468 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
469
470 std::string tombstone_contents;
471 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
472 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
473 const char* expected_dump = \
474 "\nmemory map: (fault address prefixed with --->)\n"
475 #if defined(__LP64__)
476 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
477 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
478 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"
479 "--->Fault address falls at 00001234'5a534040 after any mapped regions\n";
480 #else
481 " 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
482 " 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
483 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"
484 "--->Fault address falls at 0f534040 after any mapped regions\n";
485 #endif
486 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
487
488 ASSERT_STREQ("", amfd_data_.c_str());
489
490 // Verify that the log buf is empty, and no error messages.
491 ASSERT_STREQ("", getFakeLogBuf().c_str());
492 ASSERT_STREQ("", getFakeLogPrint().c_str());
493 }
494
TEST_F(TombstoneTest,multiple_maps_getsiginfo_fail)495 TEST_F(TombstoneTest, multiple_maps_getsiginfo_fail) {
496 backtrace_map_t map;
497
498 map.start = 0xa434000;
499 map.end = 0xa435000;
500 map.offset = 0x1000;
501 map.load_base = 0xd000;
502 map.flags = PROT_WRITE;
503 map_mock_->AddMap(map);
504
505 siginfo_t si;
506 si.si_signo = 0;
507 ptrace_set_fake_getsiginfo(si);
508 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
509
510 std::string tombstone_contents;
511 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
512 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
513 const char* expected_dump = \
514 "\nmemory map:\n"
515 #if defined(__LP64__)
516 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n";
517 #else
518 " 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n";
519 #endif
520 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
521
522 ASSERT_STREQ("", amfd_data_.c_str());
523
524 // Verify that the log buf is empty, and no error messages.
525 ASSERT_STREQ("", getFakeLogBuf().c_str());
526 ASSERT_STREQ("6 DEBUG Cannot get siginfo for 100: Bad address\n\n", getFakeLogPrint().c_str());
527 }
528
TEST_F(TombstoneTest,multiple_maps_check_signal_has_si_addr)529 TEST_F(TombstoneTest, multiple_maps_check_signal_has_si_addr) {
530 backtrace_map_t map;
531
532 map.start = 0xa434000;
533 map.end = 0xa435000;
534 map.flags = PROT_WRITE;
535 map_mock_->AddMap(map);
536
537 for (int i = 1; i < 255; i++) {
538 ASSERT_TRUE(ftruncate(log_.tfd, 0) == 0);
539 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
540
541 siginfo_t si;
542 si.si_signo = i;
543 si.si_addr = reinterpret_cast<void*>(0x1000);
544 ptrace_set_fake_getsiginfo(si);
545 dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
546
547 std::string tombstone_contents;
548 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
549 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
550 bool has_addr = false;
551 switch (si.si_signo) {
552 case SIGBUS:
553 case SIGFPE:
554 case SIGILL:
555 case SIGSEGV:
556 case SIGTRAP:
557 has_addr = true;
558 break;
559 }
560
561 const char* expected_addr_dump = \
562 "\nmemory map: (fault address prefixed with --->)\n"
563 #if defined(__LP64__)
564 "--->Fault address falls at 00000000'00001000 before any mapped regions\n"
565 " 00000000'0a434000-00000000'0a434fff -w- 0 1000\n";
566 #else
567 "--->Fault address falls at 00001000 before any mapped regions\n"
568 " 0a434000-0a434fff -w- 0 1000\n";
569 #endif
570 const char* expected_dump = \
571 "\nmemory map:\n"
572 #if defined(__LP64__)
573 " 00000000'0a434000-00000000'0a434fff -w- 0 1000\n";
574 #else
575 " 0a434000-0a434fff -w- 0 1000\n";
576 #endif
577 if (has_addr) {
578 ASSERT_STREQ(expected_addr_dump, tombstone_contents.c_str())
579 << "Signal " << si.si_signo << " expected to include an address.";
580 } else {
581 ASSERT_STREQ(expected_dump, tombstone_contents.c_str())
582 << "Signal " << si.si_signo << " is not expected to include an address.";
583 }
584
585 ASSERT_STREQ("", amfd_data_.c_str());
586
587 // Verify that the log buf is empty, and no error messages.
588 ASSERT_STREQ("", getFakeLogBuf().c_str());
589 ASSERT_STREQ("", getFakeLogPrint().c_str());
590 }
591 }
592
TEST_F(TombstoneTest,dump_signal_info_error)593 TEST_F(TombstoneTest, dump_signal_info_error) {
594 siginfo_t si;
595 si.si_signo = 0;
596 ptrace_set_fake_getsiginfo(si);
597
598 dump_signal_info(&log_, 123, SIGSEGV, 10);
599
600 std::string tombstone_contents;
601 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
602 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
603 ASSERT_STREQ("", tombstone_contents.c_str());
604
605 ASSERT_STREQ("", getFakeLogBuf().c_str());
606 ASSERT_STREQ("6 DEBUG cannot get siginfo: Bad address\n\n", getFakeLogPrint().c_str());
607
608 ASSERT_STREQ("", amfd_data_.c_str());
609 }
610
TEST_F(TombstoneTest,dump_log_file_error)611 TEST_F(TombstoneTest, dump_log_file_error) {
612 log_.should_retrieve_logcat = true;
613 dump_log_file(&log_, 123, "/fake/filename", 10);
614
615 std::string tombstone_contents;
616 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
617 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
618 ASSERT_STREQ("", tombstone_contents.c_str());
619
620 ASSERT_STREQ("", getFakeLogBuf().c_str());
621 ASSERT_STREQ("6 DEBUG Unable to open /fake/filename: Permission denied\n\n",
622 getFakeLogPrint().c_str());
623
624 ASSERT_STREQ("", amfd_data_.c_str());
625 }
626
TEST_F(TombstoneTest,dump_header_info)627 TEST_F(TombstoneTest, dump_header_info) {
628 dump_header_info(&log_);
629
630 std::string expected = "Build fingerprint: 'unknown'\nRevision: 'unknown'\n";
631 expected += android::base::StringPrintf("ABI: '%s'\n", ABI_STRING);
632 ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
633 }
634