malloc_debug_unit_tests.cpp revision 239838608dbe9917acddfe5a51d92350a4c8e135
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 "Config.h" 38#include "malloc_debug.h" 39 40#include "log_fake.h" 41#include "backtrace_fake.h" 42 43__BEGIN_DECLS 44 45int property_set(const char*, const char*); 46bool debug_initialize(const MallocDispatch*, int*); 47void debug_finalize(); 48 49void* debug_malloc(size_t); 50void debug_free(void*); 51void* debug_calloc(size_t, size_t); 52void* debug_realloc(void*, size_t); 53int debug_posix_memalign(void**, size_t, size_t); 54void* debug_memalign(size_t, size_t); 55size_t debug_malloc_usable_size(void*); 56void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*); 57void debug_free_malloc_leak_info(uint8_t*); 58 59struct mallinfo debug_mallinfo(); 60 61#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) 62void* debug_pvalloc(size_t); 63void* debug_valloc(size_t); 64#endif 65 66__END_DECLS 67 68constexpr char DIVIDER[] = 69 "6 malloc_debug *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"; 70 71constexpr uint32_t BACKTRACE_HEADER = 0x1; 72 73static size_t get_tag_offset(uint32_t flags = 0, size_t backtrace_frames = 0) { 74 size_t offset = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES); 75 if (flags & BACKTRACE_HEADER) { 76 offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames, MINIMUM_ALIGNMENT_BYTES); 77 } 78 return offset; 79} 80 81class MallocDebugTest : public ::testing::Test { 82 protected: 83 void SetUp() override { 84 initialized = false; 85 resetLogs(); 86 backtrace_fake_clear_all(); 87 } 88 89 void TearDown() override { 90 if (initialized) { 91 debug_finalize(); 92 } 93 } 94 95 void Init(const char* property_value) { 96 property_set("libc.debug.malloc.options", property_value); 97 zygote = 0; 98 ASSERT_TRUE(debug_initialize(&dispatch, &zygote)); 99 initialized = true; 100 } 101 102 bool initialized; 103 104 int zygote; 105 106 static MallocDispatch dispatch; 107}; 108 109MallocDispatch MallocDebugTest::dispatch = { 110 calloc, 111 free, 112 mallinfo, 113 malloc, 114 malloc_usable_size, 115 memalign, 116 posix_memalign, 117#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) 118 nullptr, 119#endif 120 realloc, 121#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) 122 nullptr, 123#endif 124 nullptr, 125 nullptr, 126 nullptr, 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 const size_t size_t_bits = sizeof(size_t) * 8; 1294 const size_t sqrt_size_t = 1ULL << (size_t_bits/2); 1295 pointer = debug_calloc(sqrt_size_t + 1, sqrt_size_t); 1296 ASSERT_TRUE(pointer == nullptr); 1297 ASSERT_EQ(ENOMEM, errno); 1298 1299 pointer = debug_realloc(nullptr, SIZE_MAX); 1300 ASSERT_TRUE(pointer == nullptr); 1301 ASSERT_EQ(ENOMEM, errno); 1302 1303 pointer = debug_malloc(100); 1304 ASSERT_TRUE(pointer != nullptr); 1305 memset(pointer, 0xd0, 100); 1306 1307 void* realloc_pointer = debug_realloc(pointer, SIZE_MAX); 1308 ASSERT_TRUE(realloc_pointer == nullptr); 1309 // Verify the pointer was not freed. 1310 for (size_t i = 0; i < 100; i++) { 1311 ASSERT_EQ(0xd0, reinterpret_cast<uint8_t*>(pointer)[i]) << "Failed checking byte " << i; 1312 } 1313 debug_free(pointer); 1314 1315 ASSERT_STREQ("", getFakeLogBuf().c_str()); 1316 ASSERT_STREQ("", getFakeLogPrint().c_str()); 1317} 1318 1319static void VerifyZygoteSet(size_t memory_bytes) { 1320 size_t expected_info_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t); 1321 std::vector<uint8_t> expected_info(expected_info_size); 1322 memset(expected_info.data(), 0, expected_info_size); 1323 InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data()); 1324 entry->size = memory_bytes | (1U << 31); 1325 entry->num_frames = 1; 1326 entry->frames[0] = 0x1; 1327 1328 uint8_t* info; 1329 size_t overall_size; 1330 size_t info_size; 1331 size_t total_memory; 1332 size_t backtrace_size; 1333 1334 debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size); 1335 ASSERT_EQ(expected_info_size, overall_size); 1336 ASSERT_EQ(expected_info_size, info_size); 1337 ASSERT_EQ(memory_bytes, total_memory); 1338 ASSERT_EQ(16U, backtrace_size); 1339 ASSERT_TRUE(memcmp(info, expected_info.data(), expected_info_size) == 0); 1340 1341 debug_free_malloc_leak_info(info); 1342} 1343 1344TEST_F(MallocDebugTest, zygote_set) { 1345 // Set all of the options. 1346 Init("guard fill backtrace leak_track free_track=2"); 1347 1348 zygote = 1; 1349 1350 backtrace_fake_add(std::vector<uintptr_t> {0x1}); 1351 1352 void* pointer = debug_malloc(100); 1353 ASSERT_TRUE(pointer != nullptr); 1354 ASSERT_EQ(100U, debug_malloc_usable_size(pointer)); 1355 memset(pointer, 0, 100); 1356 VerifyZygoteSet(100); 1357 debug_free(pointer); 1358 1359 backtrace_fake_add(std::vector<uintptr_t> {0x1}); 1360 pointer = debug_calloc(10, 20); 1361 ASSERT_TRUE(pointer != nullptr); 1362 ASSERT_EQ(200U, debug_malloc_usable_size(pointer)); 1363 VerifyZygoteSet(200); 1364 debug_free(pointer); 1365 1366 backtrace_fake_add(std::vector<uintptr_t> {0x1}); 1367 pointer = debug_memalign(128, 300); 1368 ASSERT_TRUE(pointer != nullptr); 1369 ASSERT_EQ(300U, debug_malloc_usable_size(pointer)); 1370 memset(pointer, 0, 300); 1371 VerifyZygoteSet(300); 1372 debug_free(pointer); 1373 1374 backtrace_fake_add(std::vector<uintptr_t> {0x1}); 1375 pointer = debug_malloc(500); 1376 ASSERT_TRUE(pointer != nullptr); 1377 ASSERT_EQ(500U, debug_malloc_usable_size(pointer)); 1378 memset(pointer, 0, 500); 1379 VerifyZygoteSet(500); 1380 1381 backtrace_fake_add(std::vector<uintptr_t> {0x1}); 1382 pointer = debug_realloc(pointer, 300); 1383 ASSERT_TRUE(pointer != nullptr); 1384 ASSERT_EQ(300U, debug_malloc_usable_size(pointer)); 1385 VerifyZygoteSet(300); 1386 debug_free(pointer); 1387 1388 ASSERT_STREQ("", getFakeLogBuf().c_str()); 1389 ASSERT_STREQ("", getFakeLogPrint().c_str()); 1390} 1391 1392TEST_F(MallocDebugTest, max_size) { 1393 Init("guard"); 1394 1395 void* pointer = debug_malloc(1U << 31); 1396 ASSERT_TRUE(pointer == nullptr); 1397 1398 pointer = debug_calloc(1, 1U << 31); 1399 ASSERT_TRUE(pointer == nullptr); 1400 1401 pointer = debug_calloc(1U << 31, 1); 1402 ASSERT_TRUE(pointer == nullptr); 1403 1404 pointer = debug_memalign(16, 1U << 31); 1405 ASSERT_TRUE(pointer == nullptr); 1406 1407 ASSERT_STREQ("", getFakeLogBuf().c_str()); 1408 ASSERT_STREQ("", getFakeLogPrint().c_str()); 1409} 1410 1411TEST_F(MallocDebugTest, debug_mallinfo) { 1412 Init("guard"); 1413 1414 void* pointer = debug_malloc(150); 1415 ASSERT_TRUE(pointer != nullptr); 1416 1417 struct mallinfo mi = debug_mallinfo(); 1418 EXPECT_NE(0U, mi.uordblks); 1419 1420 debug_free(pointer); 1421 1422 ASSERT_STREQ("", getFakeLogBuf().c_str()); 1423 ASSERT_STREQ("", getFakeLogPrint().c_str()); 1424} 1425 1426TEST_F(MallocDebugTest, debug_posix_memalign) { 1427 Init("guard"); 1428 1429 void* pointer; 1430 ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 300)); 1431 ASSERT_TRUE(pointer != nullptr); 1432 debug_free(pointer); 1433 1434 ASSERT_EQ(EINVAL, debug_posix_memalign(&pointer, 11, 300)); 1435 1436 ASSERT_EQ(ENOMEM, debug_posix_memalign(&pointer, 16, SIZE_MAX)); 1437 1438 ASSERT_STREQ("", getFakeLogBuf().c_str()); 1439 ASSERT_STREQ("", getFakeLogPrint().c_str()); 1440} 1441 1442#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) 1443TEST_F(MallocDebugTest, debug_pvalloc) { 1444 Init("guard"); 1445 1446 size_t pagesize = getpagesize(); 1447 void* pointer = debug_pvalloc(1); 1448 ASSERT_TRUE(pointer != nullptr); 1449 ASSERT_EQ(pagesize, debug_malloc_usable_size(pointer)); 1450 uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1); 1451 ASSERT_EQ(0U, value); 1452 debug_free(pointer); 1453} 1454 1455TEST_F(MallocDebugTest, debug_valloc) { 1456 Init("guard"); 1457 1458 size_t pagesize = getpagesize(); 1459 void* pointer = debug_valloc(100); 1460 ASSERT_TRUE(pointer != nullptr); 1461 ASSERT_EQ(100U, debug_malloc_usable_size(pointer)); 1462 uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1); 1463 ASSERT_EQ(0U, value); 1464 debug_free(pointer); 1465} 1466#endif 1467