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