| OLD | NEW |
| 1 // Copyright (c) 2000, Google Inc. | 1 // Copyright (c) 2000, Google Inc. |
| 2 // All rights reserved. | 2 // All rights reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
| 9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
| 10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 | 145 |
| 146 // Define the malloc/free/mallopt/mallinfo implementations | 146 // Define the malloc/free/mallopt/mallinfo implementations |
| 147 // we will be working on top of. | 147 // we will be working on top of. |
| 148 // TODO(csilvers): provide debugallocation on top of libc alloc, | 148 // TODO(csilvers): provide debugallocation on top of libc alloc, |
| 149 // so this #ifdef might sometimes be false. | 149 // so this #ifdef might sometimes be false. |
| 150 #ifdef TCMALLOC_FOR_DEBUGALLOCATION | 150 #ifdef TCMALLOC_FOR_DEBUGALLOCATION |
| 151 | 151 |
| 152 // The do_* functions are defined in tcmalloc.cc, | 152 // The do_* functions are defined in tcmalloc.cc, |
| 153 // which is included before this file | 153 // which is included before this file |
| 154 // when TCMALLOC_FOR_DEBUGALLOCATION is defined. | 154 // when TCMALLOC_FOR_DEBUGALLOCATION is defined. |
| 155 #define BASE_MALLOC_NEW(size) cpp_alloc(size, false) | 155 #define BASE_MALLOC do_malloc |
| 156 #define BASE_MALLOC do_malloc_or_cpp_alloc | 156 #define BASE_FREE do_free |
| 157 #define BASE_FREE do_free | 157 #define BASE_MALLOPT do_mallopt |
| 158 #define BASE_MALLOPT do_mallopt | 158 #define BASE_MALLINFO do_mallinfo |
| 159 #define BASE_MALLINFO do_mallinfo | |
| 160 | 159 |
| 161 #else | 160 #else |
| 162 | 161 |
| 163 // We are working on top of standard libc's malloc library | 162 // We are working on top of standard libc's malloc library |
| 164 #define BASE_MALLOC_NEW __libc_malloc | 163 #define BASE_MALLOC __libc_malloc |
| 165 #define BASE_MALLOC __libc_malloc | 164 #define BASE_FREE __libc_free |
| 166 #define BASE_FREE __libc_free | 165 #define BASE_MALLOPT __libc_mallopt |
| 167 #define BASE_MALLOPT __libc_mallopt | 166 #define BASE_MALLINFO __libc_mallinfo |
| 168 #define BASE_MALLINFO __libc_mallinfo | |
| 169 | 167 |
| 170 #endif | 168 #endif |
| 171 | 169 |
| 172 // ========================================================================= // | 170 // ========================================================================= // |
| 173 | 171 |
| 174 class MallocBlock; | 172 class MallocBlock; |
| 175 | 173 |
| 176 // A circular buffer to hold freed blocks of memory. MallocBlock::Deallocate | 174 // A circular buffer to hold freed blocks of memory. MallocBlock::Deallocate |
| 177 // (below) pushes blocks into this queue instead of returning them to the | 175 // (below) pushes blocks into this queue instead of returning them to the |
| 178 // underlying allocator immediately. See MallocBlock::Deallocate for more | 176 // underlying allocator immediately. See MallocBlock::Deallocate for more |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 // is no point in propagating the error elsewhere. | 517 // is no point in propagating the error elsewhere. |
| 520 RAW_LOG(FATAL, "Out of memory: possibly due to page fence overhead: %s", | 518 RAW_LOG(FATAL, "Out of memory: possibly due to page fence overhead: %s", |
| 521 strerror(errno)); | 519 strerror(errno)); |
| 522 } | 520 } |
| 523 // Mark the page after the block inaccessible | 521 // Mark the page after the block inaccessible |
| 524 if (mprotect(p + (num_pages - 1) * pagesize, pagesize, PROT_NONE)) { | 522 if (mprotect(p + (num_pages - 1) * pagesize, pagesize, PROT_NONE)) { |
| 525 RAW_LOG(FATAL, "Guard page setup failed: %s", strerror(errno)); | 523 RAW_LOG(FATAL, "Guard page setup failed: %s", strerror(errno)); |
| 526 } | 524 } |
| 527 b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz); | 525 b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz); |
| 528 } else { | 526 } else { |
| 529 b = (MallocBlock*) (type == kMallocType ? | 527 b = (MallocBlock*) BASE_MALLOC(real_malloced_size(size)); |
| 530 BASE_MALLOC(real_malloced_size(size)) : | |
| 531 BASE_MALLOC_NEW(real_malloced_size(size))); | |
| 532 } | 528 } |
| 533 #else | 529 #else |
| 534 b = (MallocBlock*) (type == kMallocType ? | 530 b = (MallocBlock*) BASE_MALLOC(real_malloced_size(size)); |
| 535 BASE_MALLOC(real_malloced_size(size)) : | |
| 536 BASE_MALLOC_NEW(real_malloced_size(size))); | |
| 537 #endif | 531 #endif |
| 538 | 532 |
| 539 // It would be nice to output a diagnostic on allocation failure | 533 // It would be nice to output a diagnostic on allocation failure |
| 540 // here, but logging (other than FATAL) requires allocating | 534 // here, but logging (other than FATAL) requires allocating |
| 541 // memory, which could trigger a nasty recursion. Instead, preserve | 535 // memory, which could trigger a nasty recursion. Instead, preserve |
| 542 // malloc semantics and return NULL on failure. | 536 // malloc semantics and return NULL on failure. |
| 543 if (b != NULL) { | 537 if (b != NULL) { |
| 544 b->magic1_ = use_malloc_page_fence ? kMagicMMap : kMagicMalloc; | 538 b->magic1_ = use_malloc_page_fence ? kMagicMMap : kMagicMalloc; |
| 545 b->Initialize(size, type); | 539 b->Initialize(size, type); |
| 546 } | 540 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 RAW_LOG(ERROR, "Buffer too large to print corruption."); | 649 RAW_LOG(ERROR, "Buffer too large to print corruption."); |
| 656 } | 650 } |
| 657 | 651 |
| 658 const MallocBlock* b = queue_entry.block; | 652 const MallocBlock* b = queue_entry.block; |
| 659 const size_t size = queue_entry.size; | 653 const size_t size = queue_entry.size; |
| 660 if (queue_entry.num_deleter_pcs > 0) { | 654 if (queue_entry.num_deleter_pcs > 0) { |
| 661 TracePrintf(STDERR_FILENO, "Deleted by thread %p\n", | 655 TracePrintf(STDERR_FILENO, "Deleted by thread %p\n", |
| 662 reinterpret_cast<void*>( | 656 reinterpret_cast<void*>( |
| 663 PRINTABLE_PTHREAD(queue_entry.deleter_threadid))); | 657 PRINTABLE_PTHREAD(queue_entry.deleter_threadid))); |
| 664 | 658 |
| 665 SymbolTable symbolization_table; | 659 SymbolMap symbolization_table; |
| 666 const int num_symbols = queue_entry.num_deleter_pcs; // short alias name | 660 const int num_symbols = queue_entry.num_deleter_pcs; // short alias name |
| 667 for (int i = 0; i < num_symbols; i++) { | 661 for (int i = 0; i < num_symbols; i++) { |
| 668 // Symbolizes the previous address of pc because pc may be in the | 662 // Symbolizes the previous address of pc because pc may be in the |
| 669 // next function. This may happen when the function ends with | 663 // next function. This may happen when the function ends with |
| 670 // a call to a function annotated noreturn (e.g. CHECK). | 664 // a call to a function annotated noreturn (e.g. CHECK). |
| 671 char* pc = | 665 uintptr_t pc = |
| 672 reinterpret_cast<char*>(queue_entry.deleter_pcs[i]) - 1; | 666 reinterpret_cast<uintptr_t>(queue_entry.deleter_pcs[i]) - 1; |
| 673 symbolization_table.Add(pc); | 667 symbolization_table[pc] = ""; |
| 674 } | 668 } |
| 669 int sym_buffer_len = kSymbolSize * num_symbols; |
| 670 char *sym_buffer = new char[sym_buffer_len]; |
| 675 if (FLAGS_symbolize_stacktrace) | 671 if (FLAGS_symbolize_stacktrace) |
| 676 symbolization_table.Symbolize(); | 672 Symbolize(sym_buffer, sym_buffer_len, &symbolization_table); |
| 677 for (int i = 0; i < num_symbols; i++) { | 673 for (int i = 0; i < num_symbols; i++) { |
| 678 char *pc = | 674 uintptr_t pc = |
| 679 reinterpret_cast<char*>(queue_entry.deleter_pcs[i]) - 1; | 675 reinterpret_cast<uintptr_t>(queue_entry.deleter_pcs[i]) - 1; |
| 680 TracePrintf(STDERR_FILENO, " @ %"PRIxPTR" %s\n", | 676 TracePrintf(STDERR_FILENO, " @ %p %s\n", |
| 681 reinterpret_cast<uintptr_t>(pc), | 677 pc, symbolization_table[pc]); |
| 682 symbolization_table.GetSymbol(pc)); | |
| 683 } | 678 } |
| 684 } else { | 679 } else { |
| 685 RAW_LOG(ERROR, | 680 RAW_LOG(ERROR, |
| 686 "Skipping the printing of the deleter's stack! Its stack was " | 681 "Skipping the printing of the deleter's stack! Its stack was " |
| 687 "not found; either the corruption occurred too early in " | 682 "not found; either the corruption occurred too early in " |
| 688 "execution to obtain a stack trace or --max_free_queue_size was " | 683 "execution to obtain a stack trace or --max_free_queue_size was " |
| 689 "set to 0."); | 684 "set to 0."); |
| 690 } | 685 } |
| 691 | 686 |
| 692 RAW_LOG(FATAL, | 687 RAW_LOG(FATAL, |
| 693 "Memory was written to after being freed. MallocBlock: %p, user " | 688 "Memory was written to after being freed. MallocBlock: %p, user " |
| 694 "ptr: %p, size: %zd. If you can't find the source of the error, " | 689 "ptr: %p, size: %zd. If you can't find the source of the error, " |
| 695 "try using valgrind or purify, or study the output of the " | 690 "try using valgrind or purify, or study the output of the " |
| 696 "deleter's stack printed above.", b, b->data_addr(), size); | 691 "deleter's stack printed above.", b, b->data_addr(), size); |
| 697 } | 692 } |
| 698 | 693 |
| 699 static MallocBlock* FromRawPointer(void* p) { | 694 static MallocBlock* FromRawPointer(void* p) { |
| 700 const size_t data_offset = MallocBlock::data_offset(); | 695 const size_t data_offset = MallocBlock::data_offset(); |
| 701 // Find the header just before client's memory. | 696 // Find the header just before client's memory. |
| 702 MallocBlock *mb = reinterpret_cast<MallocBlock *>( | 697 MallocBlock *mb = reinterpret_cast<MallocBlock *>( |
| 703 reinterpret_cast<char *>(p) - data_offset); | 698 reinterpret_cast<char *>(p) - data_offset); |
| 704 // If mb->alloc_type_ is kMagicDeletedInt, we're not an ok pointer. | |
| 705 if (mb->alloc_type_ == kMagicDeletedInt) { | |
| 706 RAW_LOG(FATAL, "memory allocation bug: object at %p has been already" | |
| 707 " deallocated; or else a word before the object has been" | |
| 708 " corrupted (memory stomping bug)", p); | |
| 709 } | |
| 710 // If mb->offset_ is zero (common case), mb is the real header. If | 699 // If mb->offset_ is zero (common case), mb is the real header. If |
| 711 // mb->offset_ is non-zero, this block was allocated by memalign, and | 700 // mb->offset_ is non-zero, this block was allocated by memalign, and |
| 712 // mb->offset_ is the distance backwards to the real header from mb, | 701 // mb->offset_ is the distance backwards to the real header from mb, |
| 713 // which is a fake header. The following subtraction works for both zero | 702 // which is a fake header. The following subtraction works for both zero |
| 714 // and non-zero values. | 703 // and non-zero values. |
| 715 return reinterpret_cast<MallocBlock *>( | 704 return reinterpret_cast<MallocBlock *>( |
| 716 reinterpret_cast<char *>(mb) - mb->offset_); | 705 reinterpret_cast<char *>(mb) - mb->offset_); |
| 717 } | 706 } |
| 718 static const MallocBlock* FromRawPointer(const void* p) { | 707 static const MallocBlock* FromRawPointer(const void* p) { |
| 719 // const-safe version: we just cast about | 708 // const-safe version: we just cast about |
| (...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1393 void __libc_cfree(void* ptr) { cfree(ptr); } | 1382 void __libc_cfree(void* ptr) { cfree(ptr); } |
| 1394 void* __libc_memalign(size_t align, size_t s) { return memalign(align, s); } | 1383 void* __libc_memalign(size_t align, size_t s) { return memalign(align, s); } |
| 1395 void* __libc_valloc(size_t size) { return valloc(size); } | 1384 void* __libc_valloc(size_t size) { return valloc(size); } |
| 1396 void* __libc_pvalloc(size_t size) { return pvalloc(size); } | 1385 void* __libc_pvalloc(size_t size) { return pvalloc(size); } |
| 1397 int __posix_memalign(void** r, size_t a, size_t s) { | 1386 int __posix_memalign(void** r, size_t a, size_t s) { |
| 1398 return posix_memalign(r, a, s); | 1387 return posix_memalign(r, a, s); |
| 1399 } | 1388 } |
| 1400 } | 1389 } |
| 1401 | 1390 |
| 1402 #endif // #ifdef TCMALLOC_FOR_DEBUGALLOCATION | 1391 #endif // #ifdef TCMALLOC_FOR_DEBUGALLOCATION |
| OLD | NEW |