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