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 <malloc.h>
18 #include <signal.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/cdefs.h>
23 #include <sys/mman.h>
24 #include <sys/param.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27
28 #include <algorithm>
29 #include <memory>
30 #include <thread>
31 #include <vector>
32 #include <utility>
33
34 #include <tinyxml2.h>
35
36 #include <gtest/gtest.h>
37
38 #include <android-base/file.h>
39 #include <android-base/stringprintf.h>
40 #include <android-base/strings.h>
41
42 #include <private/bionic_macros.h>
43 #include <private/bionic_malloc_dispatch.h>
44
45 #include "Config.h"
46 #include "malloc_debug.h"
47
48 #include "log_fake.h"
49 #include "backtrace_fake.h"
50
51 __BEGIN_DECLS
52
53 bool debug_initialize(const MallocDispatch*, bool*, const char*);
54 void debug_finalize();
55
56 void* debug_malloc(size_t);
57 void debug_free(void*);
58 void* debug_calloc(size_t, size_t);
59 void* debug_realloc(void*, size_t);
60 int debug_posix_memalign(void**, size_t, size_t);
61 void* debug_memalign(size_t, size_t);
62 void* debug_aligned_alloc(size_t, size_t);
63 size_t debug_malloc_usable_size(void*);
64 void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
65 void debug_free_malloc_leak_info(uint8_t*);
66
67 struct mallinfo debug_mallinfo();
68 int debug_mallopt(int, int);
69 int debug_malloc_info(int, FILE*);
70
71 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
72 void* debug_pvalloc(size_t);
73 void* debug_valloc(size_t);
74 #endif
75
76 __END_DECLS
77
78 constexpr char DIVIDER[] =
79 "6 malloc_debug *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n";
80
get_tag_offset()81 static size_t get_tag_offset() {
82 return __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
83 }
84
85 static constexpr const char RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs.txt";
86
87 static constexpr const char BACKTRACE_DUMP_PREFIX[] = "/data/local/tmp/backtrace_heap";
88
89 class MallocDebugTest : public ::testing::Test {
90 protected:
SetUp()91 void SetUp() override {
92 initialized = false;
93 resetLogs();
94 backtrace_fake_clear_all();
95 // Delete the record data file if it exists.
96 unlink(RECORD_ALLOCS_FILE);
97 }
98
TearDown()99 void TearDown() override {
100 if (initialized) {
101 debug_finalize();
102 }
103 }
104
Init(const char * options)105 void Init(const char* options) {
106 zygote_child = false;
107 ASSERT_TRUE(debug_initialize(&dispatch, &zygote_child, options));
108 initialized = true;
109 }
110
111 void BacktraceDumpOnSignal(bool trigger_with_alloc);
112
GetInfoEntrySize(size_t max_frames)113 static size_t GetInfoEntrySize(size_t max_frames) {
114 return 2 * sizeof(size_t) + max_frames * sizeof(uintptr_t);
115 }
116
117 bool initialized;
118
119 bool zygote_child;
120
121 static MallocDispatch dispatch;
122 };
123
124 MallocDispatch MallocDebugTest::dispatch = {
125 calloc,
126 free,
127 mallinfo,
128 malloc,
129 malloc_usable_size,
130 memalign,
131 posix_memalign,
132 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
133 nullptr,
134 #endif
135 realloc,
136 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
137 nullptr,
138 #endif
139 nullptr,
140 nullptr,
141 nullptr,
142 mallopt,
143 aligned_alloc,
144 malloc_info,
145 };
146
ShowDiffs(uint8_t * a,uint8_t * b,size_t size)147 std::string ShowDiffs(uint8_t* a, uint8_t* b, size_t size) {
148 std::string diff;
149 for (size_t i = 0; i < size; i++) {
150 if (a[i] != b[i]) {
151 diff += android::base::StringPrintf("Byte %zu: 0x%x 0x%x\n", i, a[i], b[i]);
152 }
153 }
154 return diff;
155 }
156
VerifyAllocCalls(bool all_options)157 void VerifyAllocCalls(bool all_options) {
158 size_t alloc_size = 1024;
159
160 // Verify debug_malloc.
161 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(alloc_size));
162 ASSERT_TRUE(pointer != nullptr);
163 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
164 ASSERT_EQ(0xeb, pointer[i]);
165 }
166 debug_free(pointer);
167
168 // Verify debug_calloc.
169 pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, alloc_size));
170 ASSERT_TRUE(pointer != nullptr);
171 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
172 ASSERT_EQ(0, pointer[i]) << "Failed at byte " << i;
173 }
174 debug_free(pointer);
175
176 pointer = reinterpret_cast<uint8_t*>(debug_memalign(128, alloc_size));
177 ASSERT_TRUE(pointer != nullptr);
178 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
179 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
180 }
181 debug_free(pointer);
182
183 pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, alloc_size));
184 ASSERT_TRUE(pointer != nullptr);
185 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
186 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
187 }
188 memset(pointer, 0xff, alloc_size);
189 // Increase the size, verify the extra length is initialized to 0xeb,
190 // but the rest is 0xff.
191 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size * 2));
192 ASSERT_TRUE(pointer != nullptr);
193 for (size_t i = 0; i < alloc_size; i++) {
194 ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
195 }
196 for (size_t i = alloc_size; i < debug_malloc_usable_size(pointer); i++) {
197 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
198 }
199 memset(pointer, 0xff, debug_malloc_usable_size(pointer));
200 // Shrink the size and verify nothing changes.
201 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size));
202 ASSERT_TRUE(pointer != nullptr);
203 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
204 ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
205 }
206 // This should free the pointer.
207 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
208 ASSERT_TRUE(pointer == nullptr);
209
210 ASSERT_STREQ("", getFakeLogBuf().c_str());
211 std::string expected_log;
212 if (all_options) {
213 expected_log += android::base::StringPrintf(
214 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
215 SIGRTMAX - 19, getpid());
216 expected_log += android::base::StringPrintf(
217 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
218 SIGRTMAX - 17, getpid());
219 expected_log += android::base::StringPrintf(
220 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
221 SIGRTMAX - 18, getpid());
222 }
223 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
224 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
225 }
226
TEST_F(MallocDebugTest,fill_generic)227 TEST_F(MallocDebugTest, fill_generic) {
228 Init("verbose fill");
229 VerifyAllocCalls(false);
230 }
231
TEST_F(MallocDebugTest,fill_on_alloc_generic)232 TEST_F(MallocDebugTest, fill_on_alloc_generic) {
233 Init("verbose fill_on_alloc");
234 VerifyAllocCalls(false);
235 }
236
TEST_F(MallocDebugTest,fill_on_alloc_partial)237 TEST_F(MallocDebugTest, fill_on_alloc_partial) {
238 Init("fill_on_alloc=25");
239
240 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
241 ASSERT_TRUE(pointer != nullptr);
242 for (size_t i = 0; i < 25; i++) {
243 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
244 }
245 debug_free(pointer);
246
247 ASSERT_STREQ("", getFakeLogBuf().c_str());
248 ASSERT_STREQ("", getFakeLogPrint().c_str());
249 }
250
TEST_F(MallocDebugTest,verbose_only)251 TEST_F(MallocDebugTest, verbose_only) {
252 Init("verbose");
253
254 ASSERT_STREQ("", getFakeLogBuf().c_str());
255 ASSERT_STREQ("4 malloc_debug malloc_testing: malloc debug enabled\n", getFakeLogPrint().c_str());
256 }
257
TEST_F(MallocDebugTest,verbose_backtrace_enable_on_signal)258 TEST_F(MallocDebugTest, verbose_backtrace_enable_on_signal) {
259 Init("verbose backtrace_enable_on_signal");
260
261 std::string expected_log = android::base::StringPrintf(
262 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
263 SIGRTMAX - 19, getpid());
264 expected_log += android::base::StringPrintf(
265 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
266 SIGRTMAX - 17, getpid());
267 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
268 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
269 }
270
TEST_F(MallocDebugTest,verbose_backtrace)271 TEST_F(MallocDebugTest, verbose_backtrace) {
272 Init("verbose backtrace");
273
274 std::string expected_log = android::base::StringPrintf(
275 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
276 SIGRTMAX - 17, getpid());
277 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
278 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
279 }
280
TEST_F(MallocDebugTest,verbose_record_allocs)281 TEST_F(MallocDebugTest, verbose_record_allocs) {
282 Init("verbose record_allocs");
283
284 std::string expected_log = android::base::StringPrintf(
285 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
286 SIGRTMAX - 18, getpid());
287 expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
288 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
289 }
290
TEST_F(MallocDebugTest,fill_on_free)291 TEST_F(MallocDebugTest, fill_on_free) {
292 Init("fill_on_free free_track free_track_backtrace_num_frames=0");
293
294 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
295 ASSERT_TRUE(pointer != nullptr);
296 size_t usable_size = debug_malloc_usable_size(pointer);
297 memset(pointer, 0, usable_size);
298 debug_free(pointer);
299
300 for (size_t i = 0; i < usable_size; i++) {
301 ASSERT_EQ(0xef, pointer[i]) << "Failed at byte " << i;
302 }
303
304 ASSERT_STREQ("", getFakeLogBuf().c_str());
305 ASSERT_STREQ("", getFakeLogPrint().c_str());
306 }
307
TEST_F(MallocDebugTest,fill_on_free_partial)308 TEST_F(MallocDebugTest, fill_on_free_partial) {
309 Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
310
311 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
312 ASSERT_TRUE(pointer != nullptr);
313 size_t usable_size = debug_malloc_usable_size(pointer);
314 memset(pointer, 0, usable_size);
315 debug_free(pointer);
316
317 for (size_t i = 0; i < 30; i++) {
318 ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
319 }
320 for (size_t i = 30; i < usable_size; i++) {
321 ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
322 }
323
324 ASSERT_STREQ("", getFakeLogBuf().c_str());
325 ASSERT_STREQ("", getFakeLogPrint().c_str());
326 }
327
TEST_F(MallocDebugTest,free_track_partial)328 TEST_F(MallocDebugTest, free_track_partial) {
329 Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
330
331 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
332 ASSERT_TRUE(pointer != nullptr);
333 size_t usable_size = debug_malloc_usable_size(pointer);
334 memset(pointer, 0, usable_size);
335 debug_free(pointer);
336
337 for (size_t i = 0; i < 30; i++) {
338 ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
339 }
340 for (size_t i = 30; i < usable_size; i++) {
341 ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
342 }
343
344 debug_finalize();
345 initialized = false;
346
347 ASSERT_STREQ("", getFakeLogBuf().c_str());
348 ASSERT_STREQ("", getFakeLogPrint().c_str());
349 }
350
TEST_F(MallocDebugTest,all_options)351 TEST_F(MallocDebugTest, all_options) {
352 Init(
353 "guard backtrace backtrace_enable_on_signal fill expand_alloc free_track leak_track "
354 "record_allocs verify_pointers abort_on_error verbose");
355 VerifyAllocCalls(true);
356 }
357
TEST_F(MallocDebugTest,expand_alloc)358 TEST_F(MallocDebugTest, expand_alloc) {
359 Init("expand_alloc=1024");
360
361 void* pointer = debug_malloc(10);
362 ASSERT_TRUE(pointer != nullptr);
363 ASSERT_LE(1034U, debug_malloc_usable_size(pointer));
364 debug_free(pointer);
365
366 pointer = debug_calloc(1, 20);
367 ASSERT_TRUE(pointer != nullptr);
368 ASSERT_LE(1044U, debug_malloc_usable_size(pointer));
369 debug_free(pointer);
370
371 pointer = debug_memalign(128, 15);
372 ASSERT_TRUE(pointer != nullptr);
373 ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
374 debug_free(pointer);
375
376 pointer = debug_aligned_alloc(16, 16);
377 ASSERT_TRUE(pointer != nullptr);
378 ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
379 debug_free(pointer);
380
381 pointer = debug_realloc(nullptr, 30);
382 ASSERT_TRUE(pointer != nullptr);
383 ASSERT_LE(1054U, debug_malloc_usable_size(pointer));
384 pointer = debug_realloc(pointer, 100);
385 ASSERT_LE(1124U, debug_malloc_usable_size(pointer));
386 debug_free(pointer);
387
388 ASSERT_STREQ("", getFakeLogBuf().c_str());
389 ASSERT_STREQ("", getFakeLogPrint().c_str());
390 }
391
TEST_F(MallocDebugTest,front_guard)392 TEST_F(MallocDebugTest, front_guard) {
393 Init("front_guard=32");
394
395 // Create a buffer for doing comparisons.
396 std::vector<uint8_t> buffer(32);
397 memset(buffer.data(), 0xaa, buffer.size());
398
399 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
400 ASSERT_TRUE(pointer != nullptr);
401 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
402 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
403 memset(pointer, 0xff, 100);
404 debug_free(pointer);
405
406 // Loop through a bunch alignments.
407 for (size_t alignment = 1; alignment <= 256; alignment++) {
408 pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
409 ASSERT_TRUE(pointer != nullptr);
410 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
411 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
412 size_t alignment_mask = alignment - 1;
413 if (!powerof2(alignment)) {
414 alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
415 }
416 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask);
417 memset(pointer, 0xff, 100);
418 debug_free(pointer);
419 }
420
421 pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
422 ASSERT_TRUE(pointer != nullptr);
423 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
424 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
425 for (size_t i = 0; i < 100; i++) {
426 ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
427 }
428 debug_free(pointer);
429
430 pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
431 ASSERT_TRUE(pointer != nullptr);
432 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
433 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
434 memset(pointer, 0xff, 100);
435 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
436 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0)
437 << ShowDiffs(buffer.data(), &pointer[-buffer.size()], buffer.size());
438 memset(pointer, 0xff, 200);
439 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
440 ASSERT_TRUE(pointer == nullptr);
441
442 ASSERT_STREQ("", getFakeLogBuf().c_str());
443 ASSERT_STREQ("", getFakeLogPrint().c_str());
444 }
445
TEST_F(MallocDebugTest,realloc_memalign_memory)446 TEST_F(MallocDebugTest, realloc_memalign_memory) {
447 Init("rear_guard");
448
449 void* pointer = debug_memalign(1024, 100);
450 ASSERT_TRUE(pointer != nullptr);
451 memset(pointer, 0, 100);
452
453 pointer = debug_realloc(pointer, 1024);
454 ASSERT_TRUE(pointer != nullptr);
455 ASSERT_EQ(1024U, debug_malloc_usable_size(pointer));
456 memset(pointer, 0, 1024);
457 debug_free(pointer);
458
459 ASSERT_STREQ("", getFakeLogBuf().c_str());
460 ASSERT_STREQ("", getFakeLogPrint().c_str());
461 }
462
TEST_F(MallocDebugTest,front_guard_corrupted)463 TEST_F(MallocDebugTest, front_guard_corrupted) {
464 Init("front_guard=32");
465
466 backtrace_fake_add(std::vector<uintptr_t> {0x1, 0x2, 0x3});
467
468 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
469 ASSERT_TRUE(pointer != nullptr);
470 pointer[-32] = 0x00;
471 pointer[-15] = 0x02;
472 debug_free(pointer);
473
474 std::string expected_log(DIVIDER);
475 expected_log += android::base::StringPrintf(
476 "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED FRONT GUARD\n", pointer);
477 expected_log += "6 malloc_debug allocation[-32] = 0x00 (expected 0xaa)\n";
478 expected_log += "6 malloc_debug allocation[-15] = 0x02 (expected 0xaa)\n";
479 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
480 expected_log += "6 malloc_debug #00 pc 0x1\n";
481 expected_log += "6 malloc_debug #01 pc 0x2\n";
482 expected_log += "6 malloc_debug #02 pc 0x3\n";
483 expected_log += DIVIDER;
484 ASSERT_STREQ("", getFakeLogBuf().c_str());
485 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
486 }
487
TEST_F(MallocDebugTest,rear_guard)488 TEST_F(MallocDebugTest, rear_guard) {
489 Init("rear_guard=32");
490
491 // Create a buffer for doing comparisons.
492 std::vector<uint8_t> buffer(32);
493 memset(buffer.data(), 0xbb, buffer.size());
494
495 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
496 ASSERT_TRUE(pointer != nullptr);
497 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
498 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0)
499 << ShowDiffs(buffer.data(), &pointer[100], buffer.size());
500 memset(pointer, 0xff, 100);
501 debug_free(pointer);
502
503 // Loop through a bunch alignments.
504 for (size_t alignment = 1; alignment <= 256; alignment++) {
505 pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
506 ASSERT_TRUE(pointer != nullptr);
507 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
508 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0)
509 << ShowDiffs(buffer.data(), &pointer[100], buffer.size());
510 size_t alignment_mask = alignment - 1;
511 if (!powerof2(alignment)) {
512 alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
513 }
514 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask)
515 << "Failed at alignment " << alignment << " mask " << alignment_mask;
516 memset(pointer, 0xff, 100);
517 debug_free(pointer);
518 }
519
520 pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
521 ASSERT_TRUE(pointer != nullptr);
522 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
523 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0)
524 << ShowDiffs(buffer.data(), &pointer[100], buffer.size());
525 for (size_t i = 0; i < 100; i++) {
526 ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
527 }
528 debug_free(pointer);
529
530 pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
531 ASSERT_TRUE(pointer != nullptr);
532 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0)
533 << ShowDiffs(buffer.data(), &pointer[100], buffer.size());
534 memset(pointer, 0xff, 100);
535 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
536 ASSERT_TRUE(memcmp(buffer.data(), &pointer[200], buffer.size()) == 0)
537 << ShowDiffs(buffer.data(), &pointer[200], buffer.size());
538 for (size_t i = 0; i < 100; i++) {
539 ASSERT_EQ(0xff, pointer[i]) << "debug_realloc not copied byte at " << i;
540 }
541 memset(pointer, 0xff, 200);
542 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
543 ASSERT_TRUE(pointer == nullptr);
544
545 ASSERT_STREQ("", getFakeLogBuf().c_str());
546 ASSERT_STREQ("", getFakeLogPrint().c_str());
547 }
548
TEST_F(MallocDebugTest,rear_guard_corrupted)549 TEST_F(MallocDebugTest, rear_guard_corrupted) {
550 Init("rear_guard=32");
551
552 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
553
554 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
555 ASSERT_TRUE(pointer != nullptr);
556 pointer[130] = 0xbf;
557 pointer[131] = 0x00;
558 debug_free(pointer);
559
560 std::string expected_log(DIVIDER);
561 expected_log += android::base::StringPrintf(
562 "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
563 expected_log += "6 malloc_debug allocation[130] = 0xbf (expected 0xbb)\n";
564 expected_log += "6 malloc_debug allocation[131] = 0x00 (expected 0xbb)\n";
565 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
566 expected_log += "6 malloc_debug #00 pc 0x100\n";
567 expected_log += "6 malloc_debug #01 pc 0x200\n";
568 expected_log += "6 malloc_debug #02 pc 0x300\n";
569 expected_log += DIVIDER;
570
571 ASSERT_STREQ("", getFakeLogBuf().c_str());
572 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
573 }
574
TEST_F(MallocDebugTest,rear_guard_corrupted_after_realloc_shrink)575 TEST_F(MallocDebugTest, rear_guard_corrupted_after_realloc_shrink) {
576 Init("rear_guard=32");
577
578 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
579
580 void* pointer = debug_malloc(200);
581 ASSERT_TRUE(pointer != nullptr);
582 memset(pointer, 0, 200);
583
584 uint8_t* pointer_shrink = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 100));
585 pointer_shrink[130] = 0xbf;
586 pointer_shrink[131] = 0x00;
587 debug_free(pointer);
588
589 // When shrinking sizes, the same pointer should be returned.
590 ASSERT_EQ(pointer, pointer_shrink);
591
592 std::string expected_log(DIVIDER);
593 expected_log += android::base::StringPrintf(
594 "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
595 expected_log += "6 malloc_debug allocation[130] = 0xbf (expected 0xbb)\n";
596 expected_log += "6 malloc_debug allocation[131] = 0x00 (expected 0xbb)\n";
597 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
598 expected_log += "6 malloc_debug #00 pc 0x100\n";
599 expected_log += "6 malloc_debug #01 pc 0x200\n";
600 expected_log += "6 malloc_debug #02 pc 0x300\n";
601 expected_log += DIVIDER;
602
603 ASSERT_STREQ("", getFakeLogBuf().c_str());
604 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
605 }
606
TEST_F(MallocDebugTest,tag_corrupted)607 TEST_F(MallocDebugTest, tag_corrupted) {
608 Init("rear_guard=32");
609
610 backtrace_fake_add(std::vector<uintptr_t> {0xa, 0xb, 0xc});
611
612 backtrace_fake_add(std::vector<uintptr_t> {0xaa, 0xbb, 0xcc});
613
614 backtrace_fake_add(std::vector<uintptr_t> {0xaaa, 0xbbb, 0xccc});
615
616 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
617 ASSERT_TRUE(pointer != nullptr);
618 uint8_t saved = pointer[-get_tag_offset()];
619 pointer[-get_tag_offset()] = 0x00;
620 ASSERT_EQ(0U, debug_malloc_usable_size(pointer));
621 ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
622 debug_free(pointer);
623
624 // Fix the pointer and really free it.
625 pointer[-get_tag_offset()] = saved;
626 debug_free(pointer);
627
628 std::string expected_log(DIVIDER);
629 expected_log += android::base::StringPrintf(
630 "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (malloc_usable_size)\n",
631 pointer);
632 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
633 expected_log += "6 malloc_debug #00 pc 0xa\n";
634 expected_log += "6 malloc_debug #01 pc 0xb\n";
635 expected_log += "6 malloc_debug #02 pc 0xc\n";
636 expected_log += DIVIDER;
637
638 expected_log += DIVIDER;
639 expected_log += android::base::StringPrintf(
640 "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (realloc)\n",
641 pointer);
642 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
643 expected_log += "6 malloc_debug #00 pc 0xaa\n";
644 expected_log += "6 malloc_debug #01 pc 0xbb\n";
645 expected_log += "6 malloc_debug #02 pc 0xcc\n";
646 expected_log += DIVIDER;
647
648 expected_log += DIVIDER;
649 expected_log += android::base::StringPrintf(
650 "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (free)\n",
651 pointer);
652 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
653 expected_log += "6 malloc_debug #00 pc 0xaaa\n";
654 expected_log += "6 malloc_debug #01 pc 0xbbb\n";
655 expected_log += "6 malloc_debug #02 pc 0xccc\n";
656 expected_log += DIVIDER;
657
658 ASSERT_STREQ("", getFakeLogBuf().c_str());
659 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
660 }
661
TEST_F(MallocDebugTest,leak_track_no_frees)662 TEST_F(MallocDebugTest, leak_track_no_frees) {
663 Init("leak_track");
664
665 void* pointer1 = debug_malloc(200);
666 ASSERT_TRUE(pointer1 != nullptr);
667 memset(pointer1, 0, 200);
668
669 void* pointer2 = debug_malloc(128);
670 ASSERT_TRUE(pointer2 != nullptr);
671 memset(pointer2, 0, 128);
672
673 void* pointer3 = debug_malloc(1024);
674 ASSERT_TRUE(pointer3 != nullptr);
675 memset(pointer3, 0, 1024);
676
677 debug_finalize();
678 initialized = false;
679
680 ASSERT_STREQ("", getFakeLogBuf().c_str());
681 std::string expected_log = android::base::StringPrintf(
682 "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
683 pointer3);
684 expected_log += android::base::StringPrintf(
685 "6 malloc_debug +++ malloc_testing leaked block of size 200 at %p (leak 2 of 3)\n",
686 pointer1);
687 expected_log += android::base::StringPrintf(
688 "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 3 of 3)\n",
689 pointer2);
690 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
691 }
692
TEST_F(MallocDebugTest,leak_track_no_frees_with_backtrace)693 TEST_F(MallocDebugTest, leak_track_no_frees_with_backtrace) {
694 Init("leak_track backtrace");
695
696 backtrace_fake_add(std::vector<uintptr_t> {0x1000, 0x2000, 0x3000});
697
698 void* pointer1 = debug_malloc(100);
699 ASSERT_TRUE(pointer1 != nullptr);
700 memset(pointer1, 0, 100);
701
702 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000, 0xc000, 0xd000});
703
704 void* pointer2 = debug_malloc(128);
705 ASSERT_TRUE(pointer2 != nullptr);
706 memset(pointer2, 0, 128);
707
708 backtrace_fake_add(std::vector<uintptr_t> {0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
709
710 void* pointer3 = debug_malloc(1024);
711 ASSERT_TRUE(pointer3 != nullptr);
712 memset(pointer3, 0, 1024);
713
714 debug_finalize();
715 initialized = false;
716
717 ASSERT_STREQ("", getFakeLogBuf().c_str());
718 std::string expected_log = android::base::StringPrintf(
719 "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
720 pointer3);
721 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
722 expected_log += "6 malloc_debug #00 pc 0xfe000\n";
723 expected_log += "6 malloc_debug #01 pc 0xde000\n";
724 expected_log += "6 malloc_debug #02 pc 0xce000\n";
725 expected_log += "6 malloc_debug #03 pc 0xbe000\n";
726 expected_log += "6 malloc_debug #04 pc 0xae000\n";
727
728 expected_log += android::base::StringPrintf(
729 "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 2 of 3)\n",
730 pointer2);
731 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
732 expected_log += "6 malloc_debug #00 pc 0xa000\n";
733 expected_log += "6 malloc_debug #01 pc 0xb000\n";
734 expected_log += "6 malloc_debug #02 pc 0xc000\n";
735 expected_log += "6 malloc_debug #03 pc 0xd000\n";
736
737 expected_log += android::base::StringPrintf(
738 "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 3 of 3)\n",
739 pointer1);
740 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
741 expected_log += "6 malloc_debug #00 pc 0x1000\n";
742 expected_log += "6 malloc_debug #01 pc 0x2000\n";
743 expected_log += "6 malloc_debug #02 pc 0x3000\n";
744 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
745 }
746
TEST_F(MallocDebugTest,leak_track_frees)747 TEST_F(MallocDebugTest, leak_track_frees) {
748 Init("leak_track");
749
750 void* pointer1 = debug_malloc(390);
751 ASSERT_TRUE(pointer1 != nullptr);
752 memset(pointer1, 0, 390);
753 debug_free(pointer1);
754
755 pointer1 = debug_malloc(100);
756 ASSERT_TRUE(pointer1 != nullptr);
757 memset(pointer1, 0, 100);
758
759 void* pointer2 = debug_malloc(250);
760 ASSERT_TRUE(pointer2 != nullptr);
761 memset(pointer2, 0, 250);
762 debug_free(pointer2);
763
764 pointer2 = debug_malloc(450);
765 ASSERT_TRUE(pointer2 != nullptr);
766 memset(pointer2, 0, 450);
767
768 void* pointer3 = debug_malloc(999);
769 ASSERT_TRUE(pointer3 != nullptr);
770 memset(pointer3, 0, 999);
771 debug_free(pointer2);
772
773 debug_finalize();
774 initialized = false;
775
776 ASSERT_STREQ("", getFakeLogBuf().c_str());
777 std::string expected_log = android::base::StringPrintf(
778 "6 malloc_debug +++ malloc_testing leaked block of size 999 at %p (leak 1 of 2)\n",
779 pointer3);
780 expected_log += android::base::StringPrintf(
781 "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 2 of 2)\n",
782 pointer1);
783 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
784 }
785
TEST_F(MallocDebugTest,free_track)786 TEST_F(MallocDebugTest, free_track) {
787 Init("free_track=5 free_track_backtrace_num_frames=0");
788
789 void* pointers[10];
790 for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
791 pointers[i] = debug_malloc(100 + i);
792 ASSERT_TRUE(pointers[i] != nullptr);
793 memset(pointers[i], 0, 100 + i);
794 debug_free(pointers[i]);
795 }
796
797 // Large allocations (> 4096) to verify large allocation checks.
798 void* pointer = debug_malloc(8192);
799 ASSERT_TRUE(pointer != nullptr);
800 memset(pointer, 0, 8192);
801 debug_free(pointer);
802
803 pointer = debug_malloc(9000);
804 ASSERT_TRUE(pointer != nullptr);
805 memset(pointer, 0, 9000);
806 debug_free(pointer);
807
808 ASSERT_STREQ("", getFakeLogBuf().c_str());
809 ASSERT_STREQ("", getFakeLogPrint().c_str());
810 }
811
TEST_F(MallocDebugTest,free_track_use_after_free)812 TEST_F(MallocDebugTest, free_track_use_after_free) {
813 Init("free_track=5 free_track_backtrace_num_frames=0");
814
815 uint8_t* pointers[5];
816 for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
817 pointers[i] = reinterpret_cast<uint8_t*>(debug_malloc(100 + i));
818 ASSERT_TRUE(pointers[i] != nullptr);
819 memset(pointers[i], 0, 100 + i);
820 debug_free(pointers[i]);
821 }
822
823 // Stomp on the data.
824 pointers[0][20] = 0xaf;
825 pointers[0][99] = 0x12;
826
827 pointers[3][3] = 0x34;
828
829 // Large allocations (> 4096) to verify large allocation checks.
830 uint8_t* pointer1_large = reinterpret_cast<uint8_t*>(debug_malloc(8192));
831 ASSERT_TRUE(pointer1_large != nullptr);
832 memset(pointer1_large, 0, 8192);
833 debug_free(pointer1_large);
834
835 pointer1_large[4095] = 0x90;
836 pointer1_large[4100] = 0x56;
837 pointer1_large[8191] = 0x89;
838
839 uint8_t* pointer2_large = reinterpret_cast<uint8_t*>(debug_malloc(9000));
840 ASSERT_TRUE(pointer2_large != nullptr);
841 memset(pointer2_large, 0, 9000);
842 debug_free(pointer2_large);
843
844 pointer2_large[8200] = 0x78;
845
846 // Do a bunch of alloc and free to verify the above frees are checked.
847 for (size_t i = 0; i < 10; i++) {
848 void* flush_pointer = debug_malloc(100+i);
849 ASSERT_TRUE(flush_pointer != nullptr);
850 memset(flush_pointer, 0, 100 + i);
851 debug_free(flush_pointer);
852 }
853
854 ASSERT_STREQ("", getFakeLogBuf().c_str());
855 std::string expected_log(DIVIDER);
856 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[0]);
857 expected_log += "6 malloc_debug allocation[20] = 0xaf (expected 0xef)\n";
858 expected_log += "6 malloc_debug allocation[99] = 0x12 (expected 0xef)\n";
859 expected_log += DIVIDER;
860 expected_log += DIVIDER;
861 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[3]);
862 expected_log += "6 malloc_debug allocation[3] = 0x34 (expected 0xef)\n";
863 expected_log += DIVIDER;
864 expected_log += DIVIDER;
865 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer1_large);
866 expected_log += "6 malloc_debug allocation[4095] = 0x90 (expected 0xef)\n";
867 expected_log += "6 malloc_debug allocation[4100] = 0x56 (expected 0xef)\n";
868 expected_log += "6 malloc_debug allocation[8191] = 0x89 (expected 0xef)\n";
869 expected_log += DIVIDER;
870 expected_log += DIVIDER;
871 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer2_large);
872 expected_log += "6 malloc_debug allocation[8200] = 0x78 (expected 0xef)\n";
873 expected_log += DIVIDER;
874 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
875 }
876
TEST_F(MallocDebugTest,free_track_use_after_free_finalize)877 TEST_F(MallocDebugTest, free_track_use_after_free_finalize) {
878 Init("free_track=100 free_track_backtrace_num_frames=0");
879
880 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
881 ASSERT_TRUE(pointer != nullptr);
882 memset(pointer, 0, 100);
883 debug_free(pointer);
884
885 pointer[56] = 0x91;
886
887 ASSERT_STREQ("", getFakeLogBuf().c_str());
888 ASSERT_STREQ("", getFakeLogPrint().c_str());
889
890 debug_finalize();
891 initialized = false;
892
893 ASSERT_STREQ("", getFakeLogBuf().c_str());
894 std::string expected_log(DIVIDER);
895 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
896 expected_log += "6 malloc_debug allocation[56] = 0x91 (expected 0xef)\n";
897 expected_log += DIVIDER;
898 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
899 }
900
TEST_F(MallocDebugTest,free_track_use_after_free_with_backtrace)901 TEST_F(MallocDebugTest, free_track_use_after_free_with_backtrace) {
902 Init("free_track=100 rear_guard");
903
904 // Free backtrace.
905 backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
906
907 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(200));
908 ASSERT_TRUE(pointer != nullptr);
909 memset(pointer, 0, 200);
910 debug_free(pointer);
911
912 pointer[101] = 0xab;
913
914 ASSERT_STREQ("", getFakeLogBuf().c_str());
915 ASSERT_STREQ("", getFakeLogPrint().c_str());
916
917 debug_finalize();
918 initialized = false;
919
920 ASSERT_STREQ("", getFakeLogBuf().c_str());
921 std::string expected_log(DIVIDER);
922 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
923 expected_log += "6 malloc_debug allocation[101] = 0xab (expected 0xef)\n";
924 expected_log += "6 malloc_debug Backtrace at time of free:\n";
925 expected_log += "6 malloc_debug #00 pc 0xfa\n";
926 expected_log += "6 malloc_debug #01 pc 0xeb\n";
927 expected_log += "6 malloc_debug #02 pc 0xdc\n";
928 expected_log += DIVIDER;
929 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
930 }
931
TEST_F(MallocDebugTest,free_track_use_after_free_call_realloc)932 TEST_F(MallocDebugTest, free_track_use_after_free_call_realloc) {
933 Init("free_track=100 rear_guard");
934
935 // Free backtrace.
936 backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
937 // Backtrace at realloc.
938 backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
939
940 void* pointer = debug_malloc(200);
941 ASSERT_TRUE(pointer != nullptr);
942 memset(pointer, 0, 200);
943 debug_free(pointer);
944
945 // Choose a size that should not trigger a realloc to verify tag is
946 // verified early.
947 ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
948
949 ASSERT_STREQ("", getFakeLogBuf().c_str());
950 std::string expected_log(DIVIDER);
951 expected_log += android::base::StringPrintf(
952 "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (realloc)\n", pointer);
953 expected_log += "6 malloc_debug Backtrace of original free:\n";
954 expected_log += "6 malloc_debug #00 pc 0xfa\n";
955 expected_log += "6 malloc_debug #01 pc 0xeb\n";
956 expected_log += "6 malloc_debug #02 pc 0xdc\n";
957 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
958 expected_log += "6 malloc_debug #00 pc 0x12\n";
959 expected_log += "6 malloc_debug #01 pc 0x22\n";
960 expected_log += "6 malloc_debug #02 pc 0x32\n";
961 expected_log += "6 malloc_debug #03 pc 0x42\n";
962 expected_log += DIVIDER;
963 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
964 }
965
TEST_F(MallocDebugTest,free_track_use_after_free_call_free)966 TEST_F(MallocDebugTest, free_track_use_after_free_call_free) {
967 Init("free_track=100 rear_guard");
968
969 // Free backtrace.
970 backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
971 // Backtrace at second free.
972 backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
973
974 void* pointer = debug_malloc(200);
975 ASSERT_TRUE(pointer != nullptr);
976 memset(pointer, 0, 200);
977 debug_free(pointer);
978
979 debug_free(pointer);
980
981 ASSERT_STREQ("", getFakeLogBuf().c_str());
982 std::string expected_log(DIVIDER);
983 expected_log += android::base::StringPrintf(
984 "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (free)\n", pointer);
985 expected_log += "6 malloc_debug Backtrace of original free:\n";
986 expected_log += "6 malloc_debug #00 pc 0xfa\n";
987 expected_log += "6 malloc_debug #01 pc 0xeb\n";
988 expected_log += "6 malloc_debug #02 pc 0xdc\n";
989 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
990 expected_log += "6 malloc_debug #00 pc 0x12\n";
991 expected_log += "6 malloc_debug #01 pc 0x22\n";
992 expected_log += "6 malloc_debug #02 pc 0x32\n";
993 expected_log += "6 malloc_debug #03 pc 0x42\n";
994 expected_log += DIVIDER;
995 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
996 }
997
TEST_F(MallocDebugTest,free_track_header_tag_corrupted)998 TEST_F(MallocDebugTest, free_track_header_tag_corrupted) {
999 Init("free_track=100 free_track_backtrace_num_frames=0 rear_guard");
1000
1001 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
1002 ASSERT_TRUE(pointer != nullptr);
1003 memset(pointer, 0, 100);
1004 debug_free(pointer);
1005
1006 pointer[-get_tag_offset()] = 0x00;
1007
1008 ASSERT_STREQ("", getFakeLogBuf().c_str());
1009 ASSERT_STREQ("", getFakeLogPrint().c_str());
1010
1011 debug_finalize();
1012 initialized = false;
1013
1014 ASSERT_STREQ("", getFakeLogBuf().c_str());
1015 std::string expected_log(DIVIDER);
1016 expected_log += android::base::StringPrintf(
1017 "6 malloc_debug +++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x1cc7dc00 AFTER FREE\n",
1018 pointer);
1019 expected_log += DIVIDER;
1020 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1021 }
1022
TEST_F(MallocDebugTest,free_track_multiple_thread)1023 TEST_F(MallocDebugTest, free_track_multiple_thread) {
1024 Init("free_track=10 free_track_backtrace_num_frames=0");
1025
1026 std::vector<std::thread*> threads(1000);
1027 for (size_t i = 0; i < threads.size(); i++) {
1028 threads[i] = new std::thread([](){
1029 for (size_t j = 0; j < 100; j++) {
1030 void* mem = debug_malloc(100);
1031 write(0, mem, 0);
1032 debug_free(mem);
1033 }
1034 });
1035 }
1036 for (size_t i = 0; i < threads.size(); i++) {
1037 threads[i]->join();
1038 delete threads[i];
1039 }
1040
1041 ASSERT_STREQ("", getFakeLogBuf().c_str());
1042 ASSERT_STREQ("", getFakeLogPrint().c_str());
1043 }
1044
TEST_F(MallocDebugTest,free_track_pointer_modified_after_free)1045 TEST_F(MallocDebugTest, free_track_pointer_modified_after_free) {
1046 Init("free_track=4 fill_on_free=2 free_track_backtrace_num_frames=0");
1047
1048 void* pointers[5];
1049 for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
1050 pointers[i] = debug_malloc(100);
1051 ASSERT_TRUE(pointers[i] != nullptr);
1052 memset(pointers[i], 0, 100);
1053 }
1054
1055 debug_free(pointers[0]);
1056
1057 // overwrite the whole pointer, only expect errors on the fill bytes we check.
1058 memset(pointers[0], 0x20, 100);
1059
1060 for (size_t i = 1; i < sizeof(pointers) / sizeof(void*); i++) {
1061 debug_free(pointers[i]);
1062 }
1063
1064 std::string expected_log(DIVIDER);
1065 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n",
1066 pointers[0]);
1067 expected_log += "6 malloc_debug allocation[0] = 0x20 (expected 0xef)\n";
1068 expected_log += "6 malloc_debug allocation[1] = 0x20 (expected 0xef)\n";
1069 expected_log += DIVIDER;
1070 ASSERT_STREQ("", getFakeLogBuf().c_str());
1071 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1072 }
1073
TEST_F(MallocDebugTest,get_malloc_leak_info_invalid)1074 TEST_F(MallocDebugTest, get_malloc_leak_info_invalid) {
1075 Init("fill");
1076
1077 uint8_t* info;
1078 size_t overall_size;
1079 size_t info_size;
1080 size_t total_memory;
1081 size_t backtrace_size;
1082
1083 std::string expected_log("6 malloc_debug get_malloc_leak_info: At least one invalid parameter.\n");
1084
1085 debug_get_malloc_leak_info(nullptr, &overall_size, &info_size, &total_memory, &backtrace_size);
1086 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1087
1088 resetLogs();
1089 debug_get_malloc_leak_info(&info, nullptr, &info_size, &total_memory, &backtrace_size);
1090 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1091
1092 resetLogs();
1093 debug_get_malloc_leak_info(&info, &overall_size, nullptr, &total_memory, &backtrace_size);
1094 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1095
1096 resetLogs();
1097 debug_get_malloc_leak_info(&info, &overall_size, &info_size, nullptr, &backtrace_size);
1098 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1099
1100 resetLogs();
1101 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, nullptr);
1102 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1103 }
1104
TEST_F(MallocDebugTest,get_malloc_leak_info_not_enabled)1105 TEST_F(MallocDebugTest, get_malloc_leak_info_not_enabled) {
1106 Init("fill");
1107
1108 uint8_t* info;
1109 size_t overall_size;
1110 size_t info_size;
1111 size_t total_memory;
1112 size_t backtrace_size;
1113
1114 ASSERT_STREQ("", getFakeLogBuf().c_str());
1115 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1116 std::string expected_log(
1117 "6 malloc_debug get_malloc_leak_info: Allocations not being tracked, to enable "
1118 "set the option 'backtrace'.\n");
1119 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1120 }
1121
1122 struct InfoEntry {
1123 size_t size;
1124 size_t num_allocations;
1125 uintptr_t frames[0];
1126 } __attribute__((packed));
1127
TEST_F(MallocDebugTest,get_malloc_leak_info_empty)1128 TEST_F(MallocDebugTest, get_malloc_leak_info_empty) {
1129 Init("backtrace");
1130
1131 uint8_t* info;
1132 size_t overall_size;
1133 size_t info_size;
1134 size_t total_memory;
1135 size_t backtrace_size;
1136
1137 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1138 ASSERT_TRUE(info == nullptr);
1139 ASSERT_EQ(0U, overall_size);
1140 ASSERT_EQ(0U, info_size);
1141 ASSERT_EQ(0U, total_memory);
1142 ASSERT_EQ(0U, backtrace_size);
1143
1144 ASSERT_STREQ("", getFakeLogBuf().c_str());
1145 ASSERT_STREQ("", getFakeLogPrint().c_str());
1146 }
1147
TEST_F(MallocDebugTest,get_malloc_leak_info_single)1148 TEST_F(MallocDebugTest, get_malloc_leak_info_single) {
1149 Init("backtrace");
1150
1151 // Create the expected info buffer.
1152 size_t individual_size = GetInfoEntrySize(16);
1153 std::vector<uint8_t> expected_info(individual_size);
1154 memset(expected_info.data(), 0, individual_size);
1155
1156 InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
1157 entry->size = 200;
1158 entry->num_allocations = 1;
1159 entry->frames[0] = 0xf;
1160 entry->frames[1] = 0xe;
1161 entry->frames[2] = 0xd;
1162
1163 backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd});
1164
1165 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(entry->size));
1166 ASSERT_TRUE(pointer != nullptr);
1167 memset(pointer, 0, entry->size);
1168
1169 uint8_t* info;
1170 size_t overall_size;
1171 size_t info_size;
1172 size_t total_memory;
1173 size_t backtrace_size;
1174
1175 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1176 ASSERT_TRUE(info != nullptr);
1177 ASSERT_EQ(individual_size, overall_size);
1178 ASSERT_EQ(individual_size, info_size);
1179 ASSERT_EQ(200U, total_memory);
1180 ASSERT_EQ(16U, backtrace_size);
1181 ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0)
1182 << ShowDiffs(expected_info.data(), info, overall_size);
1183
1184 debug_free_malloc_leak_info(info);
1185
1186 debug_free(pointer);
1187
1188 ASSERT_STREQ("", getFakeLogBuf().c_str());
1189 ASSERT_STREQ("", getFakeLogPrint().c_str());
1190 }
1191
TEST_F(MallocDebugTest,get_malloc_leak_info_multi)1192 TEST_F(MallocDebugTest, get_malloc_leak_info_multi) {
1193 Init("backtrace=16");
1194
1195 // Create the expected info buffer.
1196 size_t individual_size = GetInfoEntrySize(16);
1197 std::vector<uint8_t> expected_info(individual_size * 3);
1198 memset(expected_info.data(), 0, individual_size * 3);
1199
1200 InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
1201 InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
1202 reinterpret_cast<uintptr_t>(entry0) + individual_size);
1203 InfoEntry* entry2 = reinterpret_cast<InfoEntry*>(
1204 reinterpret_cast<uintptr_t>(entry1) + individual_size);
1205
1206 // These values will be in the reverse order that we create.
1207 entry2->size = 500;
1208 entry2->num_allocations = 1;
1209 entry2->frames[0] = 0xf;
1210 entry2->frames[1] = 0xe;
1211 entry2->frames[2] = 0xd;
1212 entry2->frames[3] = 0xc;
1213
1214 backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
1215
1216 uint8_t* pointers[3];
1217
1218 pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry2->size));
1219 ASSERT_TRUE(pointers[0] != nullptr);
1220 memset(pointers[0], 0, entry2->size);
1221
1222 entry1->size = 4100;
1223 entry1->num_allocations = 1;
1224 for (size_t i = 0; i < 16; i++) {
1225 entry1->frames[i] = 0xbc000 + i;
1226 }
1227
1228 backtrace_fake_add(
1229 std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
1230 0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
1231 0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
1232
1233 pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
1234 ASSERT_TRUE(pointers[1] != nullptr);
1235 memset(pointers[1], 0, entry1->size);
1236
1237 entry0->size = 9000;
1238 entry0->num_allocations = 1;
1239
1240 entry0->frames[0] = 0x104;
1241 backtrace_fake_add(std::vector<uintptr_t> {0x104});
1242
1243 pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
1244 ASSERT_TRUE(pointers[2] != nullptr);
1245 memset(pointers[2], 0, entry0->size);
1246
1247 uint8_t* info;
1248 size_t overall_size;
1249 size_t info_size;
1250 size_t total_memory;
1251 size_t backtrace_size;
1252
1253 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1254 ASSERT_TRUE(info != nullptr);
1255 ASSERT_EQ(individual_size * 3, overall_size);
1256 ASSERT_EQ(individual_size, info_size);
1257 ASSERT_EQ(500U + 4100U + 9000U, total_memory);
1258 ASSERT_EQ(16U, backtrace_size);
1259 ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0)
1260 << ShowDiffs(expected_info.data(), info, overall_size);
1261
1262 debug_free_malloc_leak_info(info);
1263
1264 debug_free(pointers[0]);
1265 debug_free(pointers[1]);
1266 debug_free(pointers[2]);
1267
1268 ASSERT_STREQ("", getFakeLogBuf().c_str());
1269 ASSERT_STREQ("", getFakeLogPrint().c_str());
1270 }
1271
TEST_F(MallocDebugTest,get_malloc_backtrace_with_header)1272 TEST_F(MallocDebugTest, get_malloc_backtrace_with_header) {
1273 Init("backtrace=16 guard");
1274
1275 void* pointer = debug_malloc(100);
1276 ASSERT_TRUE(pointer != nullptr);
1277 memset(pointer, 0, 100);
1278 EXPECT_EQ(100U, debug_malloc_usable_size(pointer));
1279
1280 uint8_t* info;
1281 size_t overall_size;
1282 size_t info_size;
1283 size_t total_memory;
1284 size_t backtrace_size;
1285
1286 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1287 EXPECT_TRUE(info != nullptr);
1288 EXPECT_EQ(GetInfoEntrySize(16), overall_size);
1289 EXPECT_EQ(GetInfoEntrySize(16), info_size);
1290 EXPECT_EQ(100U, total_memory);
1291 EXPECT_EQ(16U, backtrace_size);
1292 debug_free_malloc_leak_info(info);
1293
1294 debug_free(pointer);
1295
1296 // There should be no pointers that have leaked.
1297 debug_finalize();
1298 initialized = false;
1299
1300 ASSERT_STREQ("", getFakeLogBuf().c_str());
1301 ASSERT_STREQ("", getFakeLogPrint().c_str());
1302 }
1303
SanitizeHeapData(const std::string & data)1304 static std::string SanitizeHeapData(const std::string& data) {
1305 // Remove the map data since it's not consistent.
1306 std::string sanitized;
1307 bool skip_map_data = false;
1308 bool map_data_found = false;
1309 for (auto& line : android::base::Split(data, "\n")) {
1310 if (skip_map_data) {
1311 if (line == "END") {
1312 if (map_data_found) {
1313 sanitized += "MAP_DATA\n";
1314 map_data_found = false;
1315 }
1316 skip_map_data = false;
1317 } else {
1318 map_data_found = true;
1319 continue;
1320 }
1321 }
1322
1323 if (android::base::StartsWith(line, "Build fingerprint:")) {
1324 sanitized += "Build fingerprint: ''\n";
1325 } else {
1326 if (line == "MAPS") {
1327 skip_map_data = true;
1328 }
1329 sanitized += line + '\n';
1330 }
1331 }
1332 return sanitized;
1333 }
1334
BacktraceDumpOnSignal(bool trigger_with_alloc)1335 void MallocDebugTest::BacktraceDumpOnSignal(bool trigger_with_alloc) {
1336 Init("backtrace=4");
1337
1338 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
1339 backtrace_fake_add(std::vector<uintptr_t> {0x300, 0x400});
1340 backtrace_fake_add(std::vector<uintptr_t> {0x500, 0x600});
1341
1342 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000});
1343 backtrace_fake_add(std::vector<uintptr_t> {0xa100, 0xb200});
1344 backtrace_fake_add(std::vector<uintptr_t> {0xa300, 0xb300});
1345
1346 std::vector<void*> pointers;
1347 zygote_child = true;
1348 pointers.push_back(debug_malloc(100));
1349 ASSERT_TRUE(pointers.back() != nullptr);
1350 pointers.push_back(debug_malloc(40));
1351 ASSERT_TRUE(pointers.back() != nullptr);
1352 pointers.push_back(debug_malloc(200));
1353 ASSERT_TRUE(pointers.back() != nullptr);
1354
1355 zygote_child = false;
1356 pointers.push_back(debug_malloc(10));
1357 ASSERT_TRUE(pointers.back() != nullptr);
1358 pointers.push_back(debug_malloc(50));
1359 ASSERT_TRUE(pointers.back() != nullptr);
1360 pointers.push_back(debug_malloc(5));
1361 ASSERT_TRUE(pointers.back() != nullptr);
1362
1363 // Dump all of the data accumulated so far.
1364 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 17) == 0);
1365 sleep(1);
1366
1367 // This triggers the dumping.
1368 if (trigger_with_alloc) {
1369 pointers.push_back(debug_malloc(23));
1370 ASSERT_TRUE(pointers.back() != nullptr);
1371 } else {
1372 debug_free(pointers.back());
1373 pointers.pop_back();
1374 }
1375
1376 for (auto* pointer : pointers) {
1377 debug_free(pointer);
1378 }
1379
1380 // Read all of the contents.
1381 std::string actual;
1382 std::string name = android::base::StringPrintf("%s.%d.txt", BACKTRACE_DUMP_PREFIX, getpid());
1383 ASSERT_TRUE(android::base::ReadFileToString(name, &actual));
1384 ASSERT_EQ(0, unlink(name.c_str()));
1385
1386 std::string sanitized(SanitizeHeapData(actual));
1387
1388 std::string expected =
1389 R"(Android Native Heap Dump v1.2
1390
1391 Build fingerprint: ''
1392
1393 Total memory: 405
1394 Allocation records: 6
1395 Backtrace size: 4
1396
1397 z 0 sz 50 num 1 bt a100 b200
1398 z 0 sz 10 num 1 bt a000 b000
1399 z 0 sz 5 num 1 bt a300 b300
1400 z 1 sz 200 num 1 bt 500 600
1401 z 1 sz 100 num 1 bt 100 200
1402 z 1 sz 40 num 1 bt 300 400
1403 MAPS
1404 MAP_DATA
1405 END
1406
1407 )";
1408 ASSERT_STREQ(expected.c_str(), sanitized.c_str()) << "Actual data: \n" << actual;
1409
1410 ASSERT_STREQ("", getFakeLogBuf().c_str());
1411 std::string expected_log = android::base::StringPrintf(
1412 "6 malloc_debug Dumping to file: /data/local/tmp/backtrace_heap.%d.txt\n\n", getpid());
1413 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1414 }
1415
TEST_F(MallocDebugTest,backtrace_dump_on_signal_by_malloc)1416 TEST_F(MallocDebugTest, backtrace_dump_on_signal_by_malloc) {
1417 BacktraceDumpOnSignal(true);
1418 }
1419
TEST_F(MallocDebugTest,backtrace_dump_on_signal_by_free)1420 TEST_F(MallocDebugTest, backtrace_dump_on_signal_by_free) {
1421 BacktraceDumpOnSignal(false);
1422 }
1423
TEST_F(MallocDebugTest,backtrace_dump_on_exit)1424 TEST_F(MallocDebugTest, backtrace_dump_on_exit) {
1425 pid_t pid;
1426 if ((pid = fork()) == 0) {
1427 Init("backtrace=4 backtrace_dump_on_exit");
1428 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
1429 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000});
1430 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000, 0xc000});
1431
1432 std::vector<void*> pointers;
1433 pointers.push_back(debug_malloc(300));
1434 pointers.push_back(debug_malloc(400));
1435 pointers.push_back(debug_malloc(500));
1436
1437 // Call the exit function manually.
1438 debug_finalize();
1439 exit(0);
1440 }
1441 ASSERT_NE(-1, pid);
1442 ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0)));
1443
1444 // Read all of the contents.
1445 std::string actual;
1446 std::string name = android::base::StringPrintf("%s.%d.exit.txt", BACKTRACE_DUMP_PREFIX, pid);
1447 ASSERT_TRUE(android::base::ReadFileToString(name, &actual));
1448 ASSERT_EQ(0, unlink(name.c_str()));
1449
1450 std::string sanitized(SanitizeHeapData(actual));
1451
1452 std::string expected =
1453 R"(Android Native Heap Dump v1.2
1454
1455 Build fingerprint: ''
1456
1457 Total memory: 1200
1458 Allocation records: 3
1459 Backtrace size: 4
1460
1461 z 0 sz 500 num 1 bt a000 b000 c000
1462 z 0 sz 400 num 1 bt a000 b000
1463 z 0 sz 300 num 1 bt 100 200
1464 MAPS
1465 MAP_DATA
1466 END
1467
1468 )";
1469 ASSERT_STREQ(expected.c_str(), sanitized.c_str()) << "Actual data: \n" << actual;
1470
1471 ASSERT_STREQ("", getFakeLogBuf().c_str());
1472 ASSERT_STREQ("", getFakeLogPrint().c_str());
1473 }
1474
TEST_F(MallocDebugTest,backtrace_dump_on_exit_shared_backtrace)1475 TEST_F(MallocDebugTest, backtrace_dump_on_exit_shared_backtrace) {
1476 pid_t pid;
1477 if ((pid = fork()) == 0) {
1478 Init("backtrace=4 backtrace_dump_on_exit");
1479 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
1480 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000, 0xc000});
1481 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
1482
1483 std::vector<void*> pointers;
1484 pointers.push_back(debug_malloc(300));
1485 pointers.push_back(debug_malloc(400));
1486 pointers.push_back(debug_malloc(300));
1487
1488 // Call the exit function manually.
1489 debug_finalize();
1490 exit(0);
1491 }
1492 ASSERT_NE(-1, pid);
1493 ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0)));
1494
1495 // Read all of the contents.
1496 std::string actual;
1497 std::string name = android::base::StringPrintf("%s.%d.exit.txt", BACKTRACE_DUMP_PREFIX, pid);
1498 ASSERT_TRUE(android::base::ReadFileToString(name, &actual));
1499 ASSERT_EQ(0, unlink(name.c_str()));
1500
1501 std::string sanitized(SanitizeHeapData(actual));
1502
1503 std::string expected =
1504 R"(Android Native Heap Dump v1.2
1505
1506 Build fingerprint: ''
1507
1508 Total memory: 1000
1509 Allocation records: 2
1510 Backtrace size: 4
1511
1512 z 0 sz 400 num 1 bt a000 b000 c000
1513 z 0 sz 300 num 2 bt 100 200
1514 MAPS
1515 MAP_DATA
1516 END
1517
1518 )";
1519 ASSERT_STREQ(expected.c_str(), sanitized.c_str()) << "Actual data: \n" << actual;
1520
1521 ASSERT_STREQ("", getFakeLogBuf().c_str());
1522 ASSERT_STREQ("", getFakeLogPrint().c_str());
1523 }
1524
TEST_F(MallocDebugTest,backtrace_full_dump_on_exit)1525 TEST_F(MallocDebugTest, backtrace_full_dump_on_exit) {
1526 pid_t pid;
1527 if ((pid = fork()) == 0) {
1528 Init("backtrace=4 backtrace_full backtrace_dump_on_exit");
1529 BacktraceUnwindFake(
1530 std::vector<unwindstack::LocalFrameData>{{nullptr, 0x1100, 0x100, "fake1", 10},
1531 {nullptr, 0x1200, 0x200, "fake2", 20}});
1532 unwindstack::MapInfo map_info{nullptr, 0x10000, 0x20000, 0, PROT_READ | PROT_EXEC, "/data/fake.so"};
1533 BacktraceUnwindFake(
1534 std::vector<unwindstack::LocalFrameData>{{&map_info, 0x1a000, 0xa000, "level1", 0},
1535 {&map_info, 0x1b000, 0xb000, "level2", 10}});
1536 BacktraceUnwindFake(
1537 std::vector<unwindstack::LocalFrameData>{{nullptr, 0x1a000, 0xa000, "func1", 0},
1538 {nullptr, 0x1b000, 0xb000, "func2", 10},
1539 {nullptr, 0x1c000, 0xc000, "", 30}});
1540
1541 std::vector<void*> pointers;
1542 pointers.push_back(debug_malloc(300));
1543 pointers.push_back(debug_malloc(400));
1544 pointers.push_back(debug_malloc(500));
1545
1546 // Call the exit function manually.
1547 debug_finalize();
1548 exit(0);
1549 }
1550 ASSERT_NE(-1, pid);
1551 ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0)));
1552
1553 // Read all of the contents.
1554 std::string actual;
1555 std::string name = android::base::StringPrintf("%s.%d.exit.txt", BACKTRACE_DUMP_PREFIX, pid);
1556 ASSERT_TRUE(android::base::ReadFileToString(name, &actual));
1557 ASSERT_EQ(0, unlink(name.c_str()));
1558
1559 std::string sanitized(SanitizeHeapData(actual));
1560
1561 std::string expected =
1562 R"(Android Native Heap Dump v1.2
1563
1564 Build fingerprint: ''
1565
1566 Total memory: 1200
1567 Allocation records: 3
1568 Backtrace size: 4
1569
1570 z 0 sz 500 num 1 bt 1a000 1b000 1c000
1571 bt_info {"" a000 "func1" 0} {"" b000 "func2" a} {"" c000 "" 0}
1572 z 0 sz 400 num 1 bt 1a000 1b000
1573 bt_info {"/data/fake.so" a000 "level1" 0} {"/data/fake.so" b000 "level2" a}
1574 z 0 sz 300 num 1 bt 1100 1200
1575 bt_info {"" 100 "fake1" a} {"" 200 "fake2" 14}
1576 MAPS
1577 MAP_DATA
1578 END
1579
1580 )";
1581 ASSERT_STREQ(expected.c_str(), sanitized.c_str()) << "Actual data: \n" << actual;
1582
1583 ASSERT_STREQ("", getFakeLogBuf().c_str());
1584 ASSERT_STREQ("", getFakeLogPrint().c_str());
1585 }
1586
TEST_F(MallocDebugTest,realloc_usable_size)1587 TEST_F(MallocDebugTest, realloc_usable_size) {
1588 Init("front_guard");
1589
1590 // Verify that if the usable size > size of alloc, that realloc
1591 // copies the bytes in the usable size not just the size.
1592 // This assumes that an allocation of size 1 returns usable size > 1.
1593 // If this isn't true, this test is not going to do anything.
1594 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(1));
1595 ASSERT_TRUE(pointer != nullptr);
1596 size_t usable_size = debug_malloc_usable_size(pointer);
1597 memset(pointer, 0xaa, usable_size);
1598 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, usable_size + 10));
1599 ASSERT_TRUE(pointer != nullptr);
1600 ASSERT_LE(usable_size + 10, debug_malloc_usable_size(pointer));
1601 for (size_t i = 0; i < usable_size; i++) {
1602 ASSERT_EQ(0xaa, pointer[i]) << "Failed compare at byte " << i;
1603 }
1604 debug_free(pointer);
1605
1606 ASSERT_STREQ("", getFakeLogBuf().c_str());
1607 ASSERT_STREQ("", getFakeLogPrint().c_str());
1608 }
1609
TEST_F(MallocDebugTest,backtrace_enable_on_signal)1610 TEST_F(MallocDebugTest, backtrace_enable_on_signal) {
1611 Init("backtrace_enable_on_signal=20");
1612
1613 size_t individual_size = GetInfoEntrySize(20);
1614
1615 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1616 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300, 0x400});
1617 backtrace_fake_add(std::vector<uintptr_t> {0x500, 0xa00, 0xb00});
1618
1619 // First allocation should not actually attempt to get the backtrace.
1620 void* pointer = debug_malloc(10);
1621 ASSERT_TRUE(pointer != nullptr);
1622
1623 uint8_t* info;
1624 size_t overall_size;
1625 size_t info_size;
1626 size_t total_memory;
1627 size_t backtrace_size;
1628
1629 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1630 ASSERT_TRUE(info == nullptr);
1631 ASSERT_EQ(0U, overall_size);
1632 ASSERT_EQ(0U, info_size);
1633 ASSERT_EQ(0U, total_memory);
1634 ASSERT_EQ(0U, backtrace_size);
1635 debug_free(pointer);
1636
1637 debug_free_malloc_leak_info(info);
1638
1639 // Send the signal to enable.
1640 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 19) == 0);
1641 sleep(1);
1642
1643 pointer = debug_malloc(100);
1644 ASSERT_TRUE(pointer != nullptr);
1645
1646 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1647 ASSERT_TRUE(info != nullptr);
1648 ASSERT_EQ(individual_size, overall_size);
1649 ASSERT_EQ(individual_size, info_size);
1650 ASSERT_EQ(100U, total_memory);
1651 ASSERT_EQ(20U, backtrace_size);
1652 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1653 ASSERT_EQ(0xbc000U, ips[0]);
1654 ASSERT_EQ(0xecd00U, ips[1]);
1655 ASSERT_EQ(0x12000U, ips[2]);
1656 for (size_t i = 3; i < 20; i++) {
1657 ASSERT_EQ(0U, ips[i]);
1658 }
1659
1660 debug_free(pointer);
1661
1662 debug_free_malloc_leak_info(info);
1663
1664 // Send the signal to disable.
1665 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 19) == 0);
1666 sleep(1);
1667
1668 pointer = debug_malloc(200);
1669 ASSERT_TRUE(pointer != nullptr);
1670
1671 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1672 ASSERT_TRUE(info == nullptr);
1673 ASSERT_EQ(0U, overall_size);
1674 ASSERT_EQ(0U, info_size);
1675 ASSERT_EQ(0U, total_memory);
1676 ASSERT_EQ(0U, backtrace_size);
1677
1678 debug_free(pointer);
1679
1680 debug_free_malloc_leak_info(info);
1681
1682 ASSERT_STREQ("", getFakeLogBuf().c_str());
1683 ASSERT_STREQ("", getFakeLogPrint().c_str());
1684 }
1685
TEST_F(MallocDebugTest,backtrace_same_stack)1686 TEST_F(MallocDebugTest, backtrace_same_stack) {
1687 Init("backtrace=4");
1688
1689 size_t individual_size = GetInfoEntrySize(4);
1690
1691 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1692 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1693 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1694 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1695
1696 void* pointers[4];
1697 pointers[0] = debug_malloc(10);
1698 ASSERT_TRUE(pointers[0] != nullptr);
1699 pointers[1] = debug_malloc(10);
1700 ASSERT_TRUE(pointers[1] != nullptr);
1701 pointers[2] = debug_malloc(10);
1702 ASSERT_TRUE(pointers[2] != nullptr);
1703 pointers[3] = debug_malloc(100);
1704 ASSERT_TRUE(pointers[3] != nullptr);
1705
1706 uint8_t* info;
1707 size_t overall_size;
1708 size_t info_size;
1709 size_t total_memory;
1710 size_t backtrace_size;
1711
1712 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1713 ASSERT_TRUE(info != nullptr);
1714 ASSERT_EQ(individual_size * 2, overall_size);
1715 ASSERT_EQ(individual_size, info_size);
1716 EXPECT_EQ(130U, total_memory);
1717 EXPECT_EQ(4U, backtrace_size);
1718 EXPECT_EQ(100U, *reinterpret_cast<size_t*>(&info[0]));
1719 EXPECT_EQ(1U, *reinterpret_cast<size_t*>(&info[sizeof(size_t)]));
1720 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1721 EXPECT_EQ(0xbc000U, ips[0]);
1722 EXPECT_EQ(0xecd00U, ips[1]);
1723 EXPECT_EQ(0x12000U, ips[2]);
1724
1725 EXPECT_EQ(10U, *reinterpret_cast<size_t*>(&info[individual_size]));
1726 EXPECT_EQ(3U, *reinterpret_cast<size_t*>(&info[sizeof(size_t) + individual_size]));
1727 ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t) + individual_size]);
1728 EXPECT_EQ(0xbc000U, ips[0]);
1729 EXPECT_EQ(0xecd00U, ips[1]);
1730 EXPECT_EQ(0x12000U, ips[2]);
1731
1732 debug_free_malloc_leak_info(info);
1733
1734 debug_free(pointers[0]);
1735 debug_free(pointers[1]);
1736 debug_free(pointers[2]);
1737 debug_free(pointers[3]);
1738
1739 ASSERT_STREQ("", getFakeLogBuf().c_str());
1740 ASSERT_STREQ("", getFakeLogPrint().c_str());
1741 }
1742
TEST_F(MallocDebugTest,backtrace_same_stack_zygote)1743 TEST_F(MallocDebugTest, backtrace_same_stack_zygote) {
1744 Init("backtrace=4");
1745
1746 size_t individual_size = GetInfoEntrySize(4);
1747
1748 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1749 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1750 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1751 backtrace_fake_add(std::vector<uintptr_t> {0xbc000});
1752
1753 zygote_child = true;
1754
1755 void* pointers[4];
1756 pointers[0] = debug_malloc(100);
1757 ASSERT_TRUE(pointers[0] != nullptr);
1758 pointers[1] = debug_malloc(100);
1759 ASSERT_TRUE(pointers[1] != nullptr);
1760 pointers[2] = debug_malloc(100);
1761 ASSERT_TRUE(pointers[2] != nullptr);
1762 pointers[3] = debug_malloc(100);
1763 ASSERT_TRUE(pointers[3] != nullptr);
1764
1765 uint8_t* info;
1766 size_t overall_size;
1767 size_t info_size;
1768 size_t total_memory;
1769 size_t backtrace_size;
1770
1771 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1772 ASSERT_TRUE(info != nullptr);
1773 ASSERT_EQ(individual_size * 2, overall_size);
1774 EXPECT_EQ(individual_size, info_size);
1775 EXPECT_EQ(400U, total_memory);
1776 EXPECT_EQ(4U, backtrace_size);
1777
1778 EXPECT_EQ(0x80000064U, *reinterpret_cast<size_t*>(&info[0]));
1779 EXPECT_EQ(3U, *reinterpret_cast<size_t*>(&info[sizeof(size_t)]));
1780 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1781 EXPECT_EQ(0xbc000U, ips[0]);
1782 EXPECT_EQ(0xecd00U, ips[1]);
1783 EXPECT_EQ(0x12000U, ips[2]);
1784
1785 EXPECT_EQ(0x80000064U, *reinterpret_cast<size_t*>(&info[individual_size]));
1786 EXPECT_EQ(1U, *reinterpret_cast<size_t*>(&info[sizeof(size_t) + individual_size]));
1787 ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t) + individual_size]);
1788 EXPECT_EQ(0xbc000U, ips[0]);
1789 EXPECT_EQ(0U, ips[1]);
1790
1791 debug_free_malloc_leak_info(info);
1792
1793 debug_free(pointers[0]);
1794 debug_free(pointers[1]);
1795 debug_free(pointers[2]);
1796 debug_free(pointers[3]);
1797
1798 ASSERT_STREQ("", getFakeLogBuf().c_str());
1799 ASSERT_STREQ("", getFakeLogPrint().c_str());
1800 }
1801
TEST_F(MallocDebugTest,backtrace_same_stack_mix_zygote)1802 TEST_F(MallocDebugTest, backtrace_same_stack_mix_zygote) {
1803 Init("backtrace=4");
1804
1805 size_t individual_size = GetInfoEntrySize(4);
1806
1807 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1808 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1809 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1810 backtrace_fake_add(std::vector<uintptr_t> {0xbc000});
1811
1812 zygote_child = true;
1813 void* pointers[4];
1814 pointers[0] = debug_malloc(40);
1815 ASSERT_TRUE(pointers[0] != nullptr);
1816 pointers[1] = debug_malloc(40);
1817 ASSERT_TRUE(pointers[1] != nullptr);
1818
1819 zygote_child = false;
1820 pointers[2] = debug_malloc(40);
1821 ASSERT_TRUE(pointers[2] != nullptr);
1822 pointers[3] = debug_malloc(100);
1823 ASSERT_TRUE(pointers[3] != nullptr);
1824
1825 uint8_t* info;
1826 size_t overall_size;
1827 size_t info_size;
1828 size_t total_memory;
1829 size_t backtrace_size;
1830
1831 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1832 ASSERT_TRUE(info != nullptr);
1833 ASSERT_EQ(individual_size * 3, overall_size);
1834 ASSERT_EQ(individual_size, info_size);
1835 EXPECT_EQ(220U, total_memory);
1836 EXPECT_EQ(4U, backtrace_size);
1837
1838 EXPECT_EQ(100U, *reinterpret_cast<size_t*>(&info[0]));
1839 EXPECT_EQ(1U, *reinterpret_cast<size_t*>(&info[sizeof(size_t)]));
1840 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1841 EXPECT_EQ(0xbc000U, ips[0]);
1842 EXPECT_EQ(0U, ips[1]);
1843
1844 EXPECT_EQ(40U, *reinterpret_cast<size_t*>(&info[individual_size]));
1845 EXPECT_EQ(1U, *reinterpret_cast<size_t*>(&info[sizeof(size_t) + individual_size]));
1846 ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t) + individual_size]);
1847 EXPECT_EQ(0xbc000U, ips[0]);
1848 EXPECT_EQ(0xecd00U, ips[1]);
1849 EXPECT_EQ(0x12000U, ips[2]);
1850
1851 EXPECT_EQ(0x80000028U, *reinterpret_cast<size_t*>(&info[2 * individual_size]));
1852 EXPECT_EQ(2U, *reinterpret_cast<size_t*>(&info[sizeof(size_t) + 2 * individual_size]));
1853 ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t) + 2 * individual_size]);
1854 EXPECT_EQ(0xbc000U, ips[0]);
1855 EXPECT_EQ(0xecd00U, ips[1]);
1856 EXPECT_EQ(0x12000U, ips[2]);
1857
1858 debug_free_malloc_leak_info(info);
1859
1860 debug_free(pointers[0]);
1861 debug_free(pointers[1]);
1862 debug_free(pointers[2]);
1863 debug_free(pointers[3]);
1864
1865 ASSERT_STREQ("", getFakeLogBuf().c_str());
1866 ASSERT_STREQ("", getFakeLogPrint().c_str());
1867 }
1868
TEST_F(MallocDebugTest,backtrace_frame_data_nullptr_same_size)1869 TEST_F(MallocDebugTest, backtrace_frame_data_nullptr_same_size) {
1870 Init("backtrace=4");
1871
1872 size_t individual_size = GetInfoEntrySize(4);
1873
1874 void* pointers[4];
1875 pointers[0] = debug_malloc(100);
1876 ASSERT_TRUE(pointers[0] != nullptr);
1877 pointers[1] = debug_malloc(100);
1878 ASSERT_TRUE(pointers[1] != nullptr);
1879 pointers[2] = debug_malloc(100);
1880 ASSERT_TRUE(pointers[2] != nullptr);
1881 pointers[3] = debug_malloc(100);
1882 ASSERT_TRUE(pointers[3] != nullptr);
1883
1884 uint8_t* info;
1885 size_t overall_size;
1886 size_t info_size;
1887 size_t total_memory;
1888 size_t backtrace_size;
1889
1890 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1891 ASSERT_TRUE(info != nullptr);
1892 ASSERT_EQ(individual_size, overall_size);
1893 EXPECT_EQ(individual_size, info_size);
1894 EXPECT_EQ(400U, total_memory);
1895 EXPECT_EQ(4U, backtrace_size);
1896
1897 EXPECT_EQ(100U, *reinterpret_cast<size_t*>(&info[0]));
1898 EXPECT_EQ(4U, *reinterpret_cast<size_t*>(&info[sizeof(size_t)]));
1899 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1900 EXPECT_EQ(0U, ips[0]);
1901
1902 debug_free_malloc_leak_info(info);
1903
1904 debug_free(pointers[0]);
1905 debug_free(pointers[1]);
1906 debug_free(pointers[2]);
1907 debug_free(pointers[3]);
1908
1909 ASSERT_STREQ("", getFakeLogBuf().c_str());
1910 ASSERT_STREQ("", getFakeLogPrint().c_str());
1911 }
1912
TEST_F(MallocDebugTest,overflow)1913 TEST_F(MallocDebugTest, overflow) {
1914 Init("guard fill_on_free");
1915
1916 void* pointer = debug_malloc(SIZE_MAX);
1917 ASSERT_TRUE(pointer == nullptr);
1918 ASSERT_EQ(ENOMEM, errno);
1919
1920 pointer = debug_calloc(1, SIZE_MAX);
1921 ASSERT_TRUE(pointer == nullptr);
1922 ASSERT_EQ(ENOMEM, errno);
1923
1924 pointer = debug_calloc(SIZE_MAX, 1);
1925 ASSERT_TRUE(pointer == nullptr);
1926 ASSERT_EQ(ENOMEM, errno);
1927
1928 pointer = debug_calloc(SIZE_MAX/100, 100);
1929 ASSERT_TRUE(pointer == nullptr);
1930 ASSERT_EQ(ENOMEM, errno);
1931
1932 pointer = debug_calloc(100, SIZE_MAX/100);
1933 ASSERT_TRUE(pointer == nullptr);
1934 ASSERT_EQ(ENOMEM, errno);
1935
1936 const size_t size_t_bits = sizeof(size_t) * 8;
1937 const size_t sqrt_size_t = 1ULL << (size_t_bits/2);
1938 pointer = debug_calloc(sqrt_size_t + 1, sqrt_size_t);
1939 ASSERT_TRUE(pointer == nullptr);
1940 ASSERT_EQ(ENOMEM, errno);
1941
1942 pointer = debug_realloc(nullptr, SIZE_MAX);
1943 ASSERT_TRUE(pointer == nullptr);
1944 ASSERT_EQ(ENOMEM, errno);
1945
1946 pointer = debug_malloc(100);
1947 ASSERT_TRUE(pointer != nullptr);
1948 memset(pointer, 0xd0, 100);
1949
1950 void* realloc_pointer = debug_realloc(pointer, SIZE_MAX);
1951 ASSERT_TRUE(realloc_pointer == nullptr);
1952 // Verify the pointer was not freed.
1953 for (size_t i = 0; i < 100; i++) {
1954 ASSERT_EQ(0xd0, reinterpret_cast<uint8_t*>(pointer)[i]) << "Failed checking byte " << i;
1955 }
1956 debug_free(pointer);
1957
1958 ASSERT_STREQ("", getFakeLogBuf().c_str());
1959 ASSERT_STREQ("", getFakeLogPrint().c_str());
1960 }
1961
VerifyZygoteSet(size_t memory_bytes)1962 static void VerifyZygoteSet(size_t memory_bytes) {
1963 size_t expected_info_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1964 std::vector<uint8_t> expected_info(expected_info_size);
1965 memset(expected_info.data(), 0, expected_info_size);
1966 InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
1967 entry->size = memory_bytes | (1U << 31);
1968 entry->num_allocations = 1;
1969 entry->frames[0] = 0x1;
1970
1971 uint8_t* info;
1972 size_t overall_size;
1973 size_t info_size;
1974 size_t total_memory;
1975 size_t backtrace_size;
1976
1977 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1978 ASSERT_EQ(expected_info_size, overall_size);
1979 ASSERT_EQ(expected_info_size, info_size);
1980 ASSERT_EQ(memory_bytes, total_memory);
1981 ASSERT_EQ(16U, backtrace_size);
1982 ASSERT_TRUE(memcmp(info, expected_info.data(), expected_info_size) == 0)
1983 << ShowDiffs(info, expected_info.data(), expected_info_size);
1984
1985 debug_free_malloc_leak_info(info);
1986 }
1987
TEST_F(MallocDebugTest,zygote_set)1988 TEST_F(MallocDebugTest, zygote_set) {
1989 // Set all of the options.
1990 Init("guard fill backtrace leak_track free_track=2");
1991
1992 zygote_child = true;
1993
1994 backtrace_fake_add(std::vector<uintptr_t> {0x1});
1995
1996 void* pointer = debug_malloc(100);
1997 ASSERT_TRUE(pointer != nullptr);
1998 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
1999 memset(pointer, 0, 100);
2000 VerifyZygoteSet(100);
2001 ASSERT_FALSE(HasFatalFailure());
2002 debug_free(pointer);
2003
2004 backtrace_fake_add(std::vector<uintptr_t> {0x1});
2005 pointer = debug_calloc(10, 20);
2006 ASSERT_TRUE(pointer != nullptr);
2007 ASSERT_EQ(200U, debug_malloc_usable_size(pointer));
2008 VerifyZygoteSet(200);
2009 ASSERT_FALSE(HasFatalFailure());
2010 debug_free(pointer);
2011
2012 backtrace_fake_add(std::vector<uintptr_t> {0x1});
2013 pointer = debug_memalign(128, 300);
2014 ASSERT_TRUE(pointer != nullptr);
2015 ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
2016 memset(pointer, 0, 300);
2017 VerifyZygoteSet(300);
2018 ASSERT_FALSE(HasFatalFailure());
2019 debug_free(pointer);
2020
2021 backtrace_fake_add(std::vector<uintptr_t> {0x1});
2022 pointer = debug_malloc(500);
2023 ASSERT_TRUE(pointer != nullptr);
2024 ASSERT_EQ(500U, debug_malloc_usable_size(pointer));
2025 memset(pointer, 0, 500);
2026 VerifyZygoteSet(500);
2027 ASSERT_FALSE(HasFatalFailure());
2028
2029 backtrace_fake_add(std::vector<uintptr_t> {0x1});
2030 pointer = debug_realloc(pointer, 300);
2031 ASSERT_TRUE(pointer != nullptr);
2032 ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
2033 VerifyZygoteSet(300);
2034 ASSERT_FALSE(HasFatalFailure());
2035 debug_free(pointer);
2036
2037 ASSERT_STREQ("", getFakeLogBuf().c_str());
2038 ASSERT_STREQ("", getFakeLogPrint().c_str());
2039 }
2040
TEST_F(MallocDebugTest,max_size)2041 TEST_F(MallocDebugTest, max_size) {
2042 Init("guard");
2043
2044 void* pointer = debug_malloc(1U << 31);
2045 ASSERT_TRUE(pointer == nullptr);
2046
2047 pointer = debug_calloc(1, 1U << 31);
2048 ASSERT_TRUE(pointer == nullptr);
2049
2050 pointer = debug_calloc(1U << 31, 1);
2051 ASSERT_TRUE(pointer == nullptr);
2052
2053 pointer = debug_memalign(16, 1U << 31);
2054 ASSERT_TRUE(pointer == nullptr);
2055
2056 ASSERT_STREQ("", getFakeLogBuf().c_str());
2057 ASSERT_STREQ("", getFakeLogPrint().c_str());
2058 }
2059
TEST_F(MallocDebugTest,debug_mallinfo)2060 TEST_F(MallocDebugTest, debug_mallinfo) {
2061 Init("guard");
2062
2063 void* pointer = debug_malloc(150);
2064 ASSERT_TRUE(pointer != nullptr);
2065
2066 struct mallinfo mi = debug_mallinfo();
2067 EXPECT_NE(0U, mi.uordblks);
2068
2069 debug_free(pointer);
2070
2071 ASSERT_STREQ("", getFakeLogBuf().c_str());
2072 ASSERT_STREQ("", getFakeLogPrint().c_str());
2073 }
2074
TEST_F(MallocDebugTest,debug_mallopt)2075 TEST_F(MallocDebugTest, debug_mallopt) {
2076 Init("guard");
2077
2078 void* pointer = debug_malloc(150);
2079 ASSERT_TRUE(pointer != nullptr);
2080
2081 EXPECT_EQ(0, debug_mallopt(-1000, 1));
2082
2083 debug_free(pointer);
2084
2085 ASSERT_STREQ("", getFakeLogBuf().c_str());
2086 ASSERT_STREQ("", getFakeLogPrint().c_str());
2087 }
2088
TEST_F(MallocDebugTest,debug_posix_memalign)2089 TEST_F(MallocDebugTest, debug_posix_memalign) {
2090 Init("guard");
2091
2092 void* pointer;
2093 ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 300));
2094 ASSERT_TRUE(pointer != nullptr);
2095 debug_free(pointer);
2096
2097 ASSERT_EQ(EINVAL, debug_posix_memalign(&pointer, 11, 300));
2098
2099 ASSERT_EQ(ENOMEM, debug_posix_memalign(&pointer, 16, SIZE_MAX));
2100
2101 ASSERT_STREQ("", getFakeLogBuf().c_str());
2102 ASSERT_STREQ("", getFakeLogPrint().c_str());
2103 }
2104
2105 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
TEST_F(MallocDebugTest,debug_pvalloc)2106 TEST_F(MallocDebugTest, debug_pvalloc) {
2107 Init("guard");
2108
2109 size_t pagesize = getpagesize();
2110 void* pointer = debug_pvalloc(1);
2111 ASSERT_TRUE(pointer != nullptr);
2112 ASSERT_EQ(pagesize, debug_malloc_usable_size(pointer));
2113 uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
2114 ASSERT_EQ(0U, value);
2115 debug_free(pointer);
2116 }
2117
TEST_F(MallocDebugTest,debug_valloc)2118 TEST_F(MallocDebugTest, debug_valloc) {
2119 Init("guard");
2120
2121 size_t pagesize = getpagesize();
2122 void* pointer = debug_valloc(100);
2123 ASSERT_TRUE(pointer != nullptr);
2124 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
2125 uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
2126 ASSERT_EQ(0U, value);
2127 debug_free(pointer);
2128 }
2129 #endif
2130
VerifyRecordAllocs()2131 void VerifyRecordAllocs() {
2132 std::string expected;
2133
2134 void* pointer = debug_malloc(10);
2135 ASSERT_TRUE(pointer != nullptr);
2136 expected += android::base::StringPrintf("%d: malloc %p 10\n", getpid(), pointer);
2137 debug_free(pointer);
2138 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2139
2140 pointer = debug_calloc(1, 20);
2141 ASSERT_TRUE(pointer != nullptr);
2142 expected += android::base::StringPrintf("%d: calloc %p 20 1\n", getpid(), pointer);
2143 debug_free(pointer);
2144 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2145
2146 pointer = debug_realloc(nullptr, 30);
2147 ASSERT_TRUE(pointer != nullptr);
2148 expected += android::base::StringPrintf("%d: realloc %p 0x0 30\n", getpid(), pointer);
2149 void* old_pointer = pointer;
2150 pointer = debug_realloc(pointer, 2048);
2151 ASSERT_TRUE(pointer != nullptr);
2152 expected += android::base::StringPrintf("%d: realloc %p %p 2048\n", getpid(),
2153 pointer, old_pointer);
2154 debug_realloc(pointer, 0);
2155 expected += android::base::StringPrintf("%d: realloc 0x0 %p 0\n", getpid(), pointer);
2156
2157 pointer = debug_memalign(16, 40);
2158 ASSERT_TRUE(pointer != nullptr);
2159 expected += android::base::StringPrintf("%d: memalign %p 16 40\n", getpid(), pointer);
2160 debug_free(pointer);
2161 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2162
2163 pointer = debug_aligned_alloc(32, 64);
2164 ASSERT_TRUE(pointer != nullptr);
2165 expected += android::base::StringPrintf("%d: memalign %p 32 64\n", getpid(), pointer);
2166 debug_free(pointer);
2167 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2168
2169 ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 50));
2170 ASSERT_TRUE(pointer != nullptr);
2171 expected += android::base::StringPrintf("%d: memalign %p 32 50\n", getpid(), pointer);
2172 debug_free(pointer);
2173 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2174
2175 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
2176 pointer = debug_pvalloc(60);
2177 ASSERT_TRUE(pointer != nullptr);
2178 expected += android::base::StringPrintf("%d: memalign %p 4096 4096\n", getpid(), pointer);
2179 debug_free(pointer);
2180 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2181
2182 pointer = debug_valloc(70);
2183 ASSERT_TRUE(pointer != nullptr);
2184 expected += android::base::StringPrintf("%d: memalign %p 4096 70\n", getpid(), pointer);
2185 debug_free(pointer);
2186 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2187 #endif
2188
2189 // Dump all of the data accumulated so far.
2190 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2191 sleep(1);
2192
2193 // This triggers the dumping.
2194 pointer = debug_malloc(110);
2195 ASSERT_TRUE(pointer != nullptr);
2196 expected += android::base::StringPrintf("%d: malloc %p 110\n", getpid(), pointer);
2197
2198 // Read all of the contents.
2199 std::string actual;
2200 ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
2201 ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
2202
2203 ASSERT_STREQ(expected.c_str(), actual.c_str());
2204
2205 ASSERT_STREQ("", getFakeLogBuf().c_str());
2206 ASSERT_STREQ("", getFakeLogPrint().c_str());
2207
2208 debug_free(pointer);
2209 }
2210
TEST_F(MallocDebugTest,record_allocs_no_header)2211 TEST_F(MallocDebugTest, record_allocs_no_header) {
2212 Init("record_allocs");
2213
2214 VerifyRecordAllocs();
2215 }
2216
TEST_F(MallocDebugTest,record_allocs_with_header)2217 TEST_F(MallocDebugTest, record_allocs_with_header) {
2218 Init("record_allocs front_guard");
2219
2220 VerifyRecordAllocs();
2221 }
2222
TEST_F(MallocDebugTest,record_allocs_max)2223 TEST_F(MallocDebugTest, record_allocs_max) {
2224 Init("record_allocs=5");
2225
2226 std::string expected;
2227
2228 void* pointer = debug_malloc(10);
2229 ASSERT_TRUE(pointer != nullptr);
2230 expected += android::base::StringPrintf("%d: malloc %p 10\n", getpid(), pointer);
2231 debug_free(pointer);
2232 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2233
2234 pointer = debug_malloc(20);
2235 ASSERT_TRUE(pointer != nullptr);
2236 expected += android::base::StringPrintf("%d: malloc %p 20\n", getpid(), pointer);
2237 debug_free(pointer);
2238 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2239
2240 pointer = debug_malloc(1024);
2241 ASSERT_TRUE(pointer != nullptr);
2242 expected += android::base::StringPrintf("%d: malloc %p 1024\n", getpid(), pointer);
2243 debug_free(pointer);
2244
2245 // Dump all of the data accumulated so far.
2246 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2247 sleep(1);
2248
2249 // This triggers the dumping.
2250 pointer = debug_malloc(110);
2251 ASSERT_TRUE(pointer != nullptr);
2252
2253 // Read all of the contents.
2254 std::string actual;
2255 ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
2256 ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
2257
2258 ASSERT_STREQ(expected.c_str(), actual.c_str());
2259
2260 ASSERT_STREQ("", getFakeLogBuf().c_str());
2261 ASSERT_STREQ("", getFakeLogPrint().c_str());
2262
2263 debug_free(pointer);
2264 }
2265
TEST_F(MallocDebugTest,record_allocs_thread_done)2266 TEST_F(MallocDebugTest, record_allocs_thread_done) {
2267 Init("record_allocs=5");
2268
2269 static pid_t tid = 0;
2270 static void* pointer = nullptr;
2271 std::thread thread([](){
2272 tid = gettid();
2273 pointer = debug_malloc(100);
2274 write(0, pointer, 0);
2275 debug_free(pointer);
2276 });
2277 thread.join();
2278
2279 std::string expected = android::base::StringPrintf("%d: malloc %p 100\n", tid, pointer);
2280 expected += android::base::StringPrintf("%d: free %p\n", tid, pointer);
2281 expected += android::base::StringPrintf("%d: thread_done 0x0\n", tid);
2282
2283 // Dump all of the data accumulated so far.
2284 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2285 sleep(1);
2286
2287 // This triggers the dumping.
2288 pointer = debug_malloc(23);
2289 ASSERT_TRUE(pointer != nullptr);
2290 expected += android::base::StringPrintf("%d: malloc %p 23\n", getpid(), pointer);
2291
2292 // Read all of the contents.
2293 std::string actual;
2294 ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
2295 ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
2296
2297 ASSERT_STREQ(expected.c_str(), actual.c_str());
2298
2299 ASSERT_STREQ("", getFakeLogBuf().c_str());
2300 ASSERT_STREQ("", getFakeLogPrint().c_str());
2301
2302 debug_free(pointer);
2303 }
2304
TEST_F(MallocDebugTest,record_allocs_file_name_fail)2305 TEST_F(MallocDebugTest, record_allocs_file_name_fail) {
2306 Init("record_allocs=5");
2307
2308 // Delete the special.txt file and create a symbolic link there to
2309 // make sure the create file will fail.
2310 unlink(RECORD_ALLOCS_FILE);
2311
2312 ASSERT_EQ(0, symlink("/data/local/tmp/does_not_exist", RECORD_ALLOCS_FILE));
2313
2314 std::string expected;
2315
2316 void* pointer = debug_malloc(10);
2317 ASSERT_TRUE(pointer != nullptr);
2318 expected += android::base::StringPrintf("%d: malloc %p 10\n", getpid(), pointer);
2319 debug_free(pointer);
2320 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2321
2322 // Dump all of the data accumulated so far.
2323 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2324 sleep(1);
2325
2326 // This triggers the dumping.
2327 pointer = debug_malloc(110);
2328 ASSERT_TRUE(pointer != nullptr);
2329 expected += android::base::StringPrintf("%d: malloc %p 110\n", getpid(), pointer);
2330
2331 // Read all of the contents.
2332 std::string actual;
2333 ASSERT_FALSE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
2334
2335 // Unlink the file so the next dump passes.
2336 ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
2337
2338 // Dump all of the data accumulated so far.
2339 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
2340 sleep(1);
2341
2342 // This triggers the dumping.
2343 debug_free(pointer);
2344 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
2345
2346 ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
2347 ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
2348 ASSERT_STREQ(expected.c_str(), actual.c_str());
2349
2350 ASSERT_STREQ("", getFakeLogBuf().c_str());
2351 std::string expected_log = android::base::StringPrintf(
2352 "6 malloc_debug Cannot create record alloc file %s: Too many symbolic links encountered\n",
2353 RECORD_ALLOCS_FILE);
2354 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
2355 }
2356
TEST_F(MallocDebugTest,verify_pointers)2357 TEST_F(MallocDebugTest, verify_pointers) {
2358 Init("verify_pointers");
2359
2360 void* pointer = debug_malloc(10);
2361 memset(pointer, 0, 10);
2362 debug_free(pointer);
2363
2364 ASSERT_STREQ("", getFakeLogBuf().c_str());
2365 ASSERT_STREQ("", getFakeLogPrint().c_str());
2366
2367 debug_free(pointer);
2368 ASSERT_EQ(0U, debug_malloc_usable_size(pointer));
2369 ASSERT_EQ(nullptr, debug_realloc(pointer, 1000));
2370
2371 ASSERT_STREQ("", getFakeLogBuf().c_str());
2372 std::string free_pointer_str(
2373 android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p UNKNOWN POINTER (free)\n",
2374 pointer));
2375 std::string usable_pointer_str(
2376 android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p UNKNOWN POINTER (malloc_usable_size)\n",
2377 pointer));
2378 std::string realloc_pointer_str(
2379 android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p UNKNOWN POINTER (realloc)\n",
2380 pointer));
2381 std::string backtrace_str("6 malloc_debug Backtrace at time of failure:\n");
2382 backtrace_str += "6 malloc_debug Backtrace failed to get any frames.\n";
2383
2384 std::string expected_log(DIVIDER + free_pointer_str + backtrace_str + DIVIDER);
2385 expected_log += DIVIDER + usable_pointer_str + backtrace_str + DIVIDER;
2386 expected_log += DIVIDER + realloc_pointer_str + backtrace_str + DIVIDER;
2387 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
2388
2389 resetLogs();
2390
2391 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200});
2392 backtrace_fake_add(std::vector<uintptr_t> {0x300, 0x400});
2393 backtrace_fake_add(std::vector<uintptr_t> {0x500, 0x600});
2394 debug_free(pointer);
2395 ASSERT_EQ(0U, debug_malloc_usable_size(pointer));
2396 ASSERT_EQ(nullptr, debug_realloc(pointer, 1000));
2397
2398 ASSERT_STREQ("", getFakeLogBuf().c_str());
2399 expected_log = DIVIDER + free_pointer_str;
2400 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
2401 expected_log += "6 malloc_debug #00 pc 0x100\n";
2402 expected_log += "6 malloc_debug #01 pc 0x200\n";
2403 expected_log += DIVIDER;
2404 expected_log += DIVIDER + usable_pointer_str;
2405 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
2406 expected_log += "6 malloc_debug #00 pc 0x300\n";
2407 expected_log += "6 malloc_debug #01 pc 0x400\n";
2408 expected_log += DIVIDER;
2409 expected_log += DIVIDER + realloc_pointer_str;
2410 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
2411 expected_log += "6 malloc_debug #00 pc 0x500\n";
2412 expected_log += "6 malloc_debug #01 pc 0x600\n";
2413 expected_log += DIVIDER;
2414 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
2415 }
2416
TEST_F(MallocDebugTest,abort_on_error_log_error)2417 TEST_F(MallocDebugTest, abort_on_error_log_error) {
2418 Init("abort_on_error verify_pointers");
2419
2420 void* pointer = debug_malloc(10);
2421 memset(pointer, 0, 10);
2422 debug_free(pointer);
2423
2424 ASSERT_STREQ("", getFakeLogBuf().c_str());
2425 ASSERT_STREQ("", getFakeLogPrint().c_str());
2426
2427 EXPECT_DEATH(debug_free(pointer), "");
2428 }
2429
TEST_F(MallocDebugTest,abort_on_error_guard_corrupted)2430 TEST_F(MallocDebugTest, abort_on_error_guard_corrupted) {
2431 Init("abort_on_error front_guard=32");
2432
2433 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
2434 ASSERT_TRUE(pointer != nullptr);
2435 pointer[-16] = 0x00;
2436 EXPECT_DEATH(debug_free(pointer), "");
2437 pointer[-16] = 0xaa;
2438 debug_free(pointer);
2439 }
2440
TEST_F(MallocDebugTest,abort_on_error_use_after_free)2441 TEST_F(MallocDebugTest, abort_on_error_use_after_free) {
2442 Init("abort_on_error free_track=100 free_track_backtrace_num_frames=0");
2443
2444 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
2445 ASSERT_TRUE(pointer != nullptr);
2446 memset(pointer, 0, 100);
2447 debug_free(pointer);
2448
2449 pointer[56] = 0x91;
2450
2451 EXPECT_DEATH(debug_finalize(), "");
2452
2453 pointer[56] = 0xef;
2454 }
2455
TEST_F(MallocDebugTest,abort_on_error_header_tag_corrupted)2456 TEST_F(MallocDebugTest, abort_on_error_header_tag_corrupted) {
2457 Init("abort_on_error free_track=100 free_track_backtrace_num_frames=0 rear_guard");
2458
2459 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
2460 ASSERT_TRUE(pointer != nullptr);
2461 memset(pointer, 0, 100);
2462 debug_free(pointer);
2463
2464 uint8_t tag_value = pointer[-get_tag_offset()];
2465 pointer[-get_tag_offset()] = 0x00;
2466
2467 EXPECT_DEATH(debug_finalize(), "");
2468
2469 pointer[-get_tag_offset()] = tag_value;
2470 }
2471
TEST_F(MallocDebugTest,malloc_info_no_pointer_tracking)2472 TEST_F(MallocDebugTest, malloc_info_no_pointer_tracking) {
2473 Init("fill");
2474
2475 char* buffer;
2476 size_t size;
2477 FILE* memstream = open_memstream(&buffer, &size);
2478 ASSERT_TRUE(memstream != nullptr);
2479 ASSERT_EQ(0, debug_malloc_info(0, memstream));
2480 ASSERT_EQ(0, fclose(memstream));
2481
2482 tinyxml2::XMLDocument doc;
2483 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buffer));
2484 auto root = doc.FirstChildElement();
2485 ASSERT_TRUE(root != nullptr);
2486 ASSERT_STREQ("malloc", root->Name());
2487 // Don't care what the underyling implementation says, just that it's
2488 // not generated by debug malloc.
2489 ASSERT_STRNE("debug-malloc-1", root->Attribute("version"));
2490 }
2491
TEST_F(MallocDebugTest,malloc_info_with_pointer_tracking)2492 TEST_F(MallocDebugTest, malloc_info_with_pointer_tracking) {
2493 Init("verify_pointers");
2494
2495 std::unique_ptr<void, decltype(debug_free)*> ptr1(debug_malloc(1000), debug_free);
2496 ASSERT_TRUE(ptr1.get() != nullptr);
2497 std::unique_ptr<void, decltype(debug_free)*> ptr2(debug_malloc(1000), debug_free);
2498 ASSERT_TRUE(ptr2.get() != nullptr);
2499 std::unique_ptr<void, decltype(debug_free)*> ptr3(debug_malloc(500), debug_free);
2500 ASSERT_TRUE(ptr3.get() != nullptr);
2501 std::unique_ptr<void, decltype(debug_free)*> ptr4(debug_malloc(1200), debug_free);
2502 ASSERT_TRUE(ptr4.get() != nullptr);
2503
2504 char* buffer;
2505 size_t size;
2506 FILE* memstream = open_memstream(&buffer, &size);
2507 ASSERT_TRUE(memstream != nullptr);
2508 ASSERT_EQ(0, debug_malloc_info(0, memstream));
2509 ASSERT_EQ(0, fclose(memstream));
2510
2511 SCOPED_TRACE(testing::Message() << "Output:\n" << buffer);
2512
2513 tinyxml2::XMLDocument doc;
2514 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buffer));
2515 auto root = doc.FirstChildElement();
2516 ASSERT_TRUE(root != nullptr);
2517 ASSERT_STREQ("malloc", root->Name());
2518 ASSERT_STREQ("debug-malloc-1", root->Attribute("version"));
2519
2520 auto alloc = root->FirstChildElement();
2521 ASSERT_TRUE(alloc != nullptr);
2522 ASSERT_STREQ("allocation", alloc->Name());
2523 int val;
2524 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->QueryIntAttribute("nr", &val));
2525 ASSERT_EQ(0, val);
2526 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("size")->QueryIntText(&val));
2527 ASSERT_EQ(1200, val);
2528 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("total")->QueryIntText(&val));
2529 ASSERT_EQ(1, val);
2530
2531 alloc = alloc->NextSiblingElement();
2532 ASSERT_TRUE(alloc != nullptr);
2533 ASSERT_STREQ("allocation", alloc->Name());
2534 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->QueryIntAttribute("nr", &val));
2535 ASSERT_EQ(1, val);
2536 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("size")->QueryIntText(&val));
2537 ASSERT_EQ(1000, val);
2538 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("total")->QueryIntText(&val));
2539 ASSERT_EQ(2, val);
2540
2541 alloc = alloc->NextSiblingElement();
2542 ASSERT_TRUE(alloc != nullptr);
2543 ASSERT_STREQ("allocation", alloc->Name());
2544 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->QueryIntAttribute("nr", &val));
2545 ASSERT_EQ(2, val);
2546 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("size")->QueryIntText(&val));
2547 ASSERT_EQ(500, val);
2548 ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("total")->QueryIntText(&val));
2549 ASSERT_EQ(1, val);
2550 }
2551