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 " 0000000012345658 0706050403020100 0f0e0d0c0b0a0908 ................\n"
34 " 0000000012345668 1716151413121110 1f1e1d1c1b1a1918 ................\n"
35 " 0000000012345678 2726252423222120 2f2e2d2c2b2a2928 !\"#$%&'()*+,-./\n"
36 " 0000000012345688 3736353433323130 3f3e3d3c3b3a3938 0123456789:;<=>?\n"
37 " 0000000012345698 4746454443424140 4f4e4d4c4b4a4948 @ABCDEFGHIJKLMNO\n"
38 " 00000000123456a8 5756555453525150 5f5e5d5c5b5a5958 PQRSTUVWXYZ[\\]^_\n"
39 " 00000000123456b8 6766656463626160 6f6e6d6c6b6a6968 `abcdefghijklmno\n"
40 " 00000000123456c8 7776757473727170 7f7e7d7c7b7a7978 pqrstuvwxyz{|}~.\n"
41 " 00000000123456d8 8786858483828180 8f8e8d8c8b8a8988 ................\n"
42 " 00000000123456e8 9796959493929190 9f9e9d9c9b9a9998 ................\n"
43 " 00000000123456f8 a7a6a5a4a3a2a1a0 afaeadacabaaa9a8 ................\n"
44 " 0000000012345708 b7b6b5b4b3b2b1b0 bfbebdbcbbbab9b8 ................\n"
45 " 0000000012345718 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8 ................\n"
46 " 0000000012345728 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8 ................\n"
47 " 0000000012345738 e7e6e5e4e3e2e1e0 efeeedecebeae9e8 ................\n"
48 " 0000000012345748 f7f6f5f4f3f2f1f0 fffefdfcfbfaf9f8 ................\n";
49 #else
50 " 12345658 03020100 07060504 0b0a0908 0f0e0d0c ................\n"
51 " 12345668 13121110 17161514 1b1a1918 1f1e1d1c ................\n"
52 " 12345678 23222120 27262524 2b2a2928 2f2e2d2c !\"#$%&'()*+,-./\n"
53 " 12345688 33323130 37363534 3b3a3938 3f3e3d3c 0123456789:;<=>?\n"
54 " 12345698 43424140 47464544 4b4a4948 4f4e4d4c @ABCDEFGHIJKLMNO\n"
55 " 123456a8 53525150 57565554 5b5a5958 5f5e5d5c PQRSTUVWXYZ[\\]^_\n"
56 " 123456b8 63626160 67666564 6b6a6968 6f6e6d6c `abcdefghijklmno\n"
57 " 123456c8 73727170 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~.\n"
58 " 123456d8 83828180 87868584 8b8a8988 8f8e8d8c ................\n"
59 " 123456e8 93929190 97969594 9b9a9998 9f9e9d9c ................\n"
60 " 123456f8 a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac ................\n"
61 " 12345708 b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc ................\n"
62 " 12345718 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc ................\n"
63 " 12345728 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc ................\n"
64 " 12345738 e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec ................\n"
65 " 12345748 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 = buffer_.size() - offset;
116
117 if (partial_read_) {
118 bytes = std::min(bytes, bytes_partial_read_);
119 bytes_partial_read_ -= bytes;
120 partial_read_ = bytes_partial_read_;
121 } else if (bytes > bytes_available) {
122 bytes = bytes_available;
123 }
124
125 if (bytes > 0) {
126 memcpy(buffer, buffer_.data() + offset, bytes);
127 }
128
129 last_read_addr_ = addr;
130 return bytes;
131 }
132
SetReadData(uint8_t * buffer,size_t bytes)133 void SetReadData(uint8_t* buffer, size_t bytes) {
134 buffer_.resize(bytes);
135 memcpy(buffer_.data(), buffer, bytes);
136 bytes_partial_read_ = 0;
137 last_read_addr_ = 0;
138 }
139
SetPartialReadAmount(size_t bytes)140 void SetPartialReadAmount(size_t bytes) {
141 if (bytes > buffer_.size()) {
142 abort();
143 }
144 partial_read_ = true;
145 bytes_partial_read_ = bytes;
146 }
147
148 private:
149 std::vector<uint8_t> buffer_;
150 bool partial_read_ = false;
151 size_t bytes_partial_read_ = 0;
152 uintptr_t last_read_addr_ = 0;
153 };
154
155 class DumpMemoryTest : public ::testing::Test {
156 protected:
SetUp()157 virtual void SetUp() {
158 memory_mock_ = std::make_unique<MemoryMock>();
159
160 char tmp_file[256];
161 const char data_template[] = "/data/local/tmp/debuggerd_memory_testXXXXXX";
162 memcpy(tmp_file, data_template, sizeof(data_template));
163 int tombstone_fd = mkstemp(tmp_file);
164 if (tombstone_fd == -1) {
165 const char tmp_template[] = "/tmp/debuggerd_memory_testXXXXXX";
166 memcpy(tmp_file, tmp_template, sizeof(tmp_template));
167 tombstone_fd = mkstemp(tmp_file);
168 if (tombstone_fd == -1) {
169 abort();
170 }
171 }
172 if (unlink(tmp_file) == -1) {
173 abort();
174 }
175
176 log_.tfd = tombstone_fd;
177 log_.amfd_data = nullptr;
178 log_.crashed_tid = 12;
179 log_.current_tid = 12;
180 log_.should_retrieve_logcat = false;
181
182 resetLogs();
183 }
184
TearDown()185 virtual void TearDown() {
186 if (log_.tfd >= 0) {
187 close(log_.tfd);
188 }
189 memory_mock_.reset();
190 }
191
192 std::unique_ptr<MemoryMock> memory_mock_;
193
194 log_t log_;
195 };
196
TEST_F(DumpMemoryTest,aligned_addr)197 TEST_F(DumpMemoryTest, aligned_addr) {
198 uint8_t buffer[256];
199 for (size_t i = 0; i < sizeof(buffer); i++) {
200 buffer[i] = i;
201 }
202 memory_mock_->SetReadData(buffer, sizeof(buffer));
203
204 dump_memory(&log_, memory_mock_.get(), 0x12345678, "memory near r1");
205
206 std::string tombstone_contents;
207 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
208 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
209 ASSERT_STREQ(g_expected_full_dump, tombstone_contents.c_str());
210
211 // Verify that the log buf is empty, and no error messages.
212 ASSERT_STREQ("", getFakeLogBuf().c_str());
213 ASSERT_STREQ("", getFakeLogPrint().c_str());
214 }
215
TEST_F(DumpMemoryTest,partial_read)216 TEST_F(DumpMemoryTest, partial_read) {
217 uint8_t buffer[256];
218 for (size_t i = 0; i < sizeof(buffer); i++) {
219 buffer[i] = i;
220 }
221 memory_mock_->SetReadData(buffer, sizeof(buffer));
222 memory_mock_->SetPartialReadAmount(96);
223
224 dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near r1");
225
226 std::string tombstone_contents;
227 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
228 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
229 ASSERT_STREQ(g_expected_full_dump, tombstone_contents.c_str());
230
231 // Verify that the log buf is empty, and no error messages.
232 ASSERT_STREQ("", getFakeLogBuf().c_str());
233 ASSERT_STREQ("", getFakeLogPrint().c_str());
234 }
235
TEST_F(DumpMemoryTest,unaligned_addr)236 TEST_F(DumpMemoryTest, unaligned_addr) {
237 uint8_t buffer[256];
238 for (size_t i = 0; i < sizeof(buffer); i++) {
239 buffer[i] = i;
240 }
241 memory_mock_->SetReadData(buffer, sizeof(buffer));
242
243 dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near r1");
244
245 std::string tombstone_contents;
246 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
247 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
248 ASSERT_STREQ(g_expected_full_dump, tombstone_contents.c_str());
249
250 // Verify that the log buf is empty, and no error messages.
251 ASSERT_STREQ("", getFakeLogBuf().c_str());
252 ASSERT_STREQ("", getFakeLogPrint().c_str());
253 }
254
TEST_F(DumpMemoryTest,memory_unreadable)255 TEST_F(DumpMemoryTest, memory_unreadable) {
256 dump_memory(&log_, memory_mock_.get(), 0xa2345678, "memory near pc");
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 near pc:\n"
263 #if defined(__LP64__)
264 " 00000000a2345658 ---------------- ---------------- ................\n"
265 " 00000000a2345668 ---------------- ---------------- ................\n"
266 " 00000000a2345678 ---------------- ---------------- ................\n"
267 " 00000000a2345688 ---------------- ---------------- ................\n"
268 " 00000000a2345698 ---------------- ---------------- ................\n"
269 " 00000000a23456a8 ---------------- ---------------- ................\n"
270 " 00000000a23456b8 ---------------- ---------------- ................\n"
271 " 00000000a23456c8 ---------------- ---------------- ................\n"
272 " 00000000a23456d8 ---------------- ---------------- ................\n"
273 " 00000000a23456e8 ---------------- ---------------- ................\n"
274 " 00000000a23456f8 ---------------- ---------------- ................\n"
275 " 00000000a2345708 ---------------- ---------------- ................\n"
276 " 00000000a2345718 ---------------- ---------------- ................\n"
277 " 00000000a2345728 ---------------- ---------------- ................\n"
278 " 00000000a2345738 ---------------- ---------------- ................\n"
279 " 00000000a2345748 ---------------- ---------------- ................\n";
280 #else
281 " a2345658 -------- -------- -------- -------- ................\n"
282 " a2345668 -------- -------- -------- -------- ................\n"
283 " a2345678 -------- -------- -------- -------- ................\n"
284 " a2345688 -------- -------- -------- -------- ................\n"
285 " a2345698 -------- -------- -------- -------- ................\n"
286 " a23456a8 -------- -------- -------- -------- ................\n"
287 " a23456b8 -------- -------- -------- -------- ................\n"
288 " a23456c8 -------- -------- -------- -------- ................\n"
289 " a23456d8 -------- -------- -------- -------- ................\n"
290 " a23456e8 -------- -------- -------- -------- ................\n"
291 " a23456f8 -------- -------- -------- -------- ................\n"
292 " a2345708 -------- -------- -------- -------- ................\n"
293 " a2345718 -------- -------- -------- -------- ................\n"
294 " a2345728 -------- -------- -------- -------- ................\n"
295 " a2345738 -------- -------- -------- -------- ................\n"
296 " a2345748 -------- -------- -------- -------- ................\n";
297 #endif
298 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
299
300 // Verify that the log buf is empty, and no error messages.
301 ASSERT_STREQ("", getFakeLogBuf().c_str());
302 ASSERT_STREQ("", getFakeLogPrint().c_str());
303 }
304
TEST_F(DumpMemoryTest,memory_partially_unreadable)305 TEST_F(DumpMemoryTest, memory_partially_unreadable) {
306 uint8_t buffer[104];
307 for (size_t i = 0; i < sizeof(buffer); i++) {
308 buffer[i] = i;
309 }
310 memory_mock_->SetReadData(buffer, sizeof(buffer));
311
312 dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");
313
314 std::string tombstone_contents;
315 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
316 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
317 ASSERT_STREQ(g_expected_partial_dump, tombstone_contents.c_str());
318
319 // Verify that the log buf is empty, and no error messages.
320 ASSERT_STREQ("", getFakeLogBuf().c_str());
321 ASSERT_STREQ("", getFakeLogPrint().c_str());
322 }
323
TEST_F(DumpMemoryTest,memory_partially_unreadable_unaligned_return)324 TEST_F(DumpMemoryTest, memory_partially_unreadable_unaligned_return) {
325 uint8_t buffer[104];
326 for (size_t i = 0; i < sizeof(buffer); i++) {
327 buffer[i] = i;
328 }
329 memory_mock_->SetReadData(buffer, sizeof(buffer));
330 memory_mock_->SetPartialReadAmount(102);
331
332 dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");
333
334 std::string tombstone_contents;
335 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
336 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
337 ASSERT_STREQ(g_expected_partial_dump, tombstone_contents.c_str());
338
339 #if defined(__LP64__)
340 ASSERT_STREQ("6 DEBUG Bytes read 102, is not a multiple of 8\n", getFakeLogPrint().c_str());
341 #else
342 ASSERT_STREQ("6 DEBUG Bytes read 102, is not a multiple of 4\n", getFakeLogPrint().c_str());
343 #endif
344
345 // Verify that the log buf is empty, and no error messages.
346 ASSERT_STREQ("", getFakeLogBuf().c_str());
347 }
348
TEST_F(DumpMemoryTest,memory_partially_unreadable_two_unaligned_reads)349 TEST_F(DumpMemoryTest, memory_partially_unreadable_two_unaligned_reads) {
350 uint8_t buffer[106];
351 for (size_t i = 0; i < sizeof(buffer); i++) {
352 buffer[i] = i;
353 }
354 memory_mock_->SetReadData(buffer, sizeof(buffer));
355 memory_mock_->SetPartialReadAmount(45);
356
357 dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");
358
359 std::string tombstone_contents;
360 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
361 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
362 ASSERT_STREQ(g_expected_partial_dump, tombstone_contents.c_str());
363
364 #if defined(__LP64__)
365 ASSERT_STREQ("6 DEBUG Bytes read 45, is not a multiple of 8\n"
366 "6 DEBUG Bytes after second read 106, is not a multiple of 8\n",
367 getFakeLogPrint().c_str());
368 #else
369 ASSERT_STREQ("6 DEBUG Bytes read 45, is not a multiple of 4\n"
370 "6 DEBUG Bytes after second read 106, is not a multiple of 4\n",
371 getFakeLogPrint().c_str());
372 #endif
373
374 // Verify that the log buf is empty, and no error messages.
375 ASSERT_STREQ("", getFakeLogBuf().c_str());
376 }
377
TEST_F(DumpMemoryTest,address_low_fence)378 TEST_F(DumpMemoryTest, address_low_fence) {
379 uint8_t buffer[256];
380 memset(buffer, 0, sizeof(buffer));
381 memory_mock_->SetReadData(buffer, sizeof(buffer));
382
383 dump_memory(&log_, memory_mock_.get(), 0x1000, "memory near r1");
384
385 std::string tombstone_contents;
386 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
387 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
388 const char* expected_dump = \
389 "\nmemory near r1:\n"
390 #if defined(__LP64__)
391 " 0000000000001000 0000000000000000 0000000000000000 ................\n"
392 " 0000000000001010 0000000000000000 0000000000000000 ................\n"
393 " 0000000000001020 0000000000000000 0000000000000000 ................\n"
394 " 0000000000001030 0000000000000000 0000000000000000 ................\n"
395 " 0000000000001040 0000000000000000 0000000000000000 ................\n"
396 " 0000000000001050 0000000000000000 0000000000000000 ................\n"
397 " 0000000000001060 0000000000000000 0000000000000000 ................\n"
398 " 0000000000001070 0000000000000000 0000000000000000 ................\n"
399 " 0000000000001080 0000000000000000 0000000000000000 ................\n"
400 " 0000000000001090 0000000000000000 0000000000000000 ................\n"
401 " 00000000000010a0 0000000000000000 0000000000000000 ................\n"
402 " 00000000000010b0 0000000000000000 0000000000000000 ................\n"
403 " 00000000000010c0 0000000000000000 0000000000000000 ................\n"
404 " 00000000000010d0 0000000000000000 0000000000000000 ................\n"
405 " 00000000000010e0 0000000000000000 0000000000000000 ................\n"
406 " 00000000000010f0 0000000000000000 0000000000000000 ................\n";
407 #else
408 " 00001000 00000000 00000000 00000000 00000000 ................\n"
409 " 00001010 00000000 00000000 00000000 00000000 ................\n"
410 " 00001020 00000000 00000000 00000000 00000000 ................\n"
411 " 00001030 00000000 00000000 00000000 00000000 ................\n"
412 " 00001040 00000000 00000000 00000000 00000000 ................\n"
413 " 00001050 00000000 00000000 00000000 00000000 ................\n"
414 " 00001060 00000000 00000000 00000000 00000000 ................\n"
415 " 00001070 00000000 00000000 00000000 00000000 ................\n"
416 " 00001080 00000000 00000000 00000000 00000000 ................\n"
417 " 00001090 00000000 00000000 00000000 00000000 ................\n"
418 " 000010a0 00000000 00000000 00000000 00000000 ................\n"
419 " 000010b0 00000000 00000000 00000000 00000000 ................\n"
420 " 000010c0 00000000 00000000 00000000 00000000 ................\n"
421 " 000010d0 00000000 00000000 00000000 00000000 ................\n"
422 " 000010e0 00000000 00000000 00000000 00000000 ................\n"
423 " 000010f0 00000000 00000000 00000000 00000000 ................\n";
424 #endif
425 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
426
427 // Verify that the log buf is empty, and no error messages.
428 ASSERT_STREQ("", getFakeLogBuf().c_str());
429 ASSERT_STREQ("", getFakeLogPrint().c_str());
430 }
431
TEST_F(DumpMemoryTest,memory_address_too_low)432 TEST_F(DumpMemoryTest, memory_address_too_low) {
433 uint8_t buffer[256];
434 memset(buffer, 0, sizeof(buffer));
435 memory_mock_->SetReadData(buffer, sizeof(buffer));
436
437 dump_memory(&log_, memory_mock_.get(), 0, "memory near r1");
438
439 std::string tombstone_contents;
440 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
441 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
442 ASSERT_STREQ("", tombstone_contents.c_str());
443
444 // Verify that the log buf is empty, and no error messages.
445 ASSERT_STREQ("", getFakeLogBuf().c_str());
446 ASSERT_STREQ("", getFakeLogPrint().c_str());
447 }
448
TEST_F(DumpMemoryTest,memory_address_too_high)449 TEST_F(DumpMemoryTest, memory_address_too_high) {
450 uint8_t buffer[256];
451 memset(buffer, 0, sizeof(buffer));
452 memory_mock_->SetReadData(buffer, sizeof(buffer));
453
454 #if defined(__LP64__)
455 dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL, "memory near r1");
456 dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 32, "memory near r1");
457 dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 216, "memory near r1");
458 #else
459 dump_memory(&log_, memory_mock_.get(), 0xffff0000, "memory near r1");
460 dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 32, "memory near r1");
461 dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 220, "memory near r1");
462 #endif
463
464 std::string tombstone_contents;
465 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
466 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
467 ASSERT_STREQ("", tombstone_contents.c_str());
468
469 // Verify that the log buf is empty, and no error messages.
470 ASSERT_STREQ("", getFakeLogBuf().c_str());
471 ASSERT_STREQ("", getFakeLogPrint().c_str());
472 }
473
TEST_F(DumpMemoryTest,memory_address_would_overflow)474 TEST_F(DumpMemoryTest, memory_address_would_overflow) {
475 uint8_t buffer[256];
476 memset(buffer, 0, sizeof(buffer));
477 memory_mock_->SetReadData(buffer, sizeof(buffer));
478
479 #if defined(__LP64__)
480 dump_memory(&log_, memory_mock_.get(), 0xfffffffffffffff0, "memory near r1");
481 #else
482 dump_memory(&log_, memory_mock_.get(), 0xfffffff0, "memory near r1");
483 #endif
484
485 std::string tombstone_contents;
486 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
487 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
488 ASSERT_STREQ("", tombstone_contents.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(DumpMemoryTest,memory_address_nearly_too_high)495 TEST_F(DumpMemoryTest, memory_address_nearly_too_high) {
496 uint8_t buffer[256];
497 for (size_t i = 0; i < sizeof(buffer); i++) {
498 buffer[i] = i;
499 }
500 memory_mock_->SetReadData(buffer, sizeof(buffer));
501
502 #if defined(__LP64__)
503 dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 224, "memory near r4");
504 #else
505 dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 224, "memory near r4");
506 #endif
507
508 std::string tombstone_contents;
509 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
510 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
511 const char* expected_dump = \
512 "\nmemory near r4:\n"
513 #if defined(__LP64__)
514 " 3fffffffffffff00 0706050403020100 0f0e0d0c0b0a0908 ................\n"
515 " 3fffffffffffff10 1716151413121110 1f1e1d1c1b1a1918 ................\n"
516 " 3fffffffffffff20 2726252423222120 2f2e2d2c2b2a2928 !\"#$%&'()*+,-./\n"
517 " 3fffffffffffff30 3736353433323130 3f3e3d3c3b3a3938 0123456789:;<=>?\n"
518 " 3fffffffffffff40 4746454443424140 4f4e4d4c4b4a4948 @ABCDEFGHIJKLMNO\n"
519 " 3fffffffffffff50 5756555453525150 5f5e5d5c5b5a5958 PQRSTUVWXYZ[\\]^_\n"
520 " 3fffffffffffff60 6766656463626160 6f6e6d6c6b6a6968 `abcdefghijklmno\n"
521 " 3fffffffffffff70 7776757473727170 7f7e7d7c7b7a7978 pqrstuvwxyz{|}~.\n"
522 " 3fffffffffffff80 8786858483828180 8f8e8d8c8b8a8988 ................\n"
523 " 3fffffffffffff90 9796959493929190 9f9e9d9c9b9a9998 ................\n"
524 " 3fffffffffffffa0 a7a6a5a4a3a2a1a0 afaeadacabaaa9a8 ................\n"
525 " 3fffffffffffffb0 b7b6b5b4b3b2b1b0 bfbebdbcbbbab9b8 ................\n"
526 " 3fffffffffffffc0 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8 ................\n"
527 " 3fffffffffffffd0 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8 ................\n"
528 " 3fffffffffffffe0 e7e6e5e4e3e2e1e0 efeeedecebeae9e8 ................\n"
529 " 3ffffffffffffff0 f7f6f5f4f3f2f1f0 fffefdfcfbfaf9f8 ................\n";
530 #else
531 " fffeff00 03020100 07060504 0b0a0908 0f0e0d0c ................\n"
532 " fffeff10 13121110 17161514 1b1a1918 1f1e1d1c ................\n"
533 " fffeff20 23222120 27262524 2b2a2928 2f2e2d2c !\"#$%&'()*+,-./\n"
534 " fffeff30 33323130 37363534 3b3a3938 3f3e3d3c 0123456789:;<=>?\n"
535 " fffeff40 43424140 47464544 4b4a4948 4f4e4d4c @ABCDEFGHIJKLMNO\n"
536 " fffeff50 53525150 57565554 5b5a5958 5f5e5d5c PQRSTUVWXYZ[\\]^_\n"
537 " fffeff60 63626160 67666564 6b6a6968 6f6e6d6c `abcdefghijklmno\n"
538 " fffeff70 73727170 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~.\n"
539 " fffeff80 83828180 87868584 8b8a8988 8f8e8d8c ................\n"
540 " fffeff90 93929190 97969594 9b9a9998 9f9e9d9c ................\n"
541 " fffeffa0 a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac ................\n"
542 " fffeffb0 b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc ................\n"
543 " fffeffc0 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc ................\n"
544 " fffeffd0 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc ................\n"
545 " fffeffe0 e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec ................\n"
546 " fffefff0 f3f2f1f0 f7f6f5f4 fbfaf9f8 fffefdfc ................\n";
547 #endif
548 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
549
550 // Verify that the log buf is empty, and no error messages.
551 ASSERT_STREQ("", getFakeLogBuf().c_str());
552 ASSERT_STREQ("", getFakeLogPrint().c_str());
553 }
554
TEST_F(DumpMemoryTest,first_read_empty)555 TEST_F(DumpMemoryTest, first_read_empty) {
556 uint8_t buffer[256];
557 for (size_t i = 0; i < sizeof(buffer); i++) {
558 buffer[i] = i;
559 }
560 memory_mock_->SetReadData(buffer, sizeof(buffer));
561 memory_mock_->SetPartialReadAmount(0);
562
563 size_t page_size = sysconf(_SC_PAGE_SIZE);
564 uintptr_t addr = 0x10000020 + page_size - 120;
565 dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
566
567 std::string tombstone_contents;
568 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
569 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
570 const char* expected_dump = \
571 "\nmemory near r4:\n"
572 #if defined(__LP64__)
573 " 0000000010000f88 ---------------- ---------------- ................\n"
574 " 0000000010000f98 ---------------- ---------------- ................\n"
575 " 0000000010000fa8 ---------------- ---------------- ................\n"
576 " 0000000010000fb8 ---------------- ---------------- ................\n"
577 " 0000000010000fc8 ---------------- ---------------- ................\n"
578 " 0000000010000fd8 ---------------- ---------------- ................\n"
579 " 0000000010000fe8 ---------------- ---------------- ................\n"
580 " 0000000010000ff8 ---------------- 7f7e7d7c7b7a7978 ........xyz{|}~.\n"
581 " 0000000010001008 8786858483828180 8f8e8d8c8b8a8988 ................\n"
582 " 0000000010001018 9796959493929190 9f9e9d9c9b9a9998 ................\n"
583 " 0000000010001028 a7a6a5a4a3a2a1a0 afaeadacabaaa9a8 ................\n"
584 " 0000000010001038 b7b6b5b4b3b2b1b0 bfbebdbcbbbab9b8 ................\n"
585 " 0000000010001048 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8 ................\n"
586 " 0000000010001058 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8 ................\n"
587 " 0000000010001068 e7e6e5e4e3e2e1e0 efeeedecebeae9e8 ................\n"
588 " 0000000010001078 f7f6f5f4f3f2f1f0 fffefdfcfbfaf9f8 ................\n";
589 #else
590 " 10000f88 -------- -------- -------- -------- ................\n"
591 " 10000f98 -------- -------- -------- -------- ................\n"
592 " 10000fa8 -------- -------- -------- -------- ................\n"
593 " 10000fb8 -------- -------- -------- -------- ................\n"
594 " 10000fc8 -------- -------- -------- -------- ................\n"
595 " 10000fd8 -------- -------- -------- -------- ................\n"
596 " 10000fe8 -------- -------- -------- -------- ................\n"
597 " 10000ff8 -------- -------- 7b7a7978 7f7e7d7c ........xyz{|}~.\n"
598 " 10001008 83828180 87868584 8b8a8988 8f8e8d8c ................\n"
599 " 10001018 93929190 97969594 9b9a9998 9f9e9d9c ................\n"
600 " 10001028 a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac ................\n"
601 " 10001038 b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc ................\n"
602 " 10001048 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc ................\n"
603 " 10001058 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc ................\n"
604 " 10001068 e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec ................\n"
605 " 10001078 f3f2f1f0 f7f6f5f4 fbfaf9f8 fffefdfc ................\n";
606 #endif
607 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
608
609 // Verify that the log buf is empty, and no error messages.
610 ASSERT_STREQ("", getFakeLogBuf().c_str());
611 ASSERT_STREQ("", getFakeLogPrint().c_str());
612 }
613
TEST_F(DumpMemoryTest,first_read_empty_second_read_stops)614 TEST_F(DumpMemoryTest, first_read_empty_second_read_stops) {
615 uint8_t buffer[224];
616 for (size_t i = 0; i < sizeof(buffer); i++) {
617 buffer[i] = i;
618 }
619 memory_mock_->SetReadData(buffer, sizeof(buffer));
620 memory_mock_->SetPartialReadAmount(0);
621
622 size_t page_size = sysconf(_SC_PAGE_SIZE);
623 uintptr_t addr = 0x10000020 + page_size - 192;
624 dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
625
626 std::string tombstone_contents;
627 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
628 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
629 const char* expected_dump = \
630 "\nmemory near r4:\n"
631 #if defined(__LP64__)
632 " 0000000010000f40 ---------------- ---------------- ................\n"
633 " 0000000010000f50 ---------------- ---------------- ................\n"
634 " 0000000010000f60 ---------------- ---------------- ................\n"
635 " 0000000010000f70 ---------------- ---------------- ................\n"
636 " 0000000010000f80 ---------------- ---------------- ................\n"
637 " 0000000010000f90 ---------------- ---------------- ................\n"
638 " 0000000010000fa0 ---------------- ---------------- ................\n"
639 " 0000000010000fb0 ---------------- ---------------- ................\n"
640 " 0000000010000fc0 ---------------- ---------------- ................\n"
641 " 0000000010000fd0 ---------------- ---------------- ................\n"
642 " 0000000010000fe0 ---------------- ---------------- ................\n"
643 " 0000000010000ff0 ---------------- ---------------- ................\n"
644 " 0000000010001000 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8 ................\n"
645 " 0000000010001010 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8 ................\n"
646 " 0000000010001020 ---------------- ---------------- ................\n"
647 " 0000000010001030 ---------------- ---------------- ................\n";
648 #else
649 " 10000f40 -------- -------- -------- -------- ................\n"
650 " 10000f50 -------- -------- -------- -------- ................\n"
651 " 10000f60 -------- -------- -------- -------- ................\n"
652 " 10000f70 -------- -------- -------- -------- ................\n"
653 " 10000f80 -------- -------- -------- -------- ................\n"
654 " 10000f90 -------- -------- -------- -------- ................\n"
655 " 10000fa0 -------- -------- -------- -------- ................\n"
656 " 10000fb0 -------- -------- -------- -------- ................\n"
657 " 10000fc0 -------- -------- -------- -------- ................\n"
658 " 10000fd0 -------- -------- -------- -------- ................\n"
659 " 10000fe0 -------- -------- -------- -------- ................\n"
660 " 10000ff0 -------- -------- -------- -------- ................\n"
661 " 10001000 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc ................\n"
662 " 10001010 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc ................\n"
663 " 10001020 -------- -------- -------- -------- ................\n"
664 " 10001030 -------- -------- -------- -------- ................\n";
665 #endif
666 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
667
668 // Verify that the log buf is empty, and no error messages.
669 ASSERT_STREQ("", getFakeLogBuf().c_str());
670 ASSERT_STREQ("", getFakeLogPrint().c_str());
671 }
672
TEST_F(DumpMemoryTest,first_read_empty_next_page_out_of_range)673 TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range) {
674 uint8_t buffer[256];
675 for (size_t i = 0; i < sizeof(buffer); i++) {
676 buffer[i] = i;
677 }
678 memory_mock_->SetReadData(buffer, sizeof(buffer));
679 memory_mock_->SetPartialReadAmount(0);
680
681 uintptr_t addr = 0x10000020;
682 dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
683
684 std::string tombstone_contents;
685 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
686 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
687 const char* expected_dump = \
688 "\nmemory near r4:\n"
689 #if defined(__LP64__)
690 " 0000000010000000 ---------------- ---------------- ................\n"
691 " 0000000010000010 ---------------- ---------------- ................\n"
692 " 0000000010000020 ---------------- ---------------- ................\n"
693 " 0000000010000030 ---------------- ---------------- ................\n"
694 " 0000000010000040 ---------------- ---------------- ................\n"
695 " 0000000010000050 ---------------- ---------------- ................\n"
696 " 0000000010000060 ---------------- ---------------- ................\n"
697 " 0000000010000070 ---------------- ---------------- ................\n"
698 " 0000000010000080 ---------------- ---------------- ................\n"
699 " 0000000010000090 ---------------- ---------------- ................\n"
700 " 00000000100000a0 ---------------- ---------------- ................\n"
701 " 00000000100000b0 ---------------- ---------------- ................\n"
702 " 00000000100000c0 ---------------- ---------------- ................\n"
703 " 00000000100000d0 ---------------- ---------------- ................\n"
704 " 00000000100000e0 ---------------- ---------------- ................\n"
705 " 00000000100000f0 ---------------- ---------------- ................\n";
706 #else
707 " 10000000 -------- -------- -------- -------- ................\n"
708 " 10000010 -------- -------- -------- -------- ................\n"
709 " 10000020 -------- -------- -------- -------- ................\n"
710 " 10000030 -------- -------- -------- -------- ................\n"
711 " 10000040 -------- -------- -------- -------- ................\n"
712 " 10000050 -------- -------- -------- -------- ................\n"
713 " 10000060 -------- -------- -------- -------- ................\n"
714 " 10000070 -------- -------- -------- -------- ................\n"
715 " 10000080 -------- -------- -------- -------- ................\n"
716 " 10000090 -------- -------- -------- -------- ................\n"
717 " 100000a0 -------- -------- -------- -------- ................\n"
718 " 100000b0 -------- -------- -------- -------- ................\n"
719 " 100000c0 -------- -------- -------- -------- ................\n"
720 " 100000d0 -------- -------- -------- -------- ................\n"
721 " 100000e0 -------- -------- -------- -------- ................\n"
722 " 100000f0 -------- -------- -------- -------- ................\n";
723 #endif
724 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
725
726 // Verify that the log buf is empty, and no error messages.
727 ASSERT_STREQ("", getFakeLogBuf().c_str());
728 ASSERT_STREQ("", getFakeLogPrint().c_str());
729 }
730
TEST_F(DumpMemoryTest,first_read_empty_next_page_out_of_range_fence_post)731 TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range_fence_post) {
732 uint8_t buffer[256];
733 for (size_t i = 0; i < sizeof(buffer); i++) {
734 buffer[i] = i;
735 }
736 memory_mock_->SetReadData(buffer, sizeof(buffer));
737 memory_mock_->SetPartialReadAmount(0);
738
739 size_t page_size = sysconf(_SC_PAGE_SIZE);
740 uintptr_t addr = 0x10000020 + page_size - 256;
741
742 dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
743
744 std::string tombstone_contents;
745 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
746 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
747 const char* expected_dump = \
748 "\nmemory near r4:\n"
749 #if defined(__LP64__)
750 " 0000000010000f00 ---------------- ---------------- ................\n"
751 " 0000000010000f10 ---------------- ---------------- ................\n"
752 " 0000000010000f20 ---------------- ---------------- ................\n"
753 " 0000000010000f30 ---------------- ---------------- ................\n"
754 " 0000000010000f40 ---------------- ---------------- ................\n"
755 " 0000000010000f50 ---------------- ---------------- ................\n"
756 " 0000000010000f60 ---------------- ---------------- ................\n"
757 " 0000000010000f70 ---------------- ---------------- ................\n"
758 " 0000000010000f80 ---------------- ---------------- ................\n"
759 " 0000000010000f90 ---------------- ---------------- ................\n"
760 " 0000000010000fa0 ---------------- ---------------- ................\n"
761 " 0000000010000fb0 ---------------- ---------------- ................\n"
762 " 0000000010000fc0 ---------------- ---------------- ................\n"
763 " 0000000010000fd0 ---------------- ---------------- ................\n"
764 " 0000000010000fe0 ---------------- ---------------- ................\n"
765 " 0000000010000ff0 ---------------- ---------------- ................\n";
766 #else
767 " 10000f00 -------- -------- -------- -------- ................\n"
768 " 10000f10 -------- -------- -------- -------- ................\n"
769 " 10000f20 -------- -------- -------- -------- ................\n"
770 " 10000f30 -------- -------- -------- -------- ................\n"
771 " 10000f40 -------- -------- -------- -------- ................\n"
772 " 10000f50 -------- -------- -------- -------- ................\n"
773 " 10000f60 -------- -------- -------- -------- ................\n"
774 " 10000f70 -------- -------- -------- -------- ................\n"
775 " 10000f80 -------- -------- -------- -------- ................\n"
776 " 10000f90 -------- -------- -------- -------- ................\n"
777 " 10000fa0 -------- -------- -------- -------- ................\n"
778 " 10000fb0 -------- -------- -------- -------- ................\n"
779 " 10000fc0 -------- -------- -------- -------- ................\n"
780 " 10000fd0 -------- -------- -------- -------- ................\n"
781 " 10000fe0 -------- -------- -------- -------- ................\n"
782 " 10000ff0 -------- -------- -------- -------- ................\n";
783 #endif
784 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
785
786 // Verify that the log buf is empty, and no error messages.
787 ASSERT_STREQ("", getFakeLogBuf().c_str());
788 ASSERT_STREQ("", getFakeLogPrint().c_str());
789 }
790