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