Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: third_party/tcmalloc/chromium/src/debugallocation.cc

Issue 576001: Merged third_party/tcmalloc/vendor/src(google-perftools r87) into... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Removed the unnecessary printf and ASSERT(0) Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 do_malloc 155 #define BASE_MALLOC_NEW(size) cpp_alloc(size, false)
156 #define BASE_FREE do_free 156 #define BASE_MALLOC do_malloc_or_cpp_alloc
157 #define BASE_MALLOPT do_mallopt 157 #define BASE_FREE do_free
158 #define BASE_MALLINFO do_mallinfo 158 #define BASE_MALLOPT do_mallopt
159 #define BASE_MALLINFO do_mallinfo
159 160
160 #else 161 #else
161 162
162 // We are working on top of standard libc's malloc library 163 // We are working on top of standard libc's malloc library
163 #define BASE_MALLOC __libc_malloc 164 #define BASE_MALLOC_NEW __libc_malloc
164 #define BASE_FREE __libc_free 165 #define BASE_MALLOC __libc_malloc
165 #define BASE_MALLOPT __libc_mallopt 166 #define BASE_FREE __libc_free
166 #define BASE_MALLINFO __libc_mallinfo 167 #define BASE_MALLOPT __libc_mallopt
168 #define BASE_MALLINFO __libc_mallinfo
167 169
168 #endif 170 #endif
169 171
170 // ========================================================================= // 172 // ========================================================================= //
171 173
172 class MallocBlock; 174 class MallocBlock;
173 175
174 // A circular buffer to hold freed blocks of memory. MallocBlock::Deallocate 176 // A circular buffer to hold freed blocks of memory. MallocBlock::Deallocate
175 // (below) pushes blocks into this queue instead of returning them to the 177 // (below) pushes blocks into this queue instead of returning them to the
176 // underlying allocator immediately. See MallocBlock::Deallocate for more 178 // underlying allocator immediately. See MallocBlock::Deallocate for more
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 // is no point in propagating the error elsewhere. 519 // is no point in propagating the error elsewhere.
518 RAW_LOG(FATAL, "Out of memory: possibly due to page fence overhead: %s", 520 RAW_LOG(FATAL, "Out of memory: possibly due to page fence overhead: %s",
519 strerror(errno)); 521 strerror(errno));
520 } 522 }
521 // Mark the page after the block inaccessible 523 // Mark the page after the block inaccessible
522 if (mprotect(p + (num_pages - 1) * pagesize, pagesize, PROT_NONE)) { 524 if (mprotect(p + (num_pages - 1) * pagesize, pagesize, PROT_NONE)) {
523 RAW_LOG(FATAL, "Guard page setup failed: %s", strerror(errno)); 525 RAW_LOG(FATAL, "Guard page setup failed: %s", strerror(errno));
524 } 526 }
525 b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz); 527 b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz);
526 } else { 528 } else {
527 b = (MallocBlock*) BASE_MALLOC(real_malloced_size(size)); 529 b = (MallocBlock*) (type == kMallocType ?
530 BASE_MALLOC(real_malloced_size(size)) :
531 BASE_MALLOC_NEW(real_malloced_size(size)));
528 } 532 }
529 #else 533 #else
530 b = (MallocBlock*) BASE_MALLOC(real_malloced_size(size)); 534 b = (MallocBlock*) (type == kMallocType ?
535 BASE_MALLOC(real_malloced_size(size)) :
536 BASE_MALLOC_NEW(real_malloced_size(size)));
531 #endif 537 #endif
532 538
533 // It would be nice to output a diagnostic on allocation failure 539 // It would be nice to output a diagnostic on allocation failure
534 // here, but logging (other than FATAL) requires allocating 540 // here, but logging (other than FATAL) requires allocating
535 // memory, which could trigger a nasty recursion. Instead, preserve 541 // memory, which could trigger a nasty recursion. Instead, preserve
536 // malloc semantics and return NULL on failure. 542 // malloc semantics and return NULL on failure.
537 if (b != NULL) { 543 if (b != NULL) {
538 b->magic1_ = use_malloc_page_fence ? kMagicMMap : kMagicMalloc; 544 b->magic1_ = use_malloc_page_fence ? kMagicMMap : kMagicMalloc;
539 b->Initialize(size, type); 545 b->Initialize(size, type);
540 } 546 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 RAW_LOG(ERROR, "Buffer too large to print corruption."); 655 RAW_LOG(ERROR, "Buffer too large to print corruption.");
650 } 656 }
651 657
652 const MallocBlock* b = queue_entry.block; 658 const MallocBlock* b = queue_entry.block;
653 const size_t size = queue_entry.size; 659 const size_t size = queue_entry.size;
654 if (queue_entry.num_deleter_pcs > 0) { 660 if (queue_entry.num_deleter_pcs > 0) {
655 TracePrintf(STDERR_FILENO, "Deleted by thread %p\n", 661 TracePrintf(STDERR_FILENO, "Deleted by thread %p\n",
656 reinterpret_cast<void*>( 662 reinterpret_cast<void*>(
657 PRINTABLE_PTHREAD(queue_entry.deleter_threadid))); 663 PRINTABLE_PTHREAD(queue_entry.deleter_threadid)));
658 664
659 SymbolMap symbolization_table; 665 SymbolTable symbolization_table;
660 const int num_symbols = queue_entry.num_deleter_pcs; // short alias name 666 const int num_symbols = queue_entry.num_deleter_pcs; // short alias name
661 for (int i = 0; i < num_symbols; i++) { 667 for (int i = 0; i < num_symbols; i++) {
662 // Symbolizes the previous address of pc because pc may be in the 668 // Symbolizes the previous address of pc because pc may be in the
663 // next function. This may happen when the function ends with 669 // next function. This may happen when the function ends with
664 // a call to a function annotated noreturn (e.g. CHECK). 670 // a call to a function annotated noreturn (e.g. CHECK).
665 uintptr_t pc = 671 char* pc =
666 reinterpret_cast<uintptr_t>(queue_entry.deleter_pcs[i]) - 1; 672 reinterpret_cast<char*>(queue_entry.deleter_pcs[i]) - 1;
667 symbolization_table[pc] = ""; 673 symbolization_table.Add(pc);
668 } 674 }
669 int sym_buffer_len = kSymbolSize * num_symbols;
670 char *sym_buffer = new char[sym_buffer_len];
671 if (FLAGS_symbolize_stacktrace) 675 if (FLAGS_symbolize_stacktrace)
672 Symbolize(sym_buffer, sym_buffer_len, &symbolization_table); 676 symbolization_table.Symbolize();
673 for (int i = 0; i < num_symbols; i++) { 677 for (int i = 0; i < num_symbols; i++) {
674 uintptr_t pc = 678 char *pc =
675 reinterpret_cast<uintptr_t>(queue_entry.deleter_pcs[i]) - 1; 679 reinterpret_cast<char*>(queue_entry.deleter_pcs[i]) - 1;
676 TracePrintf(STDERR_FILENO, " @ %p %s\n", 680 TracePrintf(STDERR_FILENO, " @ %"PRIxPTR" %s\n",
677 pc, symbolization_table[pc]); 681 reinterpret_cast<uintptr_t>(pc),
682 symbolization_table.GetSymbol(pc));
678 } 683 }
679 } else { 684 } else {
680 RAW_LOG(ERROR, 685 RAW_LOG(ERROR,
681 "Skipping the printing of the deleter's stack! Its stack was " 686 "Skipping the printing of the deleter's stack! Its stack was "
682 "not found; either the corruption occurred too early in " 687 "not found; either the corruption occurred too early in "
683 "execution to obtain a stack trace or --max_free_queue_size was " 688 "execution to obtain a stack trace or --max_free_queue_size was "
684 "set to 0."); 689 "set to 0.");
685 } 690 }
686 691
687 RAW_LOG(FATAL, 692 RAW_LOG(FATAL,
688 "Memory was written to after being freed. MallocBlock: %p, user " 693 "Memory was written to after being freed. MallocBlock: %p, user "
689 "ptr: %p, size: %zd. If you can't find the source of the error, " 694 "ptr: %p, size: %zd. If you can't find the source of the error, "
690 "try using valgrind or purify, or study the output of the " 695 "try using valgrind or purify, or study the output of the "
691 "deleter's stack printed above.", b, b->data_addr(), size); 696 "deleter's stack printed above.", b, b->data_addr(), size);
692 } 697 }
693 698
694 static MallocBlock* FromRawPointer(void* p) { 699 static MallocBlock* FromRawPointer(void* p) {
695 const size_t data_offset = MallocBlock::data_offset(); 700 const size_t data_offset = MallocBlock::data_offset();
696 // Find the header just before client's memory. 701 // Find the header just before client's memory.
697 MallocBlock *mb = reinterpret_cast<MallocBlock *>( 702 MallocBlock *mb = reinterpret_cast<MallocBlock *>(
698 reinterpret_cast<char *>(p) - data_offset); 703 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 }
699 // If mb->offset_ is zero (common case), mb is the real header. If 710 // If mb->offset_ is zero (common case), mb is the real header. If
700 // mb->offset_ is non-zero, this block was allocated by memalign, and 711 // mb->offset_ is non-zero, this block was allocated by memalign, and
701 // mb->offset_ is the distance backwards to the real header from mb, 712 // mb->offset_ is the distance backwards to the real header from mb,
702 // which is a fake header. The following subtraction works for both zero 713 // which is a fake header. The following subtraction works for both zero
703 // and non-zero values. 714 // and non-zero values.
704 return reinterpret_cast<MallocBlock *>( 715 return reinterpret_cast<MallocBlock *>(
705 reinterpret_cast<char *>(mb) - mb->offset_); 716 reinterpret_cast<char *>(mb) - mb->offset_);
706 } 717 }
707 static const MallocBlock* FromRawPointer(const void* p) { 718 static const MallocBlock* FromRawPointer(const void* p) {
708 // const-safe version: we just cast about 719 // const-safe version: we just cast about
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
1382 void __libc_cfree(void* ptr) { cfree(ptr); } 1393 void __libc_cfree(void* ptr) { cfree(ptr); }
1383 void* __libc_memalign(size_t align, size_t s) { return memalign(align, s); } 1394 void* __libc_memalign(size_t align, size_t s) { return memalign(align, s); }
1384 void* __libc_valloc(size_t size) { return valloc(size); } 1395 void* __libc_valloc(size_t size) { return valloc(size); }
1385 void* __libc_pvalloc(size_t size) { return pvalloc(size); } 1396 void* __libc_pvalloc(size_t size) { return pvalloc(size); }
1386 int __posix_memalign(void** r, size_t a, size_t s) { 1397 int __posix_memalign(void** r, size_t a, size_t s) {
1387 return posix_memalign(r, a, s); 1398 return posix_memalign(r, a, s);
1388 } 1399 }
1389 } 1400 }
1390 1401
1391 #endif // #ifdef TCMALLOC_FOR_DEBUGALLOCATION 1402 #endif // #ifdef TCMALLOC_FOR_DEBUGALLOCATION
OLDNEW
« no previous file with comments | « third_party/tcmalloc/chromium/src/config.h.in ('k') | third_party/tcmalloc/chromium/src/google/heap-checker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698