Chromium Code Reviews| Index: third_party/tcmalloc/chromium/src/tcmalloc.cc |
| =================================================================== |
| --- third_party/tcmalloc/chromium/src/tcmalloc.cc (revision 137587) |
| +++ third_party/tcmalloc/chromium/src/tcmalloc.cc (working copy) |
| @@ -178,13 +178,13 @@ |
| using tcmalloc::Static; |
| using tcmalloc::ThreadCache; |
| -// ---- Double free debug declarations |
| +// ---- Functions doing validation with an extra mark. |
| static size_t ExcludeSpaceForMark(size_t size); |
| static void AddRoomForMark(size_t* size); |
| static void ExcludeMarkFromSize(size_t* new_size); |
| static void MarkAllocatedRegion(void* ptr); |
| static void ValidateAllocatedRegion(void* ptr, size_t cl); |
| -// ---- End Double free debug declarations |
| +// ---- End validation functions. |
| DECLARE_int64(tcmalloc_sample_parameter); |
| DECLARE_double(tcmalloc_release_rate); |
| @@ -1155,8 +1155,17 @@ |
| } |
| cl = span->sizeclass; |
| Static::pageheap()->CacheSizeClass(p, cl); |
| + |
| + // The span is not in use! A double free? |
| + CHECK_CONDITION_PRINT(span->location == Span::IN_USE, |
| + "Freeing a span not in use"); |
| + |
| + // Mimic debug assertion below to validate pointer of large objects. |
| + CHECK_CONDITION_PRINT(span->start == p, |
| + "Pointer is not inside the first page of a span"); |
| + CHECK_CONDITION_PRINT(reinterpret_cast<uintptr_t>(ptr) % kPageSize == 0, |
| + "Pointer is not pointing to the start of a span"); |
| } |
| - |
| ValidateAllocatedRegion(ptr, cl); |
| if (cl != 0) { |
| @@ -1276,7 +1285,7 @@ |
| void* do_memalign(size_t align, size_t size) { |
| ASSERT((align & (align - 1)) == 0); |
| ASSERT(align > 0); |
| - // Marked in CheckMallocResult(), which is also inside SpanToMallocResult(). |
| + // Marked in CheckedMallocResult(), which is also inside SpanToMallocResult(). |
| AddRoomForMark(&size); |
| if (size + align < size) return NULL; // Overflow |
| @@ -1698,7 +1707,7 @@ |
| #endif // TCMALLOC_USING_DEBUGALLOCATION |
| -// ---Double free() debugging implementation ----------------------------------- |
| +// --- Validation implementation with an extra mark ---------------------------- |
| // We will put a mark at the extreme end of each allocation block. We make |
| // sure that we always allocate enough "extra memory" that we can fit in the |
| // mark, and still provide the requested usable region. If ever that mark is |
| @@ -1741,22 +1750,11 @@ |
| #else // TCMALLOC_VALIDATION |
| static void DieFromDoubleFree() { |
| - char* p = NULL; |
| - p++; |
| - *p += 1; // Segv. |
| + Log(kCrash, __FILE__, __LINE__, "Attempt to double free"); |
| } |
| -static size_t DieFromBadFreePointer(const void* unused) { |
| - char* p = NULL; |
| - p += 2; |
| - *p += 2; // Segv. |
|
rvargas (doing something else)
2012/05/19 01:08:04
Does this mean that we can no longer distinguish t
kaiwang
2012/05/21 18:11:42
But we can see the back trace in dump right? Can t
rvargas (doing something else)
2012/05/21 18:44:30
The stack can be optimized away (although having a
|
| - return 0; |
| -} |
| - |
| static void DieFromMemoryCorruption() { |
| - char* p = NULL; |
| - p += 3; |
| - *p += 3; // Segv. |
| + Log(kCrash, __FILE__, __LINE__, "Memory corrupted"); |
| } |
| // We can either do byte marking, or whole word marking based on the following |
| @@ -1770,7 +1768,7 @@ |
| typedef char MarkType; // char saves memory... int is more complete. |
| static const MarkType kAllocationMarkMask = static_cast<MarkType>(0x36); |
| -#else |
| +#else |
| typedef int MarkType; // char saves memory... int is more complete. |
| static const MarkType kAllocationMarkMask = static_cast<MarkType>(0xE1AB9536); |
| @@ -1793,9 +1791,9 @@ |
| } |
| inline static MarkType* GetMarkLocation(void* ptr) { |
| - size_t class_size = GetSizeWithCallback(ptr, DieFromBadFreePointer); |
| - ASSERT(class_size % sizeof(kAllocationMarkMask) == 0); |
| - size_t last_index = (class_size / sizeof(kAllocationMarkMask)) - 1; |
| + size_t size = GetSizeWithCallback(ptr, &InvalidGetAllocatedSize); |
| + ASSERT(size % sizeof(kAllocationMarkMask) == 0); |
| + size_t last_index = (size / sizeof(kAllocationMarkMask)) - 1; |
| return static_cast<MarkType*>(ptr) + last_index; |
| } |