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; |
} |