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 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: 84 void SetUp() override { 85 initialized = false; 86 resetLogs(); 87 backtrace_fake_clear_all(); 88 } 89 90 void TearDown() override { 91 if (initialized) { 92 debug_finalize(); 93 } 94 } 95 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 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 187 TEST_F(MallocDebugTest, fill_generic) { 188 Init("fill"); 189 VerifyAllocCalls(); 190 } 191 192 TEST_F(MallocDebugTest, fill_on_alloc_generic) { 193 Init("fill_on_alloc"); 194 VerifyAllocCalls(); 195 } 196 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 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 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 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 271 TEST_F(MallocDebugTest, all_options) { 272 Init("guard backtrace fill expand_alloc free_track leak_track"); 273 VerifyAllocCalls(); 274 } 275 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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) 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 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