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 <android-base/file.h>
23 #include <gtest/gtest.h>
24 #include <unwindstack/Memory.h>
25 
26 #include "libdebuggerd/utility.h"
27 
28 #include "log_fake.h"
29 
30 const char g_expected_full_dump[] =
31 "\nmemory near r1:\n"
32 #if defined(__LP64__)
33 "    0000000012345650 0706050403020100 0f0e0d0c0b0a0908  ................\n"
34 "    0000000012345660 1716151413121110 1f1e1d1c1b1a1918  ................\n"
35 "    0000000012345670 2726252423222120 2f2e2d2c2b2a2928   !\"#$%&'()*+,-./\n"
36 "    0000000012345680 3736353433323130 3f3e3d3c3b3a3938  0123456789:;<=>?\n"
37 "    0000000012345690 4746454443424140 4f4e4d4c4b4a4948  @ABCDEFGHIJKLMNO\n"
38 "    00000000123456a0 5756555453525150 5f5e5d5c5b5a5958  PQRSTUVWXYZ[\\]^_\n"
39 "    00000000123456b0 6766656463626160 6f6e6d6c6b6a6968  `abcdefghijklmno\n"
40 "    00000000123456c0 7776757473727170 7f7e7d7c7b7a7978  pqrstuvwxyz{|}~.\n"
41 "    00000000123456d0 8786858483828180 8f8e8d8c8b8a8988  ................\n"
42 "    00000000123456e0 9796959493929190 9f9e9d9c9b9a9998  ................\n"
43 "    00000000123456f0 a7a6a5a4a3a2a1a0 afaeadacabaaa9a8  ................\n"
44 "    0000000012345700 b7b6b5b4b3b2b1b0 bfbebdbcbbbab9b8  ................\n"
45 "    0000000012345710 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8  ................\n"
46 "    0000000012345720 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8  ................\n"
47 "    0000000012345730 e7e6e5e4e3e2e1e0 efeeedecebeae9e8  ................\n"
48 "    0000000012345740 f7f6f5f4f3f2f1f0 fffefdfcfbfaf9f8  ................\n";
49 #else
50 "    12345650 03020100 07060504 0b0a0908 0f0e0d0c  ................\n"
51 "    12345660 13121110 17161514 1b1a1918 1f1e1d1c  ................\n"
52 "    12345670 23222120 27262524 2b2a2928 2f2e2d2c   !\"#$%&'()*+,-./\n"
53 "    12345680 33323130 37363534 3b3a3938 3f3e3d3c  0123456789:;<=>?\n"
54 "    12345690 43424140 47464544 4b4a4948 4f4e4d4c  @ABCDEFGHIJKLMNO\n"
55 "    123456a0 53525150 57565554 5b5a5958 5f5e5d5c  PQRSTUVWXYZ[\\]^_\n"
56 "    123456b0 63626160 67666564 6b6a6968 6f6e6d6c  `abcdefghijklmno\n"
57 "    123456c0 73727170 77767574 7b7a7978 7f7e7d7c  pqrstuvwxyz{|}~.\n"
58 "    123456d0 83828180 87868584 8b8a8988 8f8e8d8c  ................\n"
59 "    123456e0 93929190 97969594 9b9a9998 9f9e9d9c  ................\n"
60 "    123456f0 a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac  ................\n"
61 "    12345700 b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc  ................\n"
62 "    12345710 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc  ................\n"
63 "    12345720 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc  ................\n"
64 "    12345730 e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec  ................\n"
65 "    12345740 f3f2f1f0 f7f6f5f4 fbfaf9f8 fffefdfc  ................\n";
66 #endif
67 
68 const char g_expected_partial_dump[] = \
69 "\nmemory near pc:\n"
70 #if defined(__LP64__)
71 "    00000000123455e0 0706050403020100 0f0e0d0c0b0a0908  ................\n"
72 "    00000000123455f0 1716151413121110 1f1e1d1c1b1a1918  ................\n"
73 "    0000000012345600 2726252423222120 2f2e2d2c2b2a2928   !\"#$%&'()*+,-./\n"
74 "    0000000012345610 3736353433323130 3f3e3d3c3b3a3938  0123456789:;<=>?\n"
75 "    0000000012345620 4746454443424140 4f4e4d4c4b4a4948  @ABCDEFGHIJKLMNO\n"
76 "    0000000012345630 5756555453525150 5f5e5d5c5b5a5958  PQRSTUVWXYZ[\\]^_\n"
77 "    0000000012345640 6766656463626160 ----------------  `abcdefg........\n"
78 "    0000000012345650 ---------------- ----------------  ................\n"
79 "    0000000012345660 ---------------- ----------------  ................\n"
80 "    0000000012345670 ---------------- ----------------  ................\n"
81 "    0000000012345680 ---------------- ----------------  ................\n"
82 "    0000000012345690 ---------------- ----------------  ................\n"
83 "    00000000123456a0 ---------------- ----------------  ................\n"
84 "    00000000123456b0 ---------------- ----------------  ................\n"
85 "    00000000123456c0 ---------------- ----------------  ................\n"
86 "    00000000123456d0 ---------------- ----------------  ................\n";
87 #else
88 "    123455e0 03020100 07060504 0b0a0908 0f0e0d0c  ................\n"
89 "    123455f0 13121110 17161514 1b1a1918 1f1e1d1c  ................\n"
90 "    12345600 23222120 27262524 2b2a2928 2f2e2d2c   !\"#$%&'()*+,-./\n"
91 "    12345610 33323130 37363534 3b3a3938 3f3e3d3c  0123456789:;<=>?\n"
92 "    12345620 43424140 47464544 4b4a4948 4f4e4d4c  @ABCDEFGHIJKLMNO\n"
93 "    12345630 53525150 57565554 5b5a5958 5f5e5d5c  PQRSTUVWXYZ[\\]^_\n"
94 "    12345640 63626160 67666564 -------- --------  `abcdefg........\n"
95 "    12345650 -------- -------- -------- --------  ................\n"
96 "    12345660 -------- -------- -------- --------  ................\n"
97 "    12345670 -------- -------- -------- --------  ................\n"
98 "    12345680 -------- -------- -------- --------  ................\n"
99 "    12345690 -------- -------- -------- --------  ................\n"
100 "    123456a0 -------- -------- -------- --------  ................\n"
101 "    123456b0 -------- -------- -------- --------  ................\n"
102 "    123456c0 -------- -------- -------- --------  ................\n"
103 "    123456d0 -------- -------- -------- --------  ................\n";
104 #endif
105 
106 class MemoryMock : public unwindstack::Memory {
107  public:
108   virtual ~MemoryMock() = default;
109 
Read(uint64_t addr,void * buffer,size_t bytes)110   virtual size_t Read(uint64_t addr, void* buffer, size_t bytes) override {
111     size_t offset = 0;
112     if (last_read_addr_ > 0) {
113       offset = addr - last_read_addr_;
114     }
115     size_t bytes_available = 0;
116     if (offset < buffer_.size()) {
117       bytes_available = buffer_.size() - offset;
118     }
119 
120     if (partial_read_) {
121       bytes = std::min(bytes, bytes_partial_read_);
122       bytes_partial_read_ -= bytes;
123       partial_read_ = bytes_partial_read_;
124     } else if (bytes > bytes_available) {
125       bytes = bytes_available;
126     }
127 
128     if (bytes > 0) {
129       memcpy(buffer, buffer_.data() + offset, bytes);
130     }
131 
132     last_read_addr_ = addr;
133     return bytes;
134   }
135 
SetReadData(uint8_t * buffer,size_t bytes)136   void SetReadData(uint8_t* buffer, size_t bytes) {
137     buffer_.resize(bytes);
138     memcpy(buffer_.data(), buffer, bytes);
139     bytes_partial_read_ = 0;
140     last_read_addr_ = 0;
141   }
142 
SetPartialReadAmount(size_t bytes)143   void SetPartialReadAmount(size_t bytes) {
144     if (bytes > buffer_.size()) {
145       abort();
146     }
147     partial_read_ = true;
148     bytes_partial_read_ = bytes;
149   }
150 
151  private:
152   std::vector<uint8_t> buffer_;
153   bool partial_read_ = false;
154   size_t bytes_partial_read_ = 0;
155   uintptr_t last_read_addr_ = 0;
156 };
157 
158 class DumpMemoryTest : public ::testing::Test {
159  protected:
SetUp()160   virtual void SetUp() {
161     memory_mock_ = std::make_unique<MemoryMock>();
162 
163     char tmp_file[256];
164     const char data_template[] = "/data/local/tmp/debuggerd_memory_testXXXXXX";
165     memcpy(tmp_file, data_template, sizeof(data_template));
166     int tombstone_fd = mkstemp(tmp_file);
167     if (tombstone_fd == -1) {
168       const char tmp_template[] = "/tmp/debuggerd_memory_testXXXXXX";
169       memcpy(tmp_file, tmp_template, sizeof(tmp_template));
170       tombstone_fd = mkstemp(tmp_file);
171       if (tombstone_fd == -1) {
172         abort();
173       }
174     }
175     if (unlink(tmp_file) == -1) {
176       abort();
177     }
178 
179     log_.tfd = tombstone_fd;
180     log_.amfd_data = nullptr;
181     log_.crashed_tid = 12;
182     log_.current_tid = 12;
183     log_.should_retrieve_logcat = false;
184 
185     resetLogs();
186   }
187 
TearDown()188   virtual void TearDown() {
189     if (log_.tfd >= 0) {
190       close(log_.tfd);
191     }
192     memory_mock_.reset();
193   }
194 
195   std::unique_ptr<MemoryMock> memory_mock_;
196 
197   log_t log_;
198 };
199 
TEST_F(DumpMemoryTest,aligned_addr)200 TEST_F(DumpMemoryTest, aligned_addr) {
201   uint8_t buffer[256];
202   for (size_t i = 0; i < sizeof(buffer); i++) {
203     buffer[i] = i;
204   }
205   memory_mock_->SetReadData(buffer, sizeof(buffer));
206 
207   dump_memory(&log_, memory_mock_.get(), 0x12345678, "memory near r1");
208 
209   std::string tombstone_contents;
210   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
211   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
212   ASSERT_STREQ(g_expected_full_dump, tombstone_contents.c_str());
213 
214   // Verify that the log buf is empty, and no error messages.
215   ASSERT_STREQ("", getFakeLogBuf().c_str());
216   ASSERT_STREQ("", getFakeLogPrint().c_str());
217 }
218 
TEST_F(DumpMemoryTest,partial_read)219 TEST_F(DumpMemoryTest, partial_read) {
220   uint8_t buffer[256];
221   for (size_t i = 0; i < sizeof(buffer); i++) {
222     buffer[i] = i;
223   }
224   memory_mock_->SetReadData(buffer, sizeof(buffer));
225   memory_mock_->SetPartialReadAmount(96);
226 
227   dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near r1");
228 
229   std::string tombstone_contents;
230   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
231   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
232   ASSERT_STREQ(g_expected_full_dump, tombstone_contents.c_str());
233 
234   // Verify that the log buf is empty, and no error messages.
235   ASSERT_STREQ("", getFakeLogBuf().c_str());
236   ASSERT_STREQ("", getFakeLogPrint().c_str());
237 }
238 
TEST_F(DumpMemoryTest,unaligned_addr)239 TEST_F(DumpMemoryTest, unaligned_addr) {
240   uint8_t buffer[256];
241   for (size_t i = 0; i < sizeof(buffer); i++) {
242     buffer[i] = i;
243   }
244   memory_mock_->SetReadData(buffer, sizeof(buffer));
245 
246   dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near r1");
247 
248   std::string tombstone_contents;
249   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
250   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
251   ASSERT_STREQ(g_expected_full_dump, tombstone_contents.c_str());
252 
253   // Verify that the log buf is empty, and no error messages.
254   ASSERT_STREQ("", getFakeLogBuf().c_str());
255   ASSERT_STREQ("", getFakeLogPrint().c_str());
256 }
257 
TEST_F(DumpMemoryTest,memory_unreadable)258 TEST_F(DumpMemoryTest, memory_unreadable) {
259   dump_memory(&log_, memory_mock_.get(), 0xa2345678, "memory near pc");
260 
261   std::string tombstone_contents;
262   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
263   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
264   ASSERT_STREQ("", tombstone_contents.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(DumpMemoryTest,memory_partially_unreadable)271 TEST_F(DumpMemoryTest, memory_partially_unreadable) {
272   uint8_t buffer[104];
273   for (size_t i = 0; i < sizeof(buffer); i++) {
274     buffer[i] = i;
275   }
276   memory_mock_->SetReadData(buffer, sizeof(buffer));
277 
278   dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");
279 
280   std::string tombstone_contents;
281   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
282   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
283   ASSERT_STREQ(g_expected_partial_dump, tombstone_contents.c_str());
284 
285   // Verify that the log buf is empty, and no error messages.
286   ASSERT_STREQ("", getFakeLogBuf().c_str());
287   ASSERT_STREQ("", getFakeLogPrint().c_str());
288 }
289 
TEST_F(DumpMemoryTest,memory_partially_unreadable_unaligned_return)290 TEST_F(DumpMemoryTest, memory_partially_unreadable_unaligned_return) {
291   uint8_t buffer[104];
292   for (size_t i = 0; i < sizeof(buffer); i++) {
293     buffer[i] = i;
294   }
295   memory_mock_->SetReadData(buffer, sizeof(buffer));
296   memory_mock_->SetPartialReadAmount(102);
297 
298   dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");
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   ASSERT_STREQ(g_expected_partial_dump, tombstone_contents.c_str());
304 
305 #if defined(__LP64__)
306   ASSERT_STREQ("6 DEBUG Bytes read 102, is not a multiple of 8\n", getFakeLogPrint().c_str());
307 #else
308   ASSERT_STREQ("6 DEBUG Bytes read 102, is not a multiple of 4\n", getFakeLogPrint().c_str());
309 #endif
310 
311   // Verify that the log buf is empty, and no error messages.
312   ASSERT_STREQ("", getFakeLogBuf().c_str());
313 }
314 
TEST_F(DumpMemoryTest,memory_partially_unreadable_two_unaligned_reads)315 TEST_F(DumpMemoryTest, memory_partially_unreadable_two_unaligned_reads) {
316   uint8_t buffer[106];
317   for (size_t i = 0; i < sizeof(buffer); i++) {
318     buffer[i] = i;
319   }
320   memory_mock_->SetReadData(buffer, sizeof(buffer));
321   memory_mock_->SetPartialReadAmount(45);
322 
323   dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");
324 
325   std::string tombstone_contents;
326   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
327   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
328   ASSERT_STREQ(g_expected_partial_dump, tombstone_contents.c_str());
329 
330 #if defined(__LP64__)
331   ASSERT_STREQ("6 DEBUG Bytes read 45, is not a multiple of 8\n"
332                "6 DEBUG Bytes after second read 106, is not a multiple of 8\n",
333                getFakeLogPrint().c_str());
334 #else
335   ASSERT_STREQ("6 DEBUG Bytes read 45, is not a multiple of 4\n"
336                "6 DEBUG Bytes after second read 106, is not a multiple of 4\n",
337                getFakeLogPrint().c_str());
338 #endif
339 
340   // Verify that the log buf is empty, and no error messages.
341   ASSERT_STREQ("", getFakeLogBuf().c_str());
342 }
343 
TEST_F(DumpMemoryTest,address_low_fence)344 TEST_F(DumpMemoryTest, address_low_fence) {
345   uint8_t buffer[256];
346   memset(buffer, 0, sizeof(buffer));
347   memory_mock_->SetReadData(buffer, sizeof(buffer));
348 
349   dump_memory(&log_, memory_mock_.get(), 0x1000, "memory near r1");
350 
351   std::string tombstone_contents;
352   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
353   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
354   const char* expected_dump = \
355 "\nmemory near r1:\n"
356 #if defined(__LP64__)
357 "    0000000000001000 0000000000000000 0000000000000000  ................\n"
358 "    0000000000001010 0000000000000000 0000000000000000  ................\n"
359 "    0000000000001020 0000000000000000 0000000000000000  ................\n"
360 "    0000000000001030 0000000000000000 0000000000000000  ................\n"
361 "    0000000000001040 0000000000000000 0000000000000000  ................\n"
362 "    0000000000001050 0000000000000000 0000000000000000  ................\n"
363 "    0000000000001060 0000000000000000 0000000000000000  ................\n"
364 "    0000000000001070 0000000000000000 0000000000000000  ................\n"
365 "    0000000000001080 0000000000000000 0000000000000000  ................\n"
366 "    0000000000001090 0000000000000000 0000000000000000  ................\n"
367 "    00000000000010a0 0000000000000000 0000000000000000  ................\n"
368 "    00000000000010b0 0000000000000000 0000000000000000  ................\n"
369 "    00000000000010c0 0000000000000000 0000000000000000  ................\n"
370 "    00000000000010d0 0000000000000000 0000000000000000  ................\n"
371 "    00000000000010e0 0000000000000000 0000000000000000  ................\n"
372 "    00000000000010f0 0000000000000000 0000000000000000  ................\n";
373 #else
374 "    00001000 00000000 00000000 00000000 00000000  ................\n"
375 "    00001010 00000000 00000000 00000000 00000000  ................\n"
376 "    00001020 00000000 00000000 00000000 00000000  ................\n"
377 "    00001030 00000000 00000000 00000000 00000000  ................\n"
378 "    00001040 00000000 00000000 00000000 00000000  ................\n"
379 "    00001050 00000000 00000000 00000000 00000000  ................\n"
380 "    00001060 00000000 00000000 00000000 00000000  ................\n"
381 "    00001070 00000000 00000000 00000000 00000000  ................\n"
382 "    00001080 00000000 00000000 00000000 00000000  ................\n"
383 "    00001090 00000000 00000000 00000000 00000000  ................\n"
384 "    000010a0 00000000 00000000 00000000 00000000  ................\n"
385 "    000010b0 00000000 00000000 00000000 00000000  ................\n"
386 "    000010c0 00000000 00000000 00000000 00000000  ................\n"
387 "    000010d0 00000000 00000000 00000000 00000000  ................\n"
388 "    000010e0 00000000 00000000 00000000 00000000  ................\n"
389 "    000010f0 00000000 00000000 00000000 00000000  ................\n";
390 #endif
391   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
392 
393   // Verify that the log buf is empty, and no error messages.
394   ASSERT_STREQ("", getFakeLogBuf().c_str());
395   ASSERT_STREQ("", getFakeLogPrint().c_str());
396 }
397 
TEST_F(DumpMemoryTest,memory_address_too_high)398 TEST_F(DumpMemoryTest, memory_address_too_high) {
399   uint8_t buffer[256];
400   memset(buffer, 0, sizeof(buffer));
401   memory_mock_->SetReadData(buffer, sizeof(buffer));
402 
403 #if defined(__LP64__)
404   dump_memory(&log_, memory_mock_.get(), -32, "memory near r1");
405   dump_memory(&log_, memory_mock_.get(), -208, "memory near r1");
406 #else
407   dump_memory(&log_, memory_mock_.get(), 0x100000000 - 32, "memory near r1");
408   dump_memory(&log_, memory_mock_.get(), 0x100000000 - 208, "memory near r1");
409 #endif
410 
411   std::string tombstone_contents;
412   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
413   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
414   ASSERT_STREQ("", tombstone_contents.c_str());
415 
416   // Verify that the log buf is empty, and no error messages.
417   ASSERT_STREQ("", getFakeLogBuf().c_str());
418   ASSERT_STREQ("", getFakeLogPrint().c_str());
419 }
420 
TEST_F(DumpMemoryTest,memory_address_nearly_too_high)421 TEST_F(DumpMemoryTest, memory_address_nearly_too_high) {
422   uint8_t buffer[256];
423   for (size_t i = 0; i < sizeof(buffer); i++) {
424     buffer[i] = i;
425   }
426   memory_mock_->SetReadData(buffer, sizeof(buffer));
427 
428 #if defined(__LP64__)
429   dump_memory(&log_, memory_mock_.get(), -224, "memory near r4");
430 #else
431   dump_memory(&log_, memory_mock_.get(), 0x100000000 - 224, "memory near r4");
432 #endif
433 
434   std::string tombstone_contents;
435   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
436   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
437   const char* expected_dump = \
438 "\nmemory near r4:\n"
439 #if defined(__aarch64__)
440 "    00ffffffffffff00 0706050403020100 0f0e0d0c0b0a0908  ................\n"
441 "    00ffffffffffff10 1716151413121110 1f1e1d1c1b1a1918  ................\n"
442 "    00ffffffffffff20 2726252423222120 2f2e2d2c2b2a2928   !\"#$%&'()*+,-./\n"
443 "    00ffffffffffff30 3736353433323130 3f3e3d3c3b3a3938  0123456789:;<=>?\n"
444 "    00ffffffffffff40 4746454443424140 4f4e4d4c4b4a4948  @ABCDEFGHIJKLMNO\n"
445 "    00ffffffffffff50 5756555453525150 5f5e5d5c5b5a5958  PQRSTUVWXYZ[\\]^_\n"
446 "    00ffffffffffff60 6766656463626160 6f6e6d6c6b6a6968  `abcdefghijklmno\n"
447 "    00ffffffffffff70 7776757473727170 7f7e7d7c7b7a7978  pqrstuvwxyz{|}~.\n"
448 "    00ffffffffffff80 8786858483828180 8f8e8d8c8b8a8988  ................\n"
449 "    00ffffffffffff90 9796959493929190 9f9e9d9c9b9a9998  ................\n"
450 "    00ffffffffffffa0 a7a6a5a4a3a2a1a0 afaeadacabaaa9a8  ................\n"
451 "    00ffffffffffffb0 b7b6b5b4b3b2b1b0 bfbebdbcbbbab9b8  ................\n"
452 "    00ffffffffffffc0 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8  ................\n"
453 "    00ffffffffffffd0 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8  ................\n"
454 "    00ffffffffffffe0 e7e6e5e4e3e2e1e0 efeeedecebeae9e8  ................\n"
455 "    00fffffffffffff0 f7f6f5f4f3f2f1f0 fffefdfcfbfaf9f8  ................\n";
456 #elif defined(__LP64__)
457 "    ffffffffffffff00 0706050403020100 0f0e0d0c0b0a0908  ................\n"
458 "    ffffffffffffff10 1716151413121110 1f1e1d1c1b1a1918  ................\n"
459 "    ffffffffffffff20 2726252423222120 2f2e2d2c2b2a2928   !\"#$%&'()*+,-./\n"
460 "    ffffffffffffff30 3736353433323130 3f3e3d3c3b3a3938  0123456789:;<=>?\n"
461 "    ffffffffffffff40 4746454443424140 4f4e4d4c4b4a4948  @ABCDEFGHIJKLMNO\n"
462 "    ffffffffffffff50 5756555453525150 5f5e5d5c5b5a5958  PQRSTUVWXYZ[\\]^_\n"
463 "    ffffffffffffff60 6766656463626160 6f6e6d6c6b6a6968  `abcdefghijklmno\n"
464 "    ffffffffffffff70 7776757473727170 7f7e7d7c7b7a7978  pqrstuvwxyz{|}~.\n"
465 "    ffffffffffffff80 8786858483828180 8f8e8d8c8b8a8988  ................\n"
466 "    ffffffffffffff90 9796959493929190 9f9e9d9c9b9a9998  ................\n"
467 "    ffffffffffffffa0 a7a6a5a4a3a2a1a0 afaeadacabaaa9a8  ................\n"
468 "    ffffffffffffffb0 b7b6b5b4b3b2b1b0 bfbebdbcbbbab9b8  ................\n"
469 "    ffffffffffffffc0 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8  ................\n"
470 "    ffffffffffffffd0 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8  ................\n"
471 "    ffffffffffffffe0 e7e6e5e4e3e2e1e0 efeeedecebeae9e8  ................\n"
472 "    fffffffffffffff0 f7f6f5f4f3f2f1f0 fffefdfcfbfaf9f8  ................\n";
473 #else
474 "    ffffff00 03020100 07060504 0b0a0908 0f0e0d0c  ................\n"
475 "    ffffff10 13121110 17161514 1b1a1918 1f1e1d1c  ................\n"
476 "    ffffff20 23222120 27262524 2b2a2928 2f2e2d2c   !\"#$%&'()*+,-./\n"
477 "    ffffff30 33323130 37363534 3b3a3938 3f3e3d3c  0123456789:;<=>?\n"
478 "    ffffff40 43424140 47464544 4b4a4948 4f4e4d4c  @ABCDEFGHIJKLMNO\n"
479 "    ffffff50 53525150 57565554 5b5a5958 5f5e5d5c  PQRSTUVWXYZ[\\]^_\n"
480 "    ffffff60 63626160 67666564 6b6a6968 6f6e6d6c  `abcdefghijklmno\n"
481 "    ffffff70 73727170 77767574 7b7a7978 7f7e7d7c  pqrstuvwxyz{|}~.\n"
482 "    ffffff80 83828180 87868584 8b8a8988 8f8e8d8c  ................\n"
483 "    ffffff90 93929190 97969594 9b9a9998 9f9e9d9c  ................\n"
484 "    ffffffa0 a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac  ................\n"
485 "    ffffffb0 b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc  ................\n"
486 "    ffffffc0 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc  ................\n"
487 "    ffffffd0 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc  ................\n"
488 "    ffffffe0 e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec  ................\n"
489 "    fffffff0 f3f2f1f0 f7f6f5f4 fbfaf9f8 fffefdfc  ................\n";
490 #endif
491   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
492 
493   // Verify that the log buf is empty, and no error messages.
494   ASSERT_STREQ("", getFakeLogBuf().c_str());
495   ASSERT_STREQ("", getFakeLogPrint().c_str());
496 }
497 
TEST_F(DumpMemoryTest,first_read_empty)498 TEST_F(DumpMemoryTest, first_read_empty) {
499   uint8_t buffer[256];
500   for (size_t i = 0; i < sizeof(buffer); i++) {
501     buffer[i] = i;
502   }
503   memory_mock_->SetReadData(buffer, sizeof(buffer));
504   memory_mock_->SetPartialReadAmount(0);
505 
506   size_t page_size = sysconf(_SC_PAGE_SIZE);
507   uintptr_t addr = 0x10000020 + page_size - 120;
508   dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
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 near r4:\n"
515 #if defined(__LP64__)
516 R"(    0000000010000f80 ---------------- ----------------  ................
517     0000000010000f90 ---------------- ----------------  ................
518     0000000010000fa0 ---------------- ----------------  ................
519     0000000010000fb0 ---------------- ----------------  ................
520     0000000010000fc0 ---------------- ----------------  ................
521     0000000010000fd0 ---------------- ----------------  ................
522     0000000010000fe0 ---------------- ----------------  ................
523     0000000010000ff0 ---------------- ----------------  ................
524     0000000010001000 8786858483828180 8f8e8d8c8b8a8988  ................
525     0000000010001010 9796959493929190 9f9e9d9c9b9a9998  ................
526     0000000010001020 a7a6a5a4a3a2a1a0 afaeadacabaaa9a8  ................
527     0000000010001030 b7b6b5b4b3b2b1b0 bfbebdbcbbbab9b8  ................
528     0000000010001040 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8  ................
529     0000000010001050 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8  ................
530     0000000010001060 e7e6e5e4e3e2e1e0 efeeedecebeae9e8  ................
531     0000000010001070 f7f6f5f4f3f2f1f0 fffefdfcfbfaf9f8  ................
532 )";
533 #else
534 R"(    10000f80 -------- -------- -------- --------  ................
535     10000f90 -------- -------- -------- --------  ................
536     10000fa0 -------- -------- -------- --------  ................
537     10000fb0 -------- -------- -------- --------  ................
538     10000fc0 -------- -------- -------- --------  ................
539     10000fd0 -------- -------- -------- --------  ................
540     10000fe0 -------- -------- -------- --------  ................
541     10000ff0 -------- -------- -------- --------  ................
542     10001000 83828180 87868584 8b8a8988 8f8e8d8c  ................
543     10001010 93929190 97969594 9b9a9998 9f9e9d9c  ................
544     10001020 a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac  ................
545     10001030 b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc  ................
546     10001040 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc  ................
547     10001050 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc  ................
548     10001060 e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec  ................
549     10001070 f3f2f1f0 f7f6f5f4 fbfaf9f8 fffefdfc  ................
550 )";
551 #endif
552   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
553 
554   // Verify that the log buf is empty, and no error messages.
555   ASSERT_STREQ("", getFakeLogBuf().c_str());
556   ASSERT_STREQ("", getFakeLogPrint().c_str());
557 }
558 
TEST_F(DumpMemoryTest,first_read_empty_second_read_stops)559 TEST_F(DumpMemoryTest, first_read_empty_second_read_stops) {
560   uint8_t buffer[224];
561   for (size_t i = 0; i < sizeof(buffer); i++) {
562     buffer[i] = i;
563   }
564   memory_mock_->SetReadData(buffer, sizeof(buffer));
565   memory_mock_->SetPartialReadAmount(0);
566 
567   size_t page_size = sysconf(_SC_PAGE_SIZE);
568   uintptr_t addr = 0x10000020 + page_size - 192;
569   dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
570 
571   std::string tombstone_contents;
572   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
573   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
574   const char* expected_dump = \
575 "\nmemory near r4:\n"
576 #if defined(__LP64__)
577 "    0000000010000f40 ---------------- ----------------  ................\n"
578 "    0000000010000f50 ---------------- ----------------  ................\n"
579 "    0000000010000f60 ---------------- ----------------  ................\n"
580 "    0000000010000f70 ---------------- ----------------  ................\n"
581 "    0000000010000f80 ---------------- ----------------  ................\n"
582 "    0000000010000f90 ---------------- ----------------  ................\n"
583 "    0000000010000fa0 ---------------- ----------------  ................\n"
584 "    0000000010000fb0 ---------------- ----------------  ................\n"
585 "    0000000010000fc0 ---------------- ----------------  ................\n"
586 "    0000000010000fd0 ---------------- ----------------  ................\n"
587 "    0000000010000fe0 ---------------- ----------------  ................\n"
588 "    0000000010000ff0 ---------------- ----------------  ................\n"
589 "    0000000010001000 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8  ................\n"
590 "    0000000010001010 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8  ................\n"
591 "    0000000010001020 ---------------- ----------------  ................\n"
592 "    0000000010001030 ---------------- ----------------  ................\n";
593 #else
594 "    10000f40 -------- -------- -------- --------  ................\n"
595 "    10000f50 -------- -------- -------- --------  ................\n"
596 "    10000f60 -------- -------- -------- --------  ................\n"
597 "    10000f70 -------- -------- -------- --------  ................\n"
598 "    10000f80 -------- -------- -------- --------  ................\n"
599 "    10000f90 -------- -------- -------- --------  ................\n"
600 "    10000fa0 -------- -------- -------- --------  ................\n"
601 "    10000fb0 -------- -------- -------- --------  ................\n"
602 "    10000fc0 -------- -------- -------- --------  ................\n"
603 "    10000fd0 -------- -------- -------- --------  ................\n"
604 "    10000fe0 -------- -------- -------- --------  ................\n"
605 "    10000ff0 -------- -------- -------- --------  ................\n"
606 "    10001000 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc  ................\n"
607 "    10001010 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc  ................\n"
608 "    10001020 -------- -------- -------- --------  ................\n"
609 "    10001030 -------- -------- -------- --------  ................\n";
610 #endif
611   ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
612 
613   // Verify that the log buf is empty, and no error messages.
614   ASSERT_STREQ("", getFakeLogBuf().c_str());
615   ASSERT_STREQ("", getFakeLogPrint().c_str());
616 }
617 
TEST_F(DumpMemoryTest,first_read_empty_next_page_out_of_range)618 TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range) {
619   uint8_t buffer[256];
620   for (size_t i = 0; i < sizeof(buffer); i++) {
621     buffer[i] = i;
622   }
623   memory_mock_->SetReadData(buffer, sizeof(buffer));
624   memory_mock_->SetPartialReadAmount(0);
625 
626   uintptr_t addr = 0x10000020;
627   dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
628 
629   std::string tombstone_contents;
630   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
631   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
632   ASSERT_STREQ("", tombstone_contents.c_str());
633 
634   // Verify that the log buf is empty, and no error messages.
635   ASSERT_STREQ("", getFakeLogBuf().c_str());
636   ASSERT_STREQ("", getFakeLogPrint().c_str());
637 }
638 
TEST_F(DumpMemoryTest,first_read_empty_next_page_out_of_range_fence_post)639 TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range_fence_post) {
640   uint8_t buffer[256];
641   for (size_t i = 0; i < sizeof(buffer); i++) {
642     buffer[i] = i;
643   }
644   memory_mock_->SetReadData(buffer, sizeof(buffer));
645   memory_mock_->SetPartialReadAmount(0);
646 
647   size_t page_size = sysconf(_SC_PAGE_SIZE);
648   uintptr_t addr = 0x10000020 + page_size - 256;
649 
650   dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
651 
652   std::string tombstone_contents;
653   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
654   ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
655   ASSERT_STREQ("", tombstone_contents.c_str());
656 
657   // Verify that the log buf is empty, and no error messages.
658   ASSERT_STREQ("", getFakeLogBuf().c_str());
659   ASSERT_STREQ("", getFakeLogPrint().c_str());
660 }
661