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 #include <sys/mman.h>
19 #include <time.h>
20
21 #include <memory>
22 #include <string>
23
24 #include <android-base/file.h>
25 #include <android-base/properties.h>
26 #include <gtest/gtest.h>
27
28 #include "libdebuggerd/utility.h"
29
30 #include "UnwinderMock.h"
31 #include "host_signal_fixup.h"
32 #include "log_fake.h"
33
34 #include "tombstone.cpp"
35
36 class TombstoneTest : public ::testing::Test {
37 protected:
SetUp()38 virtual void SetUp() {
39 unwinder_mock_.reset(new UnwinderMock());
40
41 char tmp_file[256];
42 const char data_template[] = "/data/local/tmp/debuggerd_memory_testXXXXXX";
43 memcpy(tmp_file, data_template, sizeof(data_template));
44 int tombstone_fd = mkstemp(tmp_file);
45 if (tombstone_fd == -1) {
46 const char tmp_template[] = "/tmp/debuggerd_memory_testXXXXXX";
47 memcpy(tmp_file, tmp_template, sizeof(tmp_template));
48 tombstone_fd = mkstemp(tmp_file);
49 if (tombstone_fd == -1) {
50 abort();
51 }
52 }
53 if (unlink(tmp_file) == -1) {
54 abort();
55 }
56
57 log_.tfd = tombstone_fd;
58 amfd_data_.clear();
59 log_.amfd_data = &amfd_data_;
60 log_.crashed_tid = 12;
61 log_.current_tid = 12;
62 log_.should_retrieve_logcat = false;
63
64 resetLogs();
65 }
66
TearDown()67 virtual void TearDown() {
68 if (log_.tfd >= 0) {
69 close(log_.tfd);
70 }
71 }
72
73 std::unique_ptr<UnwinderMock> unwinder_mock_;
74
75 log_t log_;
76 std::string amfd_data_;
77 };
78
TEST_F(TombstoneTest,single_map)79 TEST_F(TombstoneTest, single_map) {
80 #if defined(__LP64__)
81 unwinder_mock_->MockAddMap(0x123456789abcd000UL, 0x123456789abdf000UL, 0, 0, "", 0);
82 #else
83 unwinder_mock_->MockAddMap(0x1234000, 0x1235000, 0, 0, "", 0);
84 #endif
85
86 dump_all_maps(&log_, unwinder_mock_.get(), 0);
87
88 std::string tombstone_contents;
89 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
90 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
91 const char* expected_dump = \
92 "\nmemory map (1 entry):\n"
93 #if defined(__LP64__)
94 " 12345678'9abcd000-12345678'9abdefff --- 0 12000\n";
95 #else
96 " 01234000-01234fff --- 0 1000\n";
97 #endif
98 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
99
100 ASSERT_STREQ("", amfd_data_.c_str());
101
102 // Verify that the log buf is empty, and no error messages.
103 ASSERT_STREQ("", getFakeLogBuf().c_str());
104 ASSERT_STREQ("", getFakeLogPrint().c_str());
105 }
106
TEST_F(TombstoneTest,single_map_elf_build_id)107 TEST_F(TombstoneTest, single_map_elf_build_id) {
108 uint64_t build_id_offset;
109 #if defined(__LP64__)
110 build_id_offset = 0x123456789abcd000UL;
111 unwinder_mock_->MockAddMap(build_id_offset, 0x123456789abdf000UL, 0, PROT_READ,
112 "/system/lib/libfake.so", 0);
113 #else
114 build_id_offset = 0x1234000;
115 unwinder_mock_->MockAddMap(0x1234000, 0x1235000, 0, PROT_READ, "/system/lib/libfake.so", 0);
116 #endif
117
118 unwinder_mock_->MockSetBuildID(
119 build_id_offset,
120 std::string{static_cast<char>(0xab), static_cast<char>(0xcd), static_cast<char>(0xef),
121 static_cast<char>(0x12), static_cast<char>(0x34), static_cast<char>(0x56),
122 static_cast<char>(0x78), static_cast<char>(0x90), static_cast<char>(0xab),
123 static_cast<char>(0xcd), static_cast<char>(0xef), static_cast<char>(0x12),
124 static_cast<char>(0x34), static_cast<char>(0x56), static_cast<char>(0x78),
125 static_cast<char>(0x90)});
126 dump_all_maps(&log_, unwinder_mock_.get(), 0);
127
128 std::string tombstone_contents;
129 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
130 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
131 const char* expected_dump = \
132 "\nmemory map (1 entry):\n"
133 #if defined(__LP64__)
134 " 12345678'9abcd000-12345678'9abdefff r-- 0 12000 /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
135 #else
136 " 01234000-01234fff r-- 0 1000 /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
137 #endif
138 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
139
140 ASSERT_STREQ("", amfd_data_.c_str());
141
142 // Verify that the log buf is empty, and no error messages.
143 ASSERT_STREQ("", getFakeLogBuf().c_str());
144 ASSERT_STREQ("", getFakeLogPrint().c_str());
145 }
146
TEST_F(TombstoneTest,multiple_maps)147 TEST_F(TombstoneTest, multiple_maps) {
148 unwinder_mock_->MockAddMap(0xa234000, 0xa235000, 0, 0, "", 0);
149 unwinder_mock_->MockAddMap(0xa334000, 0xa335000, 0xf000, PROT_READ, "", 0);
150 unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
151 unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
152 unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
153 "/system/lib/fake.so", 0);
154
155 dump_all_maps(&log_, unwinder_mock_.get(), 0);
156
157 std::string tombstone_contents;
158 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
159 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
160 const char* expected_dump =
161 "\nmemory map (5 entries):\n"
162 #if defined(__LP64__)
163 " 00000000'0a234000-00000000'0a234fff --- 0 1000\n"
164 " 00000000'0a334000-00000000'0a334fff r-- f000 1000\n"
165 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
166 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
167 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
168 #else
169 " 0a234000-0a234fff --- 0 1000\n"
170 " 0a334000-0a334fff r-- f000 1000\n"
171 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
172 " 0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
173 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
174 #endif
175 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
176
177 ASSERT_STREQ("", amfd_data_.c_str());
178
179 // Verify that the log buf is empty, and no error messages.
180 ASSERT_STREQ("", getFakeLogBuf().c_str());
181 ASSERT_STREQ("", getFakeLogPrint().c_str());
182 }
183
TEST_F(TombstoneTest,multiple_maps_fault_address_before)184 TEST_F(TombstoneTest, multiple_maps_fault_address_before) {
185 unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
186 unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
187 unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
188 "/system/lib/fake.so", 0);
189
190 dump_all_maps(&log_, unwinder_mock_.get(), 0x1000);
191
192 std::string tombstone_contents;
193 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
194 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
195 const char* expected_dump =
196 "\nmemory map (3 entries):\n"
197 #if defined(__LP64__)
198 "--->Fault address falls at 00000000'00001000 before any mapped regions\n"
199 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
200 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
201 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
202 #else
203 "--->Fault address falls at 00001000 before any mapped regions\n"
204 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
205 " 0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
206 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
207 #endif
208 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
209
210 ASSERT_STREQ("", amfd_data_.c_str());
211
212 // Verify that the log buf is empty, and no error messages.
213 ASSERT_STREQ("", getFakeLogBuf().c_str());
214 ASSERT_STREQ("", getFakeLogPrint().c_str());
215 }
216
TEST_F(TombstoneTest,multiple_maps_fault_address_between)217 TEST_F(TombstoneTest, multiple_maps_fault_address_between) {
218 unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
219 unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
220 unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
221 "/system/lib/fake.so", 0);
222
223 dump_all_maps(&log_, unwinder_mock_.get(), 0xa533000);
224
225 std::string tombstone_contents;
226 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
227 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
228 const char* expected_dump =
229 "\nmemory map (3 entries): (fault address prefixed with --->)\n"
230 #if defined(__LP64__)
231 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
232 "--->Fault address falls at 00000000'0a533000 between mapped regions\n"
233 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
234 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
235 #else
236 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
237 "--->Fault address falls at 0a533000 between mapped regions\n"
238 " 0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
239 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
240 #endif
241 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
242
243 ASSERT_STREQ("", amfd_data_.c_str());
244
245 // Verify that the log buf is empty, and no error messages.
246 ASSERT_STREQ("", getFakeLogBuf().c_str());
247 ASSERT_STREQ("", getFakeLogPrint().c_str());
248 }
249
TEST_F(TombstoneTest,multiple_maps_fault_address_in_map)250 TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) {
251 unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
252 unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
253 unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
254 "/system/lib/fake.so", 0);
255
256 dump_all_maps(&log_, unwinder_mock_.get(), 0xa534040);
257
258 std::string tombstone_contents;
259 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
260 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
261 const char* expected_dump =
262 "\nmemory map (3 entries): (fault address prefixed with --->)\n"
263 #if defined(__LP64__)
264 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
265 "--->00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
266 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
267 #else
268 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
269 "--->0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
270 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
271 #endif
272 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
273
274 ASSERT_STREQ("", amfd_data_.c_str());
275
276 // Verify that the log buf is empty, and no error messages.
277 ASSERT_STREQ("", getFakeLogBuf().c_str());
278 ASSERT_STREQ("", getFakeLogPrint().c_str());
279 }
280
TEST_F(TombstoneTest,multiple_maps_fault_address_after)281 TEST_F(TombstoneTest, multiple_maps_fault_address_after) {
282 unwinder_mock_->MockAddMap(0xa434000, 0xa435000, 0x1000, PROT_WRITE, "", 0xd000);
283 unwinder_mock_->MockAddMap(0xa534000, 0xa535000, 0x3000, PROT_EXEC, "", 0x2000);
284 unwinder_mock_->MockAddMap(0xa634000, 0xa635000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
285 "/system/lib/fake.so", 0);
286
287 #if defined(__LP64__)
288 uint64_t addr = 0x12345a534040UL;
289 #else
290 uint64_t addr = 0xf534040UL;
291 #endif
292 dump_all_maps(&log_, unwinder_mock_.get(), addr);
293
294 std::string tombstone_contents;
295 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
296 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
297 const char* expected_dump =
298 "\nmemory map (3 entries): (fault address prefixed with --->)\n"
299 #if defined(__LP64__)
300 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
301 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
302 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"
303 "--->Fault address falls at 00001234'5a534040 after any mapped regions\n";
304 #else
305 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
306 " 0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
307 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"
308 "--->Fault address falls at 0f534040 after any mapped regions\n";
309 #endif
310 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
311
312 ASSERT_STREQ("", amfd_data_.c_str());
313
314 // Verify that the log buf is empty, and no error messages.
315 ASSERT_STREQ("", getFakeLogBuf().c_str());
316 ASSERT_STREQ("", getFakeLogPrint().c_str());
317 }
318
TEST_F(TombstoneTest,dump_log_file_error)319 TEST_F(TombstoneTest, dump_log_file_error) {
320 log_.should_retrieve_logcat = true;
321 dump_log_file(&log_, 123, "/fake/filename", 10);
322
323 std::string tombstone_contents;
324 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
325 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
326 ASSERT_STREQ("", tombstone_contents.c_str());
327
328 ASSERT_STREQ("", getFakeLogBuf().c_str());
329 ASSERT_STREQ("6 DEBUG Unable to open /fake/filename: Permission denied\n\n",
330 getFakeLogPrint().c_str());
331
332 ASSERT_STREQ("", amfd_data_.c_str());
333 }
334
TEST_F(TombstoneTest,dump_header_info)335 TEST_F(TombstoneTest, dump_header_info) {
336 dump_header_info(&log_);
337
338 std::string expected = android::base::StringPrintf(
339 "Build fingerprint: '%s'\nRevision: '%s'\n",
340 android::base::GetProperty("ro.build.fingerprint", "unknown").c_str(),
341 android::base::GetProperty("ro.revision", "unknown").c_str());
342 expected += android::base::StringPrintf("ABI: '%s'\n", ABI_STRING);
343 ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
344 }
345
TEST_F(TombstoneTest,dump_thread_info_uid)346 TEST_F(TombstoneTest, dump_thread_info_uid) {
347 dump_thread_info(&log_, ThreadInfo{.uid = 1,
348 .pid = 2,
349 .tid = 3,
350 .thread_name = "some_thread",
351 .process_name = "some_process"});
352 std::string expected = "pid: 2, tid: 3, name: some_thread >>> some_process <<<\nuid: 1\n";
353 ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
354 }
355
TEST_F(TombstoneTest,dump_timestamp)356 TEST_F(TombstoneTest, dump_timestamp) {
357 setenv("TZ", "UTC", 1);
358 tzset();
359 dump_timestamp(&log_, 0);
360 ASSERT_STREQ("Timestamp: 1970-01-01 00:00:00+0000\n", amfd_data_.c_str());
361 }
362
363 class MemoryPattern : public unwindstack::Memory {
364 public:
365 MemoryPattern() = default;
366 virtual ~MemoryPattern() = default;
367
Read(uint64_t,void * dst,size_t size)368 size_t Read(uint64_t, void* dst, size_t size) override {
369 uint8_t* data = reinterpret_cast<uint8_t*>(dst);
370 for (size_t i = 0; i < size; i++) {
371 data[i] = (i % 0xff);
372 }
373 return size;
374 }
375 };
376
TEST_F(TombstoneTest,dump_stack_single_frame)377 TEST_F(TombstoneTest, dump_stack_single_frame) {
378 std::vector<unwindstack::FrameData> frames;
379 unwindstack::Maps maps;
380 MemoryPattern memory;
381
382 frames.push_back(
383 unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000});
384 dump_stack(&log_, frames, &maps, &memory);
385
386 std::string contents;
387 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
388 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents));
389
390 std::string expected =
391 #if defined(__LP64__)
392 " 0000000000001f80 0706050403020100\n"
393 " 0000000000001f88 0f0e0d0c0b0a0908\n"
394 " 0000000000001f90 1716151413121110\n"
395 " 0000000000001f98 1f1e1d1c1b1a1918\n"
396 " 0000000000001fa0 2726252423222120\n"
397 " 0000000000001fa8 2f2e2d2c2b2a2928\n"
398 " 0000000000001fb0 3736353433323130\n"
399 " 0000000000001fb8 3f3e3d3c3b3a3938\n"
400 " 0000000000001fc0 4746454443424140\n"
401 " 0000000000001fc8 4f4e4d4c4b4a4948\n"
402 " 0000000000001fd0 5756555453525150\n"
403 " 0000000000001fd8 5f5e5d5c5b5a5958\n"
404 " 0000000000001fe0 6766656463626160\n"
405 " 0000000000001fe8 6f6e6d6c6b6a6968\n"
406 " 0000000000001ff0 7776757473727170\n"
407 " 0000000000001ff8 7f7e7d7c7b7a7978\n"
408 " #00 0000000000002000 0706050403020100\n"
409 " 0000000000002008 0f0e0d0c0b0a0908\n"
410 " 0000000000002010 1716151413121110\n"
411 " 0000000000002018 1f1e1d1c1b1a1918\n"
412 " 0000000000002020 2726252423222120\n"
413 " 0000000000002028 2f2e2d2c2b2a2928\n"
414 " 0000000000002030 3736353433323130\n"
415 " 0000000000002038 3f3e3d3c3b3a3938\n"
416 " 0000000000002040 4746454443424140\n"
417 " 0000000000002048 4f4e4d4c4b4a4948\n"
418 " 0000000000002050 5756555453525150\n"
419 " 0000000000002058 5f5e5d5c5b5a5958\n"
420 " 0000000000002060 6766656463626160\n"
421 " 0000000000002068 6f6e6d6c6b6a6968\n"
422 " 0000000000002070 7776757473727170\n"
423 " 0000000000002078 7f7e7d7c7b7a7978\n";
424 #else
425 " 00001fc0 03020100\n"
426 " 00001fc4 07060504\n"
427 " 00001fc8 0b0a0908\n"
428 " 00001fcc 0f0e0d0c\n"
429 " 00001fd0 13121110\n"
430 " 00001fd4 17161514\n"
431 " 00001fd8 1b1a1918\n"
432 " 00001fdc 1f1e1d1c\n"
433 " 00001fe0 23222120\n"
434 " 00001fe4 27262524\n"
435 " 00001fe8 2b2a2928\n"
436 " 00001fec 2f2e2d2c\n"
437 " 00001ff0 33323130\n"
438 " 00001ff4 37363534\n"
439 " 00001ff8 3b3a3938\n"
440 " 00001ffc 3f3e3d3c\n"
441 " #00 00002000 03020100\n"
442 " 00002004 07060504\n"
443 " 00002008 0b0a0908\n"
444 " 0000200c 0f0e0d0c\n"
445 " 00002010 13121110\n"
446 " 00002014 17161514\n"
447 " 00002018 1b1a1918\n"
448 " 0000201c 1f1e1d1c\n"
449 " 00002020 23222120\n"
450 " 00002024 27262524\n"
451 " 00002028 2b2a2928\n"
452 " 0000202c 2f2e2d2c\n"
453 " 00002030 33323130\n"
454 " 00002034 37363534\n"
455 " 00002038 3b3a3938\n"
456 " 0000203c 3f3e3d3c\n";
457 #endif
458 EXPECT_EQ(expected, contents);
459 }
460
TEST_F(TombstoneTest,dump_stack_multiple_frames_same_sp)461 TEST_F(TombstoneTest, dump_stack_multiple_frames_same_sp) {
462 std::vector<unwindstack::FrameData> frames;
463 unwindstack::Maps maps;
464 MemoryPattern memory;
465
466 frames.push_back(
467 unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000});
468 frames.push_back(
469 unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2000});
470 dump_stack(&log_, frames, &maps, &memory);
471
472 std::string contents;
473 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
474 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents));
475
476 std::string expected =
477 #if defined(__LP64__)
478 " 0000000000001f80 0706050403020100\n"
479 " 0000000000001f88 0f0e0d0c0b0a0908\n"
480 " 0000000000001f90 1716151413121110\n"
481 " 0000000000001f98 1f1e1d1c1b1a1918\n"
482 " 0000000000001fa0 2726252423222120\n"
483 " 0000000000001fa8 2f2e2d2c2b2a2928\n"
484 " 0000000000001fb0 3736353433323130\n"
485 " 0000000000001fb8 3f3e3d3c3b3a3938\n"
486 " 0000000000001fc0 4746454443424140\n"
487 " 0000000000001fc8 4f4e4d4c4b4a4948\n"
488 " 0000000000001fd0 5756555453525150\n"
489 " 0000000000001fd8 5f5e5d5c5b5a5958\n"
490 " 0000000000001fe0 6766656463626160\n"
491 " 0000000000001fe8 6f6e6d6c6b6a6968\n"
492 " 0000000000001ff0 7776757473727170\n"
493 " 0000000000001ff8 7f7e7d7c7b7a7978\n"
494 " #00 0000000000002000 0706050403020100\n"
495 " ................ ................\n"
496 " #01 0000000000002000 0706050403020100\n"
497 " 0000000000002008 0f0e0d0c0b0a0908\n"
498 " 0000000000002010 1716151413121110\n"
499 " 0000000000002018 1f1e1d1c1b1a1918\n"
500 " 0000000000002020 2726252423222120\n"
501 " 0000000000002028 2f2e2d2c2b2a2928\n"
502 " 0000000000002030 3736353433323130\n"
503 " 0000000000002038 3f3e3d3c3b3a3938\n"
504 " 0000000000002040 4746454443424140\n"
505 " 0000000000002048 4f4e4d4c4b4a4948\n"
506 " 0000000000002050 5756555453525150\n"
507 " 0000000000002058 5f5e5d5c5b5a5958\n"
508 " 0000000000002060 6766656463626160\n"
509 " 0000000000002068 6f6e6d6c6b6a6968\n"
510 " 0000000000002070 7776757473727170\n"
511 " 0000000000002078 7f7e7d7c7b7a7978\n";
512 #else
513 " 00001fc0 03020100\n"
514 " 00001fc4 07060504\n"
515 " 00001fc8 0b0a0908\n"
516 " 00001fcc 0f0e0d0c\n"
517 " 00001fd0 13121110\n"
518 " 00001fd4 17161514\n"
519 " 00001fd8 1b1a1918\n"
520 " 00001fdc 1f1e1d1c\n"
521 " 00001fe0 23222120\n"
522 " 00001fe4 27262524\n"
523 " 00001fe8 2b2a2928\n"
524 " 00001fec 2f2e2d2c\n"
525 " 00001ff0 33323130\n"
526 " 00001ff4 37363534\n"
527 " 00001ff8 3b3a3938\n"
528 " 00001ffc 3f3e3d3c\n"
529 " #00 00002000 03020100\n"
530 " ........ ........\n"
531 " #01 00002000 03020100\n"
532 " 00002004 07060504\n"
533 " 00002008 0b0a0908\n"
534 " 0000200c 0f0e0d0c\n"
535 " 00002010 13121110\n"
536 " 00002014 17161514\n"
537 " 00002018 1b1a1918\n"
538 " 0000201c 1f1e1d1c\n"
539 " 00002020 23222120\n"
540 " 00002024 27262524\n"
541 " 00002028 2b2a2928\n"
542 " 0000202c 2f2e2d2c\n"
543 " 00002030 33323130\n"
544 " 00002034 37363534\n"
545 " 00002038 3b3a3938\n"
546 " 0000203c 3f3e3d3c\n";
547 #endif
548 EXPECT_EQ(expected, contents);
549 }
550
TEST_F(TombstoneTest,dump_stack_multiple_frames)551 TEST_F(TombstoneTest, dump_stack_multiple_frames) {
552 std::vector<unwindstack::FrameData> frames;
553 unwindstack::Maps maps;
554 MemoryPattern memory;
555
556 frames.push_back(
557 unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000});
558 frames.push_back(
559 unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2010});
560 frames.push_back(
561 unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2100});
562 dump_stack(&log_, frames, &maps, &memory);
563
564 std::string contents;
565 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
566 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents));
567
568 std::string expected =
569 #if defined(__LP64__)
570 " 0000000000001f80 0706050403020100\n"
571 " 0000000000001f88 0f0e0d0c0b0a0908\n"
572 " 0000000000001f90 1716151413121110\n"
573 " 0000000000001f98 1f1e1d1c1b1a1918\n"
574 " 0000000000001fa0 2726252423222120\n"
575 " 0000000000001fa8 2f2e2d2c2b2a2928\n"
576 " 0000000000001fb0 3736353433323130\n"
577 " 0000000000001fb8 3f3e3d3c3b3a3938\n"
578 " 0000000000001fc0 4746454443424140\n"
579 " 0000000000001fc8 4f4e4d4c4b4a4948\n"
580 " 0000000000001fd0 5756555453525150\n"
581 " 0000000000001fd8 5f5e5d5c5b5a5958\n"
582 " 0000000000001fe0 6766656463626160\n"
583 " 0000000000001fe8 6f6e6d6c6b6a6968\n"
584 " 0000000000001ff0 7776757473727170\n"
585 " 0000000000001ff8 7f7e7d7c7b7a7978\n"
586 " #00 0000000000002000 0706050403020100\n"
587 " 0000000000002008 0f0e0d0c0b0a0908\n"
588 " #01 0000000000002010 0706050403020100\n"
589 " 0000000000002018 0f0e0d0c0b0a0908\n"
590 " 0000000000002020 1716151413121110\n"
591 " 0000000000002028 1f1e1d1c1b1a1918\n"
592 " 0000000000002030 2726252423222120\n"
593 " 0000000000002038 2f2e2d2c2b2a2928\n"
594 " 0000000000002040 3736353433323130\n"
595 " 0000000000002048 3f3e3d3c3b3a3938\n"
596 " 0000000000002050 4746454443424140\n"
597 " 0000000000002058 4f4e4d4c4b4a4948\n"
598 " 0000000000002060 5756555453525150\n"
599 " 0000000000002068 5f5e5d5c5b5a5958\n"
600 " 0000000000002070 6766656463626160\n"
601 " 0000000000002078 6f6e6d6c6b6a6968\n"
602 " 0000000000002080 7776757473727170\n"
603 " 0000000000002088 7f7e7d7c7b7a7978\n"
604 " ................ ................\n"
605 " #02 0000000000002100 0706050403020100\n"
606 " 0000000000002108 0f0e0d0c0b0a0908\n"
607 " 0000000000002110 1716151413121110\n"
608 " 0000000000002118 1f1e1d1c1b1a1918\n"
609 " 0000000000002120 2726252423222120\n"
610 " 0000000000002128 2f2e2d2c2b2a2928\n"
611 " 0000000000002130 3736353433323130\n"
612 " 0000000000002138 3f3e3d3c3b3a3938\n"
613 " 0000000000002140 4746454443424140\n"
614 " 0000000000002148 4f4e4d4c4b4a4948\n"
615 " 0000000000002150 5756555453525150\n"
616 " 0000000000002158 5f5e5d5c5b5a5958\n"
617 " 0000000000002160 6766656463626160\n"
618 " 0000000000002168 6f6e6d6c6b6a6968\n"
619 " 0000000000002170 7776757473727170\n"
620 " 0000000000002178 7f7e7d7c7b7a7978\n";
621 #else
622 " 00001fc0 03020100\n"
623 " 00001fc4 07060504\n"
624 " 00001fc8 0b0a0908\n"
625 " 00001fcc 0f0e0d0c\n"
626 " 00001fd0 13121110\n"
627 " 00001fd4 17161514\n"
628 " 00001fd8 1b1a1918\n"
629 " 00001fdc 1f1e1d1c\n"
630 " 00001fe0 23222120\n"
631 " 00001fe4 27262524\n"
632 " 00001fe8 2b2a2928\n"
633 " 00001fec 2f2e2d2c\n"
634 " 00001ff0 33323130\n"
635 " 00001ff4 37363534\n"
636 " 00001ff8 3b3a3938\n"
637 " 00001ffc 3f3e3d3c\n"
638 " #00 00002000 03020100\n"
639 " 00002004 07060504\n"
640 " 00002008 0b0a0908\n"
641 " 0000200c 0f0e0d0c\n"
642 " #01 00002010 03020100\n"
643 " 00002014 07060504\n"
644 " 00002018 0b0a0908\n"
645 " 0000201c 0f0e0d0c\n"
646 " 00002020 13121110\n"
647 " 00002024 17161514\n"
648 " 00002028 1b1a1918\n"
649 " 0000202c 1f1e1d1c\n"
650 " 00002030 23222120\n"
651 " 00002034 27262524\n"
652 " 00002038 2b2a2928\n"
653 " 0000203c 2f2e2d2c\n"
654 " 00002040 33323130\n"
655 " 00002044 37363534\n"
656 " 00002048 3b3a3938\n"
657 " 0000204c 3f3e3d3c\n"
658 " ........ ........\n"
659 " #02 00002100 03020100\n"
660 " 00002104 07060504\n"
661 " 00002108 0b0a0908\n"
662 " 0000210c 0f0e0d0c\n"
663 " 00002110 13121110\n"
664 " 00002114 17161514\n"
665 " 00002118 1b1a1918\n"
666 " 0000211c 1f1e1d1c\n"
667 " 00002120 23222120\n"
668 " 00002124 27262524\n"
669 " 00002128 2b2a2928\n"
670 " 0000212c 2f2e2d2c\n"
671 " 00002130 33323130\n"
672 " 00002134 37363534\n"
673 " 00002138 3b3a3938\n"
674 " 0000213c 3f3e3d3c\n";
675 #endif
676 EXPECT_EQ(expected, contents);
677 }
678
TEST_F(TombstoneTest,dump_stack_multiple_frames_disjoint_frames)679 TEST_F(TombstoneTest, dump_stack_multiple_frames_disjoint_frames) {
680 std::vector<unwindstack::FrameData> frames;
681 unwindstack::Maps maps;
682 MemoryPattern memory;
683
684 frames.push_back(
685 unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000});
686 frames.push_back(
687 unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2010});
688 frames.push_back(
689 unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x1000});
690 frames.push_back(
691 unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x1030});
692 dump_stack(&log_, frames, &maps, &memory);
693
694 std::string contents;
695 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
696 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents));
697
698 std::string expected =
699 #if defined(__LP64__)
700 " 0000000000001f80 0706050403020100\n"
701 " 0000000000001f88 0f0e0d0c0b0a0908\n"
702 " 0000000000001f90 1716151413121110\n"
703 " 0000000000001f98 1f1e1d1c1b1a1918\n"
704 " 0000000000001fa0 2726252423222120\n"
705 " 0000000000001fa8 2f2e2d2c2b2a2928\n"
706 " 0000000000001fb0 3736353433323130\n"
707 " 0000000000001fb8 3f3e3d3c3b3a3938\n"
708 " 0000000000001fc0 4746454443424140\n"
709 " 0000000000001fc8 4f4e4d4c4b4a4948\n"
710 " 0000000000001fd0 5756555453525150\n"
711 " 0000000000001fd8 5f5e5d5c5b5a5958\n"
712 " 0000000000001fe0 6766656463626160\n"
713 " 0000000000001fe8 6f6e6d6c6b6a6968\n"
714 " 0000000000001ff0 7776757473727170\n"
715 " 0000000000001ff8 7f7e7d7c7b7a7978\n"
716 " #00 0000000000002000 0706050403020100\n"
717 " 0000000000002008 0f0e0d0c0b0a0908\n"
718 " #01 0000000000002010 0706050403020100\n"
719 " 0000000000002018 0f0e0d0c0b0a0908\n"
720 " 0000000000002020 1716151413121110\n"
721 " 0000000000002028 1f1e1d1c1b1a1918\n"
722 " 0000000000002030 2726252423222120\n"
723 " 0000000000002038 2f2e2d2c2b2a2928\n"
724 " 0000000000002040 3736353433323130\n"
725 " 0000000000002048 3f3e3d3c3b3a3938\n"
726 " 0000000000002050 4746454443424140\n"
727 " 0000000000002058 4f4e4d4c4b4a4948\n"
728 " 0000000000002060 5756555453525150\n"
729 " 0000000000002068 5f5e5d5c5b5a5958\n"
730 " 0000000000002070 6766656463626160\n"
731 " 0000000000002078 6f6e6d6c6b6a6968\n"
732 " 0000000000002080 7776757473727170\n"
733 " 0000000000002088 7f7e7d7c7b7a7978\n"
734 " ................ ................\n"
735 " #02 0000000000001000 0706050403020100\n"
736 " 0000000000001008 0f0e0d0c0b0a0908\n"
737 " 0000000000001010 1716151413121110\n"
738 " 0000000000001018 1f1e1d1c1b1a1918\n"
739 " 0000000000001020 2726252423222120\n"
740 " 0000000000001028 2f2e2d2c2b2a2928\n"
741 " #03 0000000000001030 0706050403020100\n"
742 " 0000000000001038 0f0e0d0c0b0a0908\n"
743 " 0000000000001040 1716151413121110\n"
744 " 0000000000001048 1f1e1d1c1b1a1918\n"
745 " 0000000000001050 2726252423222120\n"
746 " 0000000000001058 2f2e2d2c2b2a2928\n"
747 " 0000000000001060 3736353433323130\n"
748 " 0000000000001068 3f3e3d3c3b3a3938\n"
749 " 0000000000001070 4746454443424140\n"
750 " 0000000000001078 4f4e4d4c4b4a4948\n"
751 " 0000000000001080 5756555453525150\n"
752 " 0000000000001088 5f5e5d5c5b5a5958\n"
753 " 0000000000001090 6766656463626160\n"
754 " 0000000000001098 6f6e6d6c6b6a6968\n"
755 " 00000000000010a0 7776757473727170\n"
756 " 00000000000010a8 7f7e7d7c7b7a7978\n";
757 #else
758 " 00001fc0 03020100\n"
759 " 00001fc4 07060504\n"
760 " 00001fc8 0b0a0908\n"
761 " 00001fcc 0f0e0d0c\n"
762 " 00001fd0 13121110\n"
763 " 00001fd4 17161514\n"
764 " 00001fd8 1b1a1918\n"
765 " 00001fdc 1f1e1d1c\n"
766 " 00001fe0 23222120\n"
767 " 00001fe4 27262524\n"
768 " 00001fe8 2b2a2928\n"
769 " 00001fec 2f2e2d2c\n"
770 " 00001ff0 33323130\n"
771 " 00001ff4 37363534\n"
772 " 00001ff8 3b3a3938\n"
773 " 00001ffc 3f3e3d3c\n"
774 " #00 00002000 03020100\n"
775 " 00002004 07060504\n"
776 " 00002008 0b0a0908\n"
777 " 0000200c 0f0e0d0c\n"
778 " #01 00002010 03020100\n"
779 " 00002014 07060504\n"
780 " 00002018 0b0a0908\n"
781 " 0000201c 0f0e0d0c\n"
782 " 00002020 13121110\n"
783 " 00002024 17161514\n"
784 " 00002028 1b1a1918\n"
785 " 0000202c 1f1e1d1c\n"
786 " 00002030 23222120\n"
787 " 00002034 27262524\n"
788 " 00002038 2b2a2928\n"
789 " 0000203c 2f2e2d2c\n"
790 " 00002040 33323130\n"
791 " 00002044 37363534\n"
792 " 00002048 3b3a3938\n"
793 " 0000204c 3f3e3d3c\n"
794 " ........ ........\n"
795 " #02 00001000 03020100\n"
796 " 00001004 07060504\n"
797 " 00001008 0b0a0908\n"
798 " 0000100c 0f0e0d0c\n"
799 " 00001010 13121110\n"
800 " 00001014 17161514\n"
801 " 00001018 1b1a1918\n"
802 " 0000101c 1f1e1d1c\n"
803 " 00001020 23222120\n"
804 " 00001024 27262524\n"
805 " 00001028 2b2a2928\n"
806 " 0000102c 2f2e2d2c\n"
807 " #03 00001030 03020100\n"
808 " 00001034 07060504\n"
809 " 00001038 0b0a0908\n"
810 " 0000103c 0f0e0d0c\n"
811 " 00001040 13121110\n"
812 " 00001044 17161514\n"
813 " 00001048 1b1a1918\n"
814 " 0000104c 1f1e1d1c\n"
815 " 00001050 23222120\n"
816 " 00001054 27262524\n"
817 " 00001058 2b2a2928\n"
818 " 0000105c 2f2e2d2c\n"
819 " 00001060 33323130\n"
820 " 00001064 37363534\n"
821 " 00001068 3b3a3938\n"
822 " 0000106c 3f3e3d3c\n";
823 #endif
824 EXPECT_EQ(expected, contents);
825 }
826