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