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 <stdlib.h>
20 #include <string.h>
21 #include <sys/cdefs.h>
22 #include <sys/param.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25
26 #include <algorithm>
27 #include <thread>
28 #include <vector>
29 #include <utility>
30
31 #include <gtest/gtest.h>
32
33 #include <android-base/file.h>
34 #include <android-base/stringprintf.h>
35
36 #include <private/bionic_macros.h>
37 #include <private/bionic_malloc_dispatch.h>
38
39 #include "Config.h"
40 #include "malloc_debug.h"
41
42 #include "log_fake.h"
43 #include "backtrace_fake.h"
44
45 __BEGIN_DECLS
46
47 bool debug_initialize(const MallocDispatch*, int*, const char*);
48 void debug_finalize();
49
50 void* debug_malloc(size_t);
51 void debug_free(void*);
52 void* debug_calloc(size_t, size_t);
53 void* debug_realloc(void*, size_t);
54 int debug_posix_memalign(void**, size_t, size_t);
55 void* debug_memalign(size_t, size_t);
56 size_t debug_malloc_usable_size(void*);
57 void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
58 void debug_free_malloc_leak_info(uint8_t*);
59
60 struct mallinfo debug_mallinfo();
61 int debug_mallopt(int, int);
62
63 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
64 void* debug_pvalloc(size_t);
65 void* debug_valloc(size_t);
66 #endif
67
68 __END_DECLS
69
70 constexpr char DIVIDER[] =
71 "6 malloc_debug *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n";
72
73 constexpr uint32_t BACKTRACE_HEADER = 0x1;
74
get_tag_offset(uint32_t flags=0,size_t backtrace_frames=0)75 static size_t get_tag_offset(uint32_t flags = 0, size_t backtrace_frames = 0) {
76 size_t offset = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
77 if (flags & BACKTRACE_HEADER) {
78 offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames, MINIMUM_ALIGNMENT_BYTES);
79 }
80 return offset;
81 }
82
83 static constexpr const char RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs.txt";
84
85 class MallocDebugTest : public ::testing::Test {
86 protected:
SetUp()87 void SetUp() override {
88 initialized = false;
89 resetLogs();
90 backtrace_fake_clear_all();
91 // Delete the record data file if it exists.
92 unlink(RECORD_ALLOCS_FILE);
93 }
94
TearDown()95 void TearDown() override {
96 if (initialized) {
97 debug_finalize();
98 }
99 }
100
Init(const char * options)101 void Init(const char* options) {
102 zygote = 0;
103 ASSERT_TRUE(debug_initialize(&dispatch, &zygote, options));
104 initialized = true;
105 }
106
107 bool initialized;
108
109 int zygote;
110
111 static MallocDispatch dispatch;
112 };
113
114 MallocDispatch MallocDebugTest::dispatch = {
115 calloc,
116 free,
117 mallinfo,
118 malloc,
119 malloc_usable_size,
120 memalign,
121 posix_memalign,
122 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
123 nullptr,
124 #endif
125 realloc,
126 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
127 nullptr,
128 #endif
129 nullptr,
130 nullptr,
131 nullptr,
132 mallopt,
133 };
134
VerifyAllocCalls()135 void VerifyAllocCalls() {
136 size_t alloc_size = 1024;
137
138 // Verify debug_malloc.
139 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(alloc_size));
140 ASSERT_TRUE(pointer != nullptr);
141 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
142 ASSERT_EQ(0xeb, pointer[i]);
143 }
144 debug_free(pointer);
145
146 // Verify debug_calloc.
147 pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, alloc_size));
148 ASSERT_TRUE(pointer != nullptr);
149 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
150 ASSERT_EQ(0, pointer[i]) << "Failed at byte " << i;
151 }
152 debug_free(pointer);
153
154 pointer = reinterpret_cast<uint8_t*>(debug_memalign(128, alloc_size));
155 ASSERT_TRUE(pointer != nullptr);
156 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
157 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
158 }
159 debug_free(pointer);
160
161 pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 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]) << "Failed at byte " << i;
165 }
166 memset(pointer, 0xff, alloc_size);
167 // Increase the size, verify the extra length is initialized to 0xeb,
168 // but the rest is 0xff.
169 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size * 2));
170 ASSERT_TRUE(pointer != nullptr);
171 for (size_t i = 0; i < alloc_size; i++) {
172 ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
173 }
174 for (size_t i = alloc_size; i < debug_malloc_usable_size(pointer); i++) {
175 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
176 }
177 memset(pointer, 0xff, debug_malloc_usable_size(pointer));
178 // Shrink the size and verify nothing changes.
179 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size));
180 ASSERT_TRUE(pointer != nullptr);
181 for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
182 ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
183 }
184 // This should free the pointer.
185 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
186 ASSERT_TRUE(pointer == nullptr);
187
188 ASSERT_STREQ("", getFakeLogBuf().c_str());
189 ASSERT_STREQ("", getFakeLogPrint().c_str());
190 }
191
TEST_F(MallocDebugTest,fill_generic)192 TEST_F(MallocDebugTest, fill_generic) {
193 Init("fill");
194 VerifyAllocCalls();
195 }
196
TEST_F(MallocDebugTest,fill_on_alloc_generic)197 TEST_F(MallocDebugTest, fill_on_alloc_generic) {
198 Init("fill_on_alloc");
199 VerifyAllocCalls();
200 }
201
TEST_F(MallocDebugTest,fill_on_alloc_partial)202 TEST_F(MallocDebugTest, fill_on_alloc_partial) {
203 Init("fill_on_alloc=25");
204
205 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
206 ASSERT_TRUE(pointer != nullptr);
207 for (size_t i = 0; i < 25; i++) {
208 ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
209 }
210 debug_free(pointer);
211
212 ASSERT_STREQ("", getFakeLogBuf().c_str());
213 ASSERT_STREQ("", getFakeLogPrint().c_str());
214 }
215
TEST_F(MallocDebugTest,fill_on_free)216 TEST_F(MallocDebugTest, fill_on_free) {
217 Init("fill_on_free free_track free_track_backtrace_num_frames=0");
218
219 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
220 ASSERT_TRUE(pointer != nullptr);
221 size_t usable_size = debug_malloc_usable_size(pointer);
222 memset(pointer, 0, usable_size);
223 debug_free(pointer);
224
225 for (size_t i = 0; i < usable_size; i++) {
226 ASSERT_EQ(0xef, pointer[i]) << "Failed at byte " << i;
227 }
228
229 ASSERT_STREQ("", getFakeLogBuf().c_str());
230 ASSERT_STREQ("", getFakeLogPrint().c_str());
231 }
232
TEST_F(MallocDebugTest,fill_on_free_partial)233 TEST_F(MallocDebugTest, fill_on_free_partial) {
234 Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
235
236 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
237 ASSERT_TRUE(pointer != nullptr);
238 size_t usable_size = debug_malloc_usable_size(pointer);
239 memset(pointer, 0, usable_size);
240 debug_free(pointer);
241
242 for (size_t i = 0; i < 30; i++) {
243 ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
244 }
245 for (size_t i = 30; i < usable_size; i++) {
246 ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
247 }
248
249 ASSERT_STREQ("", getFakeLogBuf().c_str());
250 ASSERT_STREQ("", getFakeLogPrint().c_str());
251 }
252
TEST_F(MallocDebugTest,free_track_partial)253 TEST_F(MallocDebugTest, free_track_partial) {
254 Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
255
256 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
257 ASSERT_TRUE(pointer != nullptr);
258 size_t usable_size = debug_malloc_usable_size(pointer);
259 memset(pointer, 0, usable_size);
260 debug_free(pointer);
261
262 for (size_t i = 0; i < 30; i++) {
263 ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
264 }
265 for (size_t i = 30; i < usable_size; i++) {
266 ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
267 }
268
269 debug_finalize();
270 initialized = false;
271
272 ASSERT_STREQ("", getFakeLogBuf().c_str());
273 ASSERT_STREQ("", getFakeLogPrint().c_str());
274 }
275
TEST_F(MallocDebugTest,all_options)276 TEST_F(MallocDebugTest, all_options) {
277 Init("guard backtrace fill expand_alloc free_track leak_track");
278 VerifyAllocCalls();
279 }
280
TEST_F(MallocDebugTest,expand_alloc)281 TEST_F(MallocDebugTest, expand_alloc) {
282 Init("expand_alloc=1024");
283
284 void* pointer = debug_malloc(10);
285 ASSERT_TRUE(pointer != nullptr);
286 ASSERT_LE(1034U, debug_malloc_usable_size(pointer));
287 debug_free(pointer);
288
289 pointer = debug_calloc(1, 20);
290 ASSERT_TRUE(pointer != nullptr);
291 ASSERT_LE(1044U, debug_malloc_usable_size(pointer));
292 debug_free(pointer);
293
294 pointer = debug_memalign(128, 15);
295 ASSERT_TRUE(pointer != nullptr);
296 ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
297 debug_free(pointer);
298
299 pointer = debug_realloc(nullptr, 30);
300 ASSERT_TRUE(pointer != nullptr);
301 ASSERT_LE(1054U, debug_malloc_usable_size(pointer));
302 pointer = debug_realloc(pointer, 100);
303 ASSERT_LE(1124U, debug_malloc_usable_size(pointer));
304 debug_free(pointer);
305
306 ASSERT_STREQ("", getFakeLogBuf().c_str());
307 ASSERT_STREQ("", getFakeLogPrint().c_str());
308 }
309
TEST_F(MallocDebugTest,front_guard)310 TEST_F(MallocDebugTest, front_guard) {
311 Init("front_guard=32");
312
313 // Create a buffer for doing comparisons.
314 std::vector<uint8_t> buffer(32);
315 memset(buffer.data(), 0xaa, buffer.size());
316
317 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
318 ASSERT_TRUE(pointer != nullptr);
319 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
320 memset(pointer, 0xff, 100);
321 debug_free(pointer);
322
323 // Loop through a bunch alignments.
324 for (size_t alignment = 1; alignment <= 256; alignment++) {
325 pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
326 ASSERT_TRUE(pointer != nullptr);
327 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
328 size_t alignment_mask = alignment - 1;
329 if (!powerof2(alignment)) {
330 alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
331 }
332 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask);
333 memset(pointer, 0xff, 100);
334 debug_free(pointer);
335 }
336
337 pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
338 ASSERT_TRUE(pointer != nullptr);
339 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
340 for (size_t i = 0; i < 100; i++) {
341 ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
342 }
343 debug_free(pointer);
344
345 pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
346 ASSERT_TRUE(pointer != nullptr);
347 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
348 memset(pointer, 0xff, 100);
349 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
350 ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
351 memset(pointer, 0xff, 200);
352 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
353 ASSERT_TRUE(pointer == nullptr);
354
355 ASSERT_STREQ("", getFakeLogBuf().c_str());
356 ASSERT_STREQ("", getFakeLogPrint().c_str());
357 }
358
TEST_F(MallocDebugTest,realloc_memalign_memory)359 TEST_F(MallocDebugTest, realloc_memalign_memory) {
360 Init("rear_guard");
361
362 void* pointer = debug_memalign(1024, 100);
363 ASSERT_TRUE(pointer != nullptr);
364 memset(pointer, 0, 100);
365
366 pointer = debug_realloc(pointer, 1024);
367 ASSERT_TRUE(pointer != nullptr);
368 ASSERT_EQ(1024U, debug_malloc_usable_size(pointer));
369 memset(pointer, 0, 1024);
370 debug_free(pointer);
371
372 ASSERT_STREQ("", getFakeLogBuf().c_str());
373 ASSERT_STREQ("", getFakeLogPrint().c_str());
374 }
375
TEST_F(MallocDebugTest,front_guard_corrupted)376 TEST_F(MallocDebugTest, front_guard_corrupted) {
377 Init("front_guard=32");
378
379 backtrace_fake_add(std::vector<uintptr_t> {0x1, 0x2, 0x3});
380
381 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
382 ASSERT_TRUE(pointer != nullptr);
383 pointer[-32] = 0x00;
384 pointer[-15] = 0x02;
385 debug_free(pointer);
386
387 std::string expected_log(DIVIDER);
388 expected_log += android::base::StringPrintf(
389 "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED FRONT GUARD\n", pointer);
390 expected_log += "6 malloc_debug allocation[-32] = 0x00 (expected 0xaa)\n";
391 expected_log += "6 malloc_debug allocation[-15] = 0x02 (expected 0xaa)\n";
392 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
393 expected_log += "6 malloc_debug #00 pc 0x1\n";
394 expected_log += "6 malloc_debug #01 pc 0x2\n";
395 expected_log += "6 malloc_debug #02 pc 0x3\n";
396 expected_log += DIVIDER;
397 ASSERT_STREQ("", getFakeLogBuf().c_str());
398 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
399 }
400
TEST_F(MallocDebugTest,rear_guard)401 TEST_F(MallocDebugTest, rear_guard) {
402 Init("rear_guard=32");
403
404 // Create a buffer for doing comparisons.
405 std::vector<uint8_t> buffer(32);
406 memset(buffer.data(), 0xbb, buffer.size());
407
408 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
409 ASSERT_TRUE(pointer != nullptr);
410 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
411 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
412 memset(pointer, 0xff, 100);
413 debug_free(pointer);
414
415 // Loop through a bunch alignments.
416 for (size_t alignment = 1; alignment <= 256; alignment++) {
417 pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
418 ASSERT_TRUE(pointer != nullptr);
419 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
420 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
421 size_t alignment_mask = alignment - 1;
422 if (!powerof2(alignment)) {
423 alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
424 }
425 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask)
426 << "Failed at alignment " << alignment << " mask " << alignment_mask;
427 memset(pointer, 0xff, 100);
428 debug_free(pointer);
429 }
430
431 pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
432 ASSERT_TRUE(pointer != nullptr);
433 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
434 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
435 for (size_t i = 0; i < 100; i++) {
436 ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
437 }
438 debug_free(pointer);
439
440 pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
441 ASSERT_TRUE(pointer != nullptr);
442 ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
443 memset(pointer, 0xff, 100);
444 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
445 ASSERT_TRUE(memcmp(buffer.data(), &pointer[200], buffer.size()) == 0);
446 for (size_t i = 0; i < 100; i++) {
447 ASSERT_EQ(0xff, pointer[i]) << "debug_realloc not copied byte at " << i;
448 }
449 memset(pointer, 0xff, 200);
450 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
451 ASSERT_TRUE(pointer == nullptr);
452
453 ASSERT_STREQ("", getFakeLogBuf().c_str());
454 ASSERT_STREQ("", getFakeLogPrint().c_str());
455 }
456
TEST_F(MallocDebugTest,rear_guard_corrupted)457 TEST_F(MallocDebugTest, rear_guard_corrupted) {
458 Init("rear_guard=32");
459
460 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
461
462 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
463 ASSERT_TRUE(pointer != nullptr);
464 pointer[130] = 0xbf;
465 pointer[131] = 0x00;
466 debug_free(pointer);
467
468 std::string expected_log(DIVIDER);
469 expected_log += android::base::StringPrintf(
470 "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
471 expected_log += "6 malloc_debug allocation[130] = 0xbf (expected 0xbb)\n";
472 expected_log += "6 malloc_debug allocation[131] = 0x00 (expected 0xbb)\n";
473 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
474 expected_log += "6 malloc_debug #00 pc 0x100\n";
475 expected_log += "6 malloc_debug #01 pc 0x200\n";
476 expected_log += "6 malloc_debug #02 pc 0x300\n";
477 expected_log += DIVIDER;
478
479 ASSERT_STREQ("", getFakeLogBuf().c_str());
480 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
481 }
482
TEST_F(MallocDebugTest,rear_guard_corrupted_after_realloc_shrink)483 TEST_F(MallocDebugTest, rear_guard_corrupted_after_realloc_shrink) {
484 Init("rear_guard=32");
485
486 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
487
488 void* pointer = debug_malloc(200);
489 ASSERT_TRUE(pointer != nullptr);
490 memset(pointer, 0, 200);
491
492 uint8_t* pointer_shrink = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 100));
493 pointer_shrink[130] = 0xbf;
494 pointer_shrink[131] = 0x00;
495 debug_free(pointer);
496
497 // When shrinking sizes, the same pointer should be returned.
498 ASSERT_EQ(pointer, pointer_shrink);
499
500 std::string expected_log(DIVIDER);
501 expected_log += android::base::StringPrintf(
502 "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
503 expected_log += "6 malloc_debug allocation[130] = 0xbf (expected 0xbb)\n";
504 expected_log += "6 malloc_debug allocation[131] = 0x00 (expected 0xbb)\n";
505 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
506 expected_log += "6 malloc_debug #00 pc 0x100\n";
507 expected_log += "6 malloc_debug #01 pc 0x200\n";
508 expected_log += "6 malloc_debug #02 pc 0x300\n";
509 expected_log += DIVIDER;
510
511 ASSERT_STREQ("", getFakeLogBuf().c_str());
512 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
513 }
514
TEST_F(MallocDebugTest,tag_corrupted)515 TEST_F(MallocDebugTest, tag_corrupted) {
516 Init("rear_guard=32");
517
518 backtrace_fake_add(std::vector<uintptr_t> {0xa, 0xb, 0xc});
519
520 backtrace_fake_add(std::vector<uintptr_t> {0xaa, 0xbb, 0xcc});
521
522 backtrace_fake_add(std::vector<uintptr_t> {0xaaa, 0xbbb, 0xccc});
523
524 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
525 ASSERT_TRUE(pointer != nullptr);
526 uint8_t saved = pointer[-get_tag_offset()];
527 pointer[-get_tag_offset()] = 0x00;
528 ASSERT_EQ(0U, debug_malloc_usable_size(pointer));
529 ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
530 debug_free(pointer);
531
532 // Fix the pointer and really free it.
533 pointer[-get_tag_offset()] = saved;
534 debug_free(pointer);
535
536 std::string expected_log(DIVIDER);
537 expected_log += android::base::StringPrintf(
538 "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (malloc_usable_size)\n",
539 pointer);
540 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
541 expected_log += "6 malloc_debug #00 pc 0xa\n";
542 expected_log += "6 malloc_debug #01 pc 0xb\n";
543 expected_log += "6 malloc_debug #02 pc 0xc\n";
544 expected_log += DIVIDER;
545
546 expected_log += DIVIDER;
547 expected_log += android::base::StringPrintf(
548 "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (realloc)\n",
549 pointer);
550 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
551 expected_log += "6 malloc_debug #00 pc 0xaa\n";
552 expected_log += "6 malloc_debug #01 pc 0xbb\n";
553 expected_log += "6 malloc_debug #02 pc 0xcc\n";
554 expected_log += DIVIDER;
555
556 expected_log += DIVIDER;
557 expected_log += android::base::StringPrintf(
558 "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (free)\n",
559 pointer);
560 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
561 expected_log += "6 malloc_debug #00 pc 0xaaa\n";
562 expected_log += "6 malloc_debug #01 pc 0xbbb\n";
563 expected_log += "6 malloc_debug #02 pc 0xccc\n";
564 expected_log += DIVIDER;
565
566 ASSERT_STREQ("", getFakeLogBuf().c_str());
567 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
568 }
569
TEST_F(MallocDebugTest,leak_track_no_frees)570 TEST_F(MallocDebugTest, leak_track_no_frees) {
571 Init("leak_track");
572
573 void* pointer1 = debug_malloc(200);
574 ASSERT_TRUE(pointer1 != nullptr);
575 memset(pointer1, 0, 200);
576
577 void* pointer2 = debug_malloc(128);
578 ASSERT_TRUE(pointer2 != nullptr);
579 memset(pointer2, 0, 128);
580
581 void* pointer3 = debug_malloc(1024);
582 ASSERT_TRUE(pointer3 != nullptr);
583 memset(pointer3, 0, 1024);
584
585 debug_finalize();
586 initialized = false;
587
588 ASSERT_STREQ("", getFakeLogBuf().c_str());
589 std::string expected_log = android::base::StringPrintf(
590 "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
591 pointer3);
592 expected_log += android::base::StringPrintf(
593 "6 malloc_debug +++ malloc_testing leaked block of size 200 at %p (leak 2 of 3)\n",
594 pointer1);
595 expected_log += android::base::StringPrintf(
596 "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 3 of 3)\n",
597 pointer2);
598 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
599 }
600
TEST_F(MallocDebugTest,leak_track_no_frees_with_backtrace)601 TEST_F(MallocDebugTest, leak_track_no_frees_with_backtrace) {
602 Init("leak_track backtrace");
603
604 backtrace_fake_add(std::vector<uintptr_t> {0x1000, 0x2000, 0x3000});
605
606 void* pointer1 = debug_malloc(100);
607 ASSERT_TRUE(pointer1 != nullptr);
608 memset(pointer1, 0, 100);
609
610 backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000, 0xc000, 0xd000});
611
612 void* pointer2 = debug_malloc(128);
613 ASSERT_TRUE(pointer2 != nullptr);
614 memset(pointer2, 0, 128);
615
616 backtrace_fake_add(std::vector<uintptr_t> {0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
617
618 void* pointer3 = debug_malloc(1024);
619 ASSERT_TRUE(pointer3 != nullptr);
620 memset(pointer3, 0, 1024);
621
622 debug_finalize();
623 initialized = false;
624
625 ASSERT_STREQ("", getFakeLogBuf().c_str());
626 std::string expected_log = android::base::StringPrintf(
627 "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
628 pointer3);
629 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
630 expected_log += "6 malloc_debug #00 pc 0xfe000\n";
631 expected_log += "6 malloc_debug #01 pc 0xde000\n";
632 expected_log += "6 malloc_debug #02 pc 0xce000\n";
633 expected_log += "6 malloc_debug #03 pc 0xbe000\n";
634 expected_log += "6 malloc_debug #04 pc 0xae000\n";
635
636 expected_log += android::base::StringPrintf(
637 "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 2 of 3)\n",
638 pointer2);
639 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
640 expected_log += "6 malloc_debug #00 pc 0xa000\n";
641 expected_log += "6 malloc_debug #01 pc 0xb000\n";
642 expected_log += "6 malloc_debug #02 pc 0xc000\n";
643 expected_log += "6 malloc_debug #03 pc 0xd000\n";
644
645 expected_log += android::base::StringPrintf(
646 "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 3 of 3)\n",
647 pointer1);
648 expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
649 expected_log += "6 malloc_debug #00 pc 0x1000\n";
650 expected_log += "6 malloc_debug #01 pc 0x2000\n";
651 expected_log += "6 malloc_debug #02 pc 0x3000\n";
652
653 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
654 }
655
TEST_F(MallocDebugTest,leak_track_frees)656 TEST_F(MallocDebugTest, leak_track_frees) {
657 Init("leak_track");
658
659 void* pointer1 = debug_malloc(390);
660 ASSERT_TRUE(pointer1 != nullptr);
661 memset(pointer1, 0, 390);
662 debug_free(pointer1);
663
664 pointer1 = debug_malloc(100);
665 ASSERT_TRUE(pointer1 != nullptr);
666 memset(pointer1, 0, 100);
667
668 void* pointer2 = debug_malloc(250);
669 ASSERT_TRUE(pointer2 != nullptr);
670 memset(pointer2, 0, 250);
671 debug_free(pointer2);
672
673 pointer2 = debug_malloc(450);
674 ASSERT_TRUE(pointer2 != nullptr);
675 memset(pointer2, 0, 450);
676
677 void* pointer3 = debug_malloc(999);
678 ASSERT_TRUE(pointer3 != nullptr);
679 memset(pointer3, 0, 999);
680 debug_free(pointer2);
681
682 debug_finalize();
683 initialized = false;
684
685 ASSERT_STREQ("", getFakeLogBuf().c_str());
686 std::string expected_log = android::base::StringPrintf(
687 "6 malloc_debug +++ malloc_testing leaked block of size 999 at %p (leak 1 of 2)\n",
688 pointer3);
689 expected_log += android::base::StringPrintf(
690 "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 2 of 2)\n",
691 pointer1);
692 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
693 }
694
TEST_F(MallocDebugTest,free_track)695 TEST_F(MallocDebugTest, free_track) {
696 Init("free_track=5 free_track_backtrace_num_frames=0");
697
698 void* pointers[10];
699 for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
700 pointers[i] = debug_malloc(100 + i);
701 ASSERT_TRUE(pointers[i] != nullptr);
702 memset(pointers[i], 0, 100 + i);
703 debug_free(pointers[i]);
704 }
705
706 // Large allocations (> 4096) to verify large allocation checks.
707 void* pointer = debug_malloc(8192);
708 ASSERT_TRUE(pointer != nullptr);
709 memset(pointer, 0, 8192);
710 debug_free(pointer);
711
712 pointer = debug_malloc(9000);
713 ASSERT_TRUE(pointer != nullptr);
714 memset(pointer, 0, 9000);
715 debug_free(pointer);
716
717 ASSERT_STREQ("", getFakeLogBuf().c_str());
718 ASSERT_STREQ("", getFakeLogPrint().c_str());
719 }
720
TEST_F(MallocDebugTest,free_track_use_after_free)721 TEST_F(MallocDebugTest, free_track_use_after_free) {
722 Init("free_track=5 free_track_backtrace_num_frames=0");
723
724 uint8_t* pointers[5];
725 for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
726 pointers[i] = reinterpret_cast<uint8_t*>(debug_malloc(100 + i));
727 ASSERT_TRUE(pointers[i] != nullptr);
728 memset(pointers[i], 0, 100 + i);
729 debug_free(pointers[i]);
730 }
731
732 // Stomp on the data.
733 pointers[0][20] = 0xaf;
734 pointers[0][99] = 0x12;
735
736 pointers[3][3] = 0x34;
737
738 // Large allocations (> 4096) to verify large allocation checks.
739 uint8_t* pointer1_large = reinterpret_cast<uint8_t*>(debug_malloc(8192));
740 ASSERT_TRUE(pointer1_large != nullptr);
741 memset(pointer1_large, 0, 8192);
742 debug_free(pointer1_large);
743
744 pointer1_large[4095] = 0x90;
745 pointer1_large[4100] = 0x56;
746 pointer1_large[8191] = 0x89;
747
748 uint8_t* pointer2_large = reinterpret_cast<uint8_t*>(debug_malloc(9000));
749 ASSERT_TRUE(pointer2_large != nullptr);
750 memset(pointer2_large, 0, 9000);
751 debug_free(pointer2_large);
752
753 pointer2_large[8200] = 0x78;
754
755 // Do a bunch of alloc and free to verify the above frees are checked.
756 for (size_t i = 0; i < 10; i++) {
757 void* flush_pointer = debug_malloc(100+i);
758 ASSERT_TRUE(flush_pointer != nullptr);
759 memset(flush_pointer, 0, 100 + i);
760 debug_free(flush_pointer);
761 }
762
763 ASSERT_STREQ("", getFakeLogBuf().c_str());
764 std::string expected_log(DIVIDER);
765 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[0]);
766 expected_log += "6 malloc_debug allocation[20] = 0xaf (expected 0xef)\n";
767 expected_log += "6 malloc_debug allocation[99] = 0x12 (expected 0xef)\n";
768 expected_log += DIVIDER;
769 expected_log += DIVIDER;
770 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[3]);
771 expected_log += "6 malloc_debug allocation[3] = 0x34 (expected 0xef)\n";
772 expected_log += DIVIDER;
773 expected_log += DIVIDER;
774 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer1_large);
775 expected_log += "6 malloc_debug allocation[4095] = 0x90 (expected 0xef)\n";
776 expected_log += "6 malloc_debug allocation[4100] = 0x56 (expected 0xef)\n";
777 expected_log += "6 malloc_debug allocation[8191] = 0x89 (expected 0xef)\n";
778 expected_log += DIVIDER;
779 expected_log += DIVIDER;
780 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer2_large);
781 expected_log += "6 malloc_debug allocation[8200] = 0x78 (expected 0xef)\n";
782 expected_log += DIVIDER;
783 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
784 }
785
TEST_F(MallocDebugTest,free_track_use_after_free_finalize)786 TEST_F(MallocDebugTest, free_track_use_after_free_finalize) {
787 Init("free_track=100 free_track_backtrace_num_frames=0");
788
789 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
790 ASSERT_TRUE(pointer != nullptr);
791 memset(pointer, 0, 100);
792 debug_free(pointer);
793
794 pointer[56] = 0x91;
795
796 ASSERT_STREQ("", getFakeLogBuf().c_str());
797 ASSERT_STREQ("", getFakeLogPrint().c_str());
798
799 debug_finalize();
800 initialized = false;
801
802 ASSERT_STREQ("", getFakeLogBuf().c_str());
803 std::string expected_log(DIVIDER);
804 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
805 expected_log += "6 malloc_debug allocation[56] = 0x91 (expected 0xef)\n";
806 expected_log += DIVIDER;
807 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
808 }
809
TEST_F(MallocDebugTest,free_track_use_after_free_with_backtrace)810 TEST_F(MallocDebugTest, free_track_use_after_free_with_backtrace) {
811 Init("free_track=100");
812
813 // Free backtrace.
814 backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
815
816 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(200));
817 ASSERT_TRUE(pointer != nullptr);
818 memset(pointer, 0, 200);
819 debug_free(pointer);
820
821 pointer[101] = 0xab;
822
823 ASSERT_STREQ("", getFakeLogBuf().c_str());
824 ASSERT_STREQ("", getFakeLogPrint().c_str());
825
826 debug_finalize();
827 initialized = false;
828
829 ASSERT_STREQ("", getFakeLogBuf().c_str());
830 std::string expected_log(DIVIDER);
831 expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
832 expected_log += "6 malloc_debug allocation[101] = 0xab (expected 0xef)\n";
833 expected_log += "6 malloc_debug Backtrace at time of free:\n";
834 expected_log += "6 malloc_debug #00 pc 0xfa\n";
835 expected_log += "6 malloc_debug #01 pc 0xeb\n";
836 expected_log += "6 malloc_debug #02 pc 0xdc\n";
837 expected_log += DIVIDER;
838 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
839 }
840
TEST_F(MallocDebugTest,free_track_use_after_free_call_realloc)841 TEST_F(MallocDebugTest, free_track_use_after_free_call_realloc) {
842 Init("free_track=100");
843
844 // Free backtrace.
845 backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
846 // Backtrace at realloc.
847 backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
848
849 void* pointer = debug_malloc(200);
850 ASSERT_TRUE(pointer != nullptr);
851 memset(pointer, 0, 200);
852 debug_free(pointer);
853
854 // Choose a size that should not trigger a realloc to verify tag is
855 // verified early.
856 ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
857
858 ASSERT_STREQ("", getFakeLogBuf().c_str());
859 std::string expected_log(DIVIDER);
860 expected_log += android::base::StringPrintf(
861 "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (realloc)\n", pointer);
862 expected_log += "6 malloc_debug Backtrace of original free:\n";
863 expected_log += "6 malloc_debug #00 pc 0xfa\n";
864 expected_log += "6 malloc_debug #01 pc 0xeb\n";
865 expected_log += "6 malloc_debug #02 pc 0xdc\n";
866 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
867 expected_log += "6 malloc_debug #00 pc 0x12\n";
868 expected_log += "6 malloc_debug #01 pc 0x22\n";
869 expected_log += "6 malloc_debug #02 pc 0x32\n";
870 expected_log += "6 malloc_debug #03 pc 0x42\n";
871 expected_log += DIVIDER;
872 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
873 }
874
TEST_F(MallocDebugTest,free_track_use_after_free_call_free)875 TEST_F(MallocDebugTest, free_track_use_after_free_call_free) {
876 Init("free_track=100");
877
878 // Free backtrace.
879 backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
880 // Backtrace at second free.
881 backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
882
883 void* pointer = debug_malloc(200);
884 ASSERT_TRUE(pointer != nullptr);
885 memset(pointer, 0, 200);
886 debug_free(pointer);
887
888 debug_free(pointer);
889
890 ASSERT_STREQ("", getFakeLogBuf().c_str());
891 std::string expected_log(DIVIDER);
892 expected_log += android::base::StringPrintf(
893 "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (free)\n", pointer);
894 expected_log += "6 malloc_debug Backtrace of original free:\n";
895 expected_log += "6 malloc_debug #00 pc 0xfa\n";
896 expected_log += "6 malloc_debug #01 pc 0xeb\n";
897 expected_log += "6 malloc_debug #02 pc 0xdc\n";
898 expected_log += "6 malloc_debug Backtrace at time of failure:\n";
899 expected_log += "6 malloc_debug #00 pc 0x12\n";
900 expected_log += "6 malloc_debug #01 pc 0x22\n";
901 expected_log += "6 malloc_debug #02 pc 0x32\n";
902 expected_log += "6 malloc_debug #03 pc 0x42\n";
903 expected_log += DIVIDER;
904 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
905 }
906
TEST_F(MallocDebugTest,free_track_header_tag_corrupted)907 TEST_F(MallocDebugTest, free_track_header_tag_corrupted) {
908 Init("free_track=100 free_track_backtrace_num_frames=0");
909
910 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
911 ASSERT_TRUE(pointer != nullptr);
912 memset(pointer, 0, 100);
913 debug_free(pointer);
914
915 pointer[-get_tag_offset()] = 0x00;
916
917 ASSERT_STREQ("", getFakeLogBuf().c_str());
918 ASSERT_STREQ("", getFakeLogPrint().c_str());
919
920 debug_finalize();
921 initialized = false;
922
923 ASSERT_STREQ("", getFakeLogBuf().c_str());
924 std::string expected_log(DIVIDER);
925 expected_log += android::base::StringPrintf(
926 "6 malloc_debug +++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x1cc7dc00 AFTER FREE\n",
927 pointer);
928 expected_log += DIVIDER;
929 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
930 }
931
TEST_F(MallocDebugTest,free_track_multiple_thread)932 TEST_F(MallocDebugTest, free_track_multiple_thread) {
933 Init("free_track=10 free_track_backtrace_num_frames=0");
934
935 std::vector<std::thread*> threads(1000);
936 for (size_t i = 0; i < threads.size(); i++) {
937 threads[i] = new std::thread([](){
938 for (size_t j = 0; j < 100; j++) {
939 void* mem = debug_malloc(100);
940 write(0, mem, 0);
941 debug_free(mem);
942 }
943 });
944 }
945 for (size_t i = 0; i < threads.size(); i++) {
946 threads[i]->join();
947 delete threads[i];
948 }
949
950 ASSERT_STREQ("", getFakeLogBuf().c_str());
951 ASSERT_STREQ("", getFakeLogPrint().c_str());
952 }
953
TEST_F(MallocDebugTest,get_malloc_leak_info_invalid)954 TEST_F(MallocDebugTest, get_malloc_leak_info_invalid) {
955 Init("fill");
956
957 uint8_t* info;
958 size_t overall_size;
959 size_t info_size;
960 size_t total_memory;
961 size_t backtrace_size;
962
963 std::string expected_log("6 malloc_debug get_malloc_leak_info: At least one invalid parameter.\n");
964
965 debug_get_malloc_leak_info(nullptr, &overall_size, &info_size, &total_memory, &backtrace_size);
966 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
967
968 resetLogs();
969 debug_get_malloc_leak_info(&info, nullptr, &info_size, &total_memory, &backtrace_size);
970 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
971
972 resetLogs();
973 debug_get_malloc_leak_info(&info, &overall_size, nullptr, &total_memory, &backtrace_size);
974 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
975
976 resetLogs();
977 debug_get_malloc_leak_info(&info, &overall_size, &info_size, nullptr, &backtrace_size);
978 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
979
980 resetLogs();
981 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, nullptr);
982 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
983 }
984
TEST_F(MallocDebugTest,get_malloc_leak_info_not_enabled)985 TEST_F(MallocDebugTest, get_malloc_leak_info_not_enabled) {
986 Init("fill");
987
988 uint8_t* info;
989 size_t overall_size;
990 size_t info_size;
991 size_t total_memory;
992 size_t backtrace_size;
993
994 ASSERT_STREQ("", getFakeLogBuf().c_str());
995 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
996 std::string expected_log(
997 "6 malloc_debug get_malloc_leak_info: Allocations not being tracked, to enable "
998 "set the option 'backtrace'.\n");
999 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1000 }
1001
1002 struct InfoEntry {
1003 size_t size;
1004 size_t num_allocations;
1005 uintptr_t frames[0];
1006 } __attribute__((packed));
1007
TEST_F(MallocDebugTest,get_malloc_leak_info_empty)1008 TEST_F(MallocDebugTest, get_malloc_leak_info_empty) {
1009 Init("backtrace");
1010
1011 uint8_t* info;
1012 size_t overall_size;
1013 size_t info_size;
1014 size_t total_memory;
1015 size_t backtrace_size;
1016
1017 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1018 ASSERT_TRUE(info == nullptr);
1019 ASSERT_EQ(0U, overall_size);
1020 ASSERT_EQ(0U, info_size);
1021 ASSERT_EQ(0U, total_memory);
1022 ASSERT_EQ(0U, backtrace_size);
1023
1024 ASSERT_STREQ("", getFakeLogBuf().c_str());
1025 ASSERT_STREQ("", getFakeLogPrint().c_str());
1026 }
1027
TEST_F(MallocDebugTest,get_malloc_leak_info_single)1028 TEST_F(MallocDebugTest, get_malloc_leak_info_single) {
1029 Init("backtrace");
1030
1031 // Create the expected info buffer.
1032 size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1033 std::vector<uint8_t> expected_info(individual_size);
1034 memset(expected_info.data(), 0, individual_size);
1035
1036 InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
1037 entry->size = 200;
1038 entry->num_allocations = 1;
1039 entry->frames[0] = 0xf;
1040 entry->frames[1] = 0xe;
1041 entry->frames[2] = 0xd;
1042
1043 backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd});
1044
1045 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(entry->size));
1046 ASSERT_TRUE(pointer != nullptr);
1047 memset(pointer, 0, entry->size);
1048
1049 uint8_t* info;
1050 size_t overall_size;
1051 size_t info_size;
1052 size_t total_memory;
1053 size_t backtrace_size;
1054
1055 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1056 ASSERT_TRUE(info != nullptr);
1057 ASSERT_EQ(individual_size, overall_size);
1058 ASSERT_EQ(individual_size, info_size);
1059 ASSERT_EQ(200U, total_memory);
1060 ASSERT_EQ(16U, backtrace_size);
1061 ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
1062
1063 debug_free_malloc_leak_info(info);
1064
1065 debug_free(pointer);
1066
1067 ASSERT_STREQ("", getFakeLogBuf().c_str());
1068 ASSERT_STREQ("", getFakeLogPrint().c_str());
1069 }
1070
TEST_F(MallocDebugTest,get_malloc_leak_info_multi)1071 TEST_F(MallocDebugTest, get_malloc_leak_info_multi) {
1072 Init("backtrace=16");
1073
1074 // Create the expected info buffer.
1075 size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1076 std::vector<uint8_t> expected_info(individual_size * 3);
1077 memset(expected_info.data(), 0, individual_size * 3);
1078
1079 InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
1080 InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
1081 reinterpret_cast<uintptr_t>(entry0) + individual_size);
1082 InfoEntry* entry2 = reinterpret_cast<InfoEntry*>(
1083 reinterpret_cast<uintptr_t>(entry1) + individual_size);
1084
1085 // These values will be in the reverse order that we create.
1086 entry2->size = 500;
1087 entry2->num_allocations = 1;
1088 entry2->frames[0] = 0xf;
1089 entry2->frames[1] = 0xe;
1090 entry2->frames[2] = 0xd;
1091 entry2->frames[3] = 0xc;
1092
1093 backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
1094
1095 uint8_t* pointers[3];
1096
1097 pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry2->size));
1098 ASSERT_TRUE(pointers[0] != nullptr);
1099 memset(pointers[0], 0, entry2->size);
1100
1101 entry1->size = 4100;
1102 entry1->num_allocations = 1;
1103 for (size_t i = 0; i < 16; i++) {
1104 entry1->frames[i] = 0xbc000 + i;
1105 }
1106
1107 backtrace_fake_add(
1108 std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
1109 0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
1110 0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
1111
1112 pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
1113 ASSERT_TRUE(pointers[1] != nullptr);
1114 memset(pointers[1], 0, entry1->size);
1115
1116 entry0->size = 9000;
1117 entry0->num_allocations = 1;
1118
1119 entry0->frames[0] = 0x104;
1120 backtrace_fake_add(std::vector<uintptr_t> {0x104});
1121
1122 pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
1123 ASSERT_TRUE(pointers[2] != nullptr);
1124 memset(pointers[2], 0, entry0->size);
1125
1126 uint8_t* info;
1127 size_t overall_size;
1128 size_t info_size;
1129 size_t total_memory;
1130 size_t backtrace_size;
1131
1132 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1133 ASSERT_TRUE(info != nullptr);
1134 ASSERT_EQ(individual_size * 3, overall_size);
1135 ASSERT_EQ(individual_size, info_size);
1136 ASSERT_EQ(500U + 4100U + 9000U, total_memory);
1137 ASSERT_EQ(16U, backtrace_size);
1138 ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
1139
1140 debug_free_malloc_leak_info(info);
1141
1142 debug_free(pointers[0]);
1143 debug_free(pointers[1]);
1144 debug_free(pointers[2]);
1145
1146 ASSERT_STREQ("", getFakeLogBuf().c_str());
1147 ASSERT_STREQ("", getFakeLogPrint().c_str());
1148 }
1149
TEST_F(MallocDebugTest,get_malloc_leak_info_multi_skip_empty_backtrace)1150 TEST_F(MallocDebugTest, get_malloc_leak_info_multi_skip_empty_backtrace) {
1151 Init("backtrace=16");
1152
1153 // Create the expected info buffer.
1154 size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1155 std::vector<uint8_t> expected_info(individual_size * 2);
1156 memset(expected_info.data(), 0, individual_size * 2);
1157
1158 InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
1159 InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
1160 reinterpret_cast<uintptr_t>(entry0) + individual_size);
1161
1162 // These values will be in the reverse order that we create.
1163 entry1->size = 500;
1164 entry1->num_allocations = 1;
1165 entry1->frames[0] = 0xf;
1166 entry1->frames[1] = 0xe;
1167 entry1->frames[2] = 0xd;
1168 entry1->frames[3] = 0xc;
1169
1170 backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
1171
1172 uint8_t* pointers[3];
1173
1174 pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
1175 ASSERT_TRUE(pointers[0] != nullptr);
1176 memset(pointers[0], 0, entry1->size);
1177
1178 entry0->size = 4100;
1179 entry0->num_allocations = 1;
1180 for (size_t i = 0; i < 16; i++) {
1181 entry0->frames[i] = 0xbc000 + i;
1182 }
1183
1184 backtrace_fake_add(
1185 std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
1186 0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
1187 0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
1188
1189 pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
1190 ASSERT_TRUE(pointers[1] != nullptr);
1191 memset(pointers[1], 0, entry0->size);
1192
1193 pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(10000));
1194 ASSERT_TRUE(pointers[2] != nullptr);
1195 memset(pointers[2], 0, 10000);
1196
1197 uint8_t* info;
1198 size_t overall_size;
1199 size_t info_size;
1200 size_t total_memory;
1201 size_t backtrace_size;
1202
1203 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1204 ASSERT_TRUE(info != nullptr);
1205 ASSERT_EQ(individual_size * 2, overall_size);
1206 ASSERT_EQ(individual_size, info_size);
1207 ASSERT_EQ(500U + 4100U, total_memory);
1208 ASSERT_EQ(16U, backtrace_size);
1209 ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
1210
1211 debug_free_malloc_leak_info(info);
1212
1213 debug_free(pointers[0]);
1214 debug_free(pointers[1]);
1215 debug_free(pointers[2]);
1216
1217 ASSERT_STREQ("", getFakeLogBuf().c_str());
1218 ASSERT_STREQ("", getFakeLogPrint().c_str());
1219 }
1220
TEST_F(MallocDebugTest,realloc_usable_size)1221 TEST_F(MallocDebugTest, realloc_usable_size) {
1222 Init("front_guard");
1223
1224 // Verify that if the usable size > size of alloc, that realloc
1225 // copies the bytes in the usable size not just the size.
1226 // This assumes that an allocation of size 1 returns usable size > 1.
1227 // If this isn't true, this test is not going to do anything.
1228 uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(1));
1229 ASSERT_TRUE(pointer != nullptr);
1230 size_t usable_size = debug_malloc_usable_size(pointer);
1231 memset(pointer, 0xaa, usable_size);
1232 pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, usable_size + 10));
1233 ASSERT_TRUE(pointer != nullptr);
1234 ASSERT_LE(usable_size + 10, debug_malloc_usable_size(pointer));
1235 for (size_t i = 0; i < usable_size; i++) {
1236 ASSERT_EQ(0xaa, pointer[i]) << "Failed compare at byte " << i;
1237 }
1238 debug_free(pointer);
1239
1240 ASSERT_STREQ("", getFakeLogBuf().c_str());
1241 ASSERT_STREQ("", getFakeLogPrint().c_str());
1242 }
1243
TEST_F(MallocDebugTest,backtrace_enable_on_signal)1244 TEST_F(MallocDebugTest, backtrace_enable_on_signal) {
1245 Init("backtrace_enable_on_signal=20");
1246
1247 size_t individual_size = 2 * sizeof(size_t) + 20 * sizeof(uintptr_t);
1248
1249 backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
1250 backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300, 0x400});
1251 backtrace_fake_add(std::vector<uintptr_t> {0x500, 0xa00, 0xb00});
1252
1253 // First allocation should not actually attempt to get the backtrace.
1254 void* pointer = debug_malloc(10);
1255 ASSERT_TRUE(pointer != nullptr);
1256
1257 uint8_t* info;
1258 size_t overall_size;
1259 size_t info_size;
1260 size_t total_memory;
1261 size_t backtrace_size;
1262
1263 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1264 ASSERT_TRUE(info == nullptr);
1265 ASSERT_EQ(0U, overall_size);
1266 ASSERT_EQ(0U, info_size);
1267 ASSERT_EQ(0U, total_memory);
1268 ASSERT_EQ(0U, backtrace_size);
1269 debug_free(pointer);
1270
1271 debug_free_malloc_leak_info(info);
1272
1273 // Send the signal to enable.
1274 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 19) == 0);
1275 sleep(1);
1276
1277 pointer = debug_malloc(100);
1278 ASSERT_TRUE(pointer != nullptr);
1279
1280 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1281 ASSERT_TRUE(info != nullptr);
1282 ASSERT_EQ(individual_size, overall_size);
1283 ASSERT_EQ(individual_size, info_size);
1284 ASSERT_EQ(100U, total_memory);
1285 ASSERT_EQ(20U, backtrace_size);
1286 uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
1287 ASSERT_EQ(0xbc000U, ips[0]);
1288 ASSERT_EQ(0xecd00U, ips[1]);
1289 ASSERT_EQ(0x12000U, ips[2]);
1290 for (size_t i = 3; i < 20; i++) {
1291 ASSERT_EQ(0U, ips[i]);
1292 }
1293
1294 debug_free(pointer);
1295
1296 debug_free_malloc_leak_info(info);
1297
1298 // Send the signal to disable.
1299 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 19) == 0);
1300 sleep(1);
1301
1302 pointer = debug_malloc(200);
1303 ASSERT_TRUE(pointer != nullptr);
1304
1305 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1306 ASSERT_TRUE(info == nullptr);
1307 ASSERT_EQ(0U, overall_size);
1308 ASSERT_EQ(0U, info_size);
1309 ASSERT_EQ(0U, total_memory);
1310 ASSERT_EQ(0U, backtrace_size);
1311
1312 debug_free(pointer);
1313
1314 debug_free_malloc_leak_info(info);
1315
1316 ASSERT_STREQ("", getFakeLogBuf().c_str());
1317 std::string expected_log = android::base::StringPrintf(
1318 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
1319 SIGRTMAX - 19, getpid());
1320 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1321 }
1322
TEST_F(MallocDebugTest,overflow)1323 TEST_F(MallocDebugTest, overflow) {
1324 Init("guard fill_on_free");
1325
1326 void* pointer = debug_malloc(SIZE_MAX);
1327 ASSERT_TRUE(pointer == nullptr);
1328 ASSERT_EQ(ENOMEM, errno);
1329
1330 pointer = debug_calloc(1, SIZE_MAX);
1331 ASSERT_TRUE(pointer == nullptr);
1332 ASSERT_EQ(ENOMEM, errno);
1333
1334 pointer = debug_calloc(SIZE_MAX, 1);
1335 ASSERT_TRUE(pointer == nullptr);
1336 ASSERT_EQ(ENOMEM, errno);
1337
1338 pointer = debug_calloc(SIZE_MAX/100, 100);
1339 ASSERT_TRUE(pointer == nullptr);
1340 ASSERT_EQ(ENOMEM, errno);
1341
1342 pointer = debug_calloc(100, SIZE_MAX/100);
1343 ASSERT_TRUE(pointer == nullptr);
1344 ASSERT_EQ(ENOMEM, errno);
1345
1346 const size_t size_t_bits = sizeof(size_t) * 8;
1347 const size_t sqrt_size_t = 1ULL << (size_t_bits/2);
1348 pointer = debug_calloc(sqrt_size_t + 1, sqrt_size_t);
1349 ASSERT_TRUE(pointer == nullptr);
1350 ASSERT_EQ(ENOMEM, errno);
1351
1352 pointer = debug_realloc(nullptr, SIZE_MAX);
1353 ASSERT_TRUE(pointer == nullptr);
1354 ASSERT_EQ(ENOMEM, errno);
1355
1356 pointer = debug_malloc(100);
1357 ASSERT_TRUE(pointer != nullptr);
1358 memset(pointer, 0xd0, 100);
1359
1360 void* realloc_pointer = debug_realloc(pointer, SIZE_MAX);
1361 ASSERT_TRUE(realloc_pointer == nullptr);
1362 // Verify the pointer was not freed.
1363 for (size_t i = 0; i < 100; i++) {
1364 ASSERT_EQ(0xd0, reinterpret_cast<uint8_t*>(pointer)[i]) << "Failed checking byte " << i;
1365 }
1366 debug_free(pointer);
1367
1368 ASSERT_STREQ("", getFakeLogBuf().c_str());
1369 ASSERT_STREQ("", getFakeLogPrint().c_str());
1370 }
1371
VerifyZygoteSet(size_t memory_bytes)1372 static void VerifyZygoteSet(size_t memory_bytes) {
1373 size_t expected_info_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
1374 std::vector<uint8_t> expected_info(expected_info_size);
1375 memset(expected_info.data(), 0, expected_info_size);
1376 InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
1377 entry->size = memory_bytes | (1U << 31);
1378 entry->num_allocations = 1;
1379 entry->frames[0] = 0x1;
1380
1381 uint8_t* info;
1382 size_t overall_size;
1383 size_t info_size;
1384 size_t total_memory;
1385 size_t backtrace_size;
1386
1387 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
1388 ASSERT_EQ(expected_info_size, overall_size);
1389 ASSERT_EQ(expected_info_size, info_size);
1390 ASSERT_EQ(memory_bytes, total_memory);
1391 ASSERT_EQ(16U, backtrace_size);
1392 ASSERT_TRUE(memcmp(info, expected_info.data(), expected_info_size) == 0);
1393
1394 debug_free_malloc_leak_info(info);
1395 }
1396
TEST_F(MallocDebugTest,zygote_set)1397 TEST_F(MallocDebugTest, zygote_set) {
1398 // Set all of the options.
1399 Init("guard fill backtrace leak_track free_track=2");
1400
1401 zygote = 1;
1402
1403 backtrace_fake_add(std::vector<uintptr_t> {0x1});
1404
1405 void* pointer = debug_malloc(100);
1406 ASSERT_TRUE(pointer != nullptr);
1407 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
1408 memset(pointer, 0, 100);
1409 VerifyZygoteSet(100);
1410 debug_free(pointer);
1411
1412 backtrace_fake_add(std::vector<uintptr_t> {0x1});
1413 pointer = debug_calloc(10, 20);
1414 ASSERT_TRUE(pointer != nullptr);
1415 ASSERT_EQ(200U, debug_malloc_usable_size(pointer));
1416 VerifyZygoteSet(200);
1417 debug_free(pointer);
1418
1419 backtrace_fake_add(std::vector<uintptr_t> {0x1});
1420 pointer = debug_memalign(128, 300);
1421 ASSERT_TRUE(pointer != nullptr);
1422 ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
1423 memset(pointer, 0, 300);
1424 VerifyZygoteSet(300);
1425 debug_free(pointer);
1426
1427 backtrace_fake_add(std::vector<uintptr_t> {0x1});
1428 pointer = debug_malloc(500);
1429 ASSERT_TRUE(pointer != nullptr);
1430 ASSERT_EQ(500U, debug_malloc_usable_size(pointer));
1431 memset(pointer, 0, 500);
1432 VerifyZygoteSet(500);
1433
1434 backtrace_fake_add(std::vector<uintptr_t> {0x1});
1435 pointer = debug_realloc(pointer, 300);
1436 ASSERT_TRUE(pointer != nullptr);
1437 ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
1438 VerifyZygoteSet(300);
1439 debug_free(pointer);
1440
1441 ASSERT_STREQ("", getFakeLogBuf().c_str());
1442 ASSERT_STREQ("", getFakeLogPrint().c_str());
1443 }
1444
TEST_F(MallocDebugTest,max_size)1445 TEST_F(MallocDebugTest, max_size) {
1446 Init("guard");
1447
1448 void* pointer = debug_malloc(1U << 31);
1449 ASSERT_TRUE(pointer == nullptr);
1450
1451 pointer = debug_calloc(1, 1U << 31);
1452 ASSERT_TRUE(pointer == nullptr);
1453
1454 pointer = debug_calloc(1U << 31, 1);
1455 ASSERT_TRUE(pointer == nullptr);
1456
1457 pointer = debug_memalign(16, 1U << 31);
1458 ASSERT_TRUE(pointer == nullptr);
1459
1460 ASSERT_STREQ("", getFakeLogBuf().c_str());
1461 ASSERT_STREQ("", getFakeLogPrint().c_str());
1462 }
1463
TEST_F(MallocDebugTest,debug_mallinfo)1464 TEST_F(MallocDebugTest, debug_mallinfo) {
1465 Init("guard");
1466
1467 void* pointer = debug_malloc(150);
1468 ASSERT_TRUE(pointer != nullptr);
1469
1470 struct mallinfo mi = debug_mallinfo();
1471 EXPECT_NE(0U, mi.uordblks);
1472
1473 debug_free(pointer);
1474
1475 ASSERT_STREQ("", getFakeLogBuf().c_str());
1476 ASSERT_STREQ("", getFakeLogPrint().c_str());
1477 }
1478
TEST_F(MallocDebugTest,debug_mallopt)1479 TEST_F(MallocDebugTest, debug_mallopt) {
1480 Init("guard");
1481
1482 void* pointer = debug_malloc(150);
1483 ASSERT_TRUE(pointer != nullptr);
1484
1485 EXPECT_EQ(0, debug_mallopt(-1000, 1));
1486
1487 debug_free(pointer);
1488
1489 ASSERT_STREQ("", getFakeLogBuf().c_str());
1490 ASSERT_STREQ("", getFakeLogPrint().c_str());
1491 }
1492
TEST_F(MallocDebugTest,debug_posix_memalign)1493 TEST_F(MallocDebugTest, debug_posix_memalign) {
1494 Init("guard");
1495
1496 void* pointer;
1497 ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 300));
1498 ASSERT_TRUE(pointer != nullptr);
1499 debug_free(pointer);
1500
1501 ASSERT_EQ(EINVAL, debug_posix_memalign(&pointer, 11, 300));
1502
1503 ASSERT_EQ(ENOMEM, debug_posix_memalign(&pointer, 16, SIZE_MAX));
1504
1505 ASSERT_STREQ("", getFakeLogBuf().c_str());
1506 ASSERT_STREQ("", getFakeLogPrint().c_str());
1507 }
1508
1509 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
TEST_F(MallocDebugTest,debug_pvalloc)1510 TEST_F(MallocDebugTest, debug_pvalloc) {
1511 Init("guard");
1512
1513 size_t pagesize = getpagesize();
1514 void* pointer = debug_pvalloc(1);
1515 ASSERT_TRUE(pointer != nullptr);
1516 ASSERT_EQ(pagesize, debug_malloc_usable_size(pointer));
1517 uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
1518 ASSERT_EQ(0U, value);
1519 debug_free(pointer);
1520 }
1521
TEST_F(MallocDebugTest,debug_valloc)1522 TEST_F(MallocDebugTest, debug_valloc) {
1523 Init("guard");
1524
1525 size_t pagesize = getpagesize();
1526 void* pointer = debug_valloc(100);
1527 ASSERT_TRUE(pointer != nullptr);
1528 ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
1529 uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
1530 ASSERT_EQ(0U, value);
1531 debug_free(pointer);
1532 }
1533 #endif
1534
VerifyRecordAllocs()1535 void VerifyRecordAllocs() {
1536 std::string expected;
1537
1538 void* pointer = debug_malloc(10);
1539 ASSERT_TRUE(pointer != nullptr);
1540 expected += android::base::StringPrintf("%d: malloc %p 10\n", getpid(), pointer);
1541 debug_free(pointer);
1542 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1543
1544 pointer = debug_calloc(1, 20);
1545 ASSERT_TRUE(pointer != nullptr);
1546 expected += android::base::StringPrintf("%d: calloc %p 20 1\n", getpid(), pointer);
1547 debug_free(pointer);
1548 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1549
1550 pointer = debug_realloc(nullptr, 30);
1551 ASSERT_TRUE(pointer != nullptr);
1552 expected += android::base::StringPrintf("%d: realloc %p 0x0 30\n", getpid(), pointer);
1553 void* old_pointer = pointer;
1554 pointer = debug_realloc(pointer, 2048);
1555 ASSERT_TRUE(pointer != nullptr);
1556 expected += android::base::StringPrintf("%d: realloc %p %p 2048\n", getpid(),
1557 pointer, old_pointer);
1558 debug_realloc(pointer, 0);
1559 expected += android::base::StringPrintf("%d: realloc 0x0 %p 0\n", getpid(), pointer);
1560
1561 pointer = debug_memalign(16, 40);
1562 ASSERT_TRUE(pointer != nullptr);
1563 expected += android::base::StringPrintf("%d: memalign %p 16 40\n", getpid(), pointer);
1564 debug_free(pointer);
1565 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1566
1567 ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 50));
1568 ASSERT_TRUE(pointer != nullptr);
1569 expected += android::base::StringPrintf("%d: memalign %p 32 50\n", getpid(), pointer);
1570 debug_free(pointer);
1571 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1572
1573 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
1574 pointer = debug_pvalloc(60);
1575 ASSERT_TRUE(pointer != nullptr);
1576 expected += android::base::StringPrintf("%d: memalign %p 4096 4096\n", getpid(), pointer);
1577 debug_free(pointer);
1578 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1579
1580 pointer = debug_valloc(70);
1581 ASSERT_TRUE(pointer != nullptr);
1582 expected += android::base::StringPrintf("%d: memalign %p 4096 70\n", getpid(), pointer);
1583 debug_free(pointer);
1584 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1585 #endif
1586
1587 // Dump all of the data accumulated so far.
1588 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
1589 sleep(1);
1590
1591 // This triggers the dumping.
1592 pointer = debug_malloc(110);
1593 ASSERT_TRUE(pointer != nullptr);
1594 expected += android::base::StringPrintf("%d: malloc %p 110\n", getpid(), pointer);
1595
1596 // Read all of the contents.
1597 std::string actual;
1598 ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
1599
1600 ASSERT_STREQ(expected.c_str(), actual.c_str());
1601
1602 ASSERT_STREQ("", getFakeLogBuf().c_str());
1603 std::string expected_log = android::base::StringPrintf(
1604 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
1605 SIGRTMAX - 18, getpid());
1606 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1607
1608 debug_free(pointer);
1609 }
1610
TEST_F(MallocDebugTest,record_allocs_no_header)1611 TEST_F(MallocDebugTest, record_allocs_no_header) {
1612 Init("record_allocs");
1613
1614 VerifyRecordAllocs();
1615 }
1616
TEST_F(MallocDebugTest,record_allocs_with_header)1617 TEST_F(MallocDebugTest, record_allocs_with_header) {
1618 Init("record_allocs front_guard");
1619
1620 VerifyRecordAllocs();
1621 }
1622
TEST_F(MallocDebugTest,record_allocs_max)1623 TEST_F(MallocDebugTest, record_allocs_max) {
1624 Init("record_allocs=5");
1625
1626 std::string expected;
1627
1628 void* pointer = debug_malloc(10);
1629 ASSERT_TRUE(pointer != nullptr);
1630 expected += android::base::StringPrintf("%d: malloc %p 10\n", getpid(), pointer);
1631 debug_free(pointer);
1632 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1633
1634 pointer = debug_malloc(20);
1635 ASSERT_TRUE(pointer != nullptr);
1636 expected += android::base::StringPrintf("%d: malloc %p 20\n", getpid(), pointer);
1637 debug_free(pointer);
1638 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1639
1640 pointer = debug_malloc(1024);
1641 ASSERT_TRUE(pointer != nullptr);
1642 expected += android::base::StringPrintf("%d: malloc %p 1024\n", getpid(), pointer);
1643 debug_free(pointer);
1644
1645 // Dump all of the data accumulated so far.
1646 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
1647 sleep(1);
1648
1649 // This triggers the dumping.
1650 pointer = debug_malloc(110);
1651 ASSERT_TRUE(pointer != nullptr);
1652
1653 // Read all of the contents.
1654 std::string actual;
1655 ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
1656
1657 ASSERT_STREQ(expected.c_str(), actual.c_str());
1658
1659 ASSERT_STREQ("", getFakeLogBuf().c_str());
1660 std::string expected_log = android::base::StringPrintf(
1661 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
1662 SIGRTMAX - 18, getpid());
1663 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1664
1665 debug_free(pointer);
1666 }
1667
TEST_F(MallocDebugTest,record_allocs_thread_done)1668 TEST_F(MallocDebugTest, record_allocs_thread_done) {
1669 Init("record_allocs=5");
1670
1671 static pid_t tid = 0;
1672 static void* pointer = nullptr;
1673 std::thread thread([](){
1674 tid = gettid();
1675 pointer = debug_malloc(100);
1676 write(0, pointer, 0);
1677 debug_free(pointer);
1678 });
1679 thread.join();
1680
1681 std::string expected = android::base::StringPrintf("%d: malloc %p 100\n", tid, pointer);
1682 expected += android::base::StringPrintf("%d: free %p\n", tid, pointer);
1683 expected += android::base::StringPrintf("%d: thread_done 0x0\n", tid);
1684
1685 // Dump all of the data accumulated so far.
1686 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
1687 sleep(1);
1688
1689 // This triggers the dumping.
1690 pointer = debug_malloc(23);
1691 ASSERT_TRUE(pointer != nullptr);
1692 expected += android::base::StringPrintf("%d: malloc %p 23\n", getpid(), pointer);
1693
1694 // Read all of the contents.
1695 std::string actual;
1696 ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
1697
1698 ASSERT_STREQ(expected.c_str(), actual.c_str());
1699
1700 ASSERT_STREQ("", getFakeLogBuf().c_str());
1701 std::string expected_log = android::base::StringPrintf(
1702 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
1703 SIGRTMAX - 18, getpid());
1704 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1705
1706 debug_free(pointer);
1707 }
1708
TEST_F(MallocDebugTest,record_allocs_file_name_fail)1709 TEST_F(MallocDebugTest, record_allocs_file_name_fail) {
1710 Init("record_allocs=5");
1711
1712 // Delete the special.txt file and create a symbolic link there to
1713 // make sure the create file will fail.
1714 unlink(RECORD_ALLOCS_FILE);
1715
1716 ASSERT_EQ(0, symlink("/data/local/tmp/does_not_exist", RECORD_ALLOCS_FILE));
1717
1718 std::string expected;
1719
1720 void* pointer = debug_malloc(10);
1721 ASSERT_TRUE(pointer != nullptr);
1722 expected += android::base::StringPrintf("%d: malloc %p 10\n", getpid(), pointer);
1723 debug_free(pointer);
1724 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1725
1726 // Dump all of the data accumulated so far.
1727 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
1728 sleep(1);
1729
1730 // This triggers the dumping.
1731 pointer = debug_malloc(110);
1732 ASSERT_TRUE(pointer != nullptr);
1733 expected += android::base::StringPrintf("%d: malloc %p 110\n", getpid(), pointer);
1734
1735 // Read all of the contents.
1736 std::string actual;
1737 ASSERT_FALSE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
1738
1739 // Unlink the file so the next dump passes.
1740 ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
1741
1742 // Dump all of the data accumulated so far.
1743 ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
1744 sleep(1);
1745
1746 // This triggers the dumping.
1747 debug_free(pointer);
1748 expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
1749
1750 ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
1751 ASSERT_STREQ(expected.c_str(), actual.c_str());
1752
1753 ASSERT_STREQ("", getFakeLogBuf().c_str());
1754 std::string expected_log = android::base::StringPrintf(
1755 "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
1756 SIGRTMAX - 18, getpid());
1757 expected_log += android::base::StringPrintf(
1758 "6 malloc_debug Cannot create record alloc file %s: Too many symbolic links encountered\n",
1759 RECORD_ALLOCS_FILE);
1760 ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
1761 }
1762