summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authorkaiwang@chromium.org <kaiwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-24 11:13:23 +0000
committerkaiwang@chromium.org <kaiwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-24 11:13:23 +0000
commita849dc1cd365ac9f21233b9950bb39860c39a867 (patch)
tree6af6115f10d1fd5ab950f06859d3f9a1da5a22fd /third_party
parent09096e0aa7bd96a31389825152d9547c56459273 (diff)
downloadchromium_src-a849dc1cd365ac9f21233b9950bb39860c39a867.zip
chromium_src-a849dc1cd365ac9f21233b9950bb39860c39a867.tar.gz
chromium_src-a849dc1cd365ac9f21233b9950bb39860c39a867.tar.bz2
1. Enable large object pointer offset check in release build.
Following code will now cause a check error: char* p = reinterpret_cast<char*>(malloc(kMaxSize + 1)); free(p + 1); 2. Remove a duplicated error reporting function "DieFromBadFreePointer", can use "InvalidGetAllocatedSize". Review URL: https://chromiumcodereview.appspot.com/10391178 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138775 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r--third_party/tcmalloc/chromium/src/internal_logging.h9
-rw-r--r--third_party/tcmalloc/chromium/src/tcmalloc.cc47
2 files changed, 31 insertions, 25 deletions
diff --git a/third_party/tcmalloc/chromium/src/internal_logging.h b/third_party/tcmalloc/chromium/src/internal_logging.h
index 0267034..55e1808 100644
--- a/third_party/tcmalloc/chromium/src/internal_logging.h
+++ b/third_party/tcmalloc/chromium/src/internal_logging.h
@@ -113,12 +113,21 @@ do { \
} \
} while (0)
+#define CHECK_CONDITION_PRINT(cond, str) \
+do { \
+ if (!(cond)) { \
+ ::tcmalloc::Log(::tcmalloc::kCrash, __FILE__, __LINE__, str); \
+ } \
+} while (0)
+
// Our own version of assert() so we can avoid hanging by trying to do
// all kinds of goofy printing while holding the malloc lock.
#ifndef NDEBUG
#define ASSERT(cond) CHECK_CONDITION(cond)
+#define ASSERT_PRINT(cond, str) CHECK_CONDITION_PRINT(cond, str)
#else
#define ASSERT(cond) ((void) 0)
+#define ASSERT_PRINT(cond, str) ((void) 0)
#endif
// Print into buffer
diff --git a/third_party/tcmalloc/chromium/src/tcmalloc.cc b/third_party/tcmalloc/chromium/src/tcmalloc.cc
index a87a4df..219a370 100644
--- a/third_party/tcmalloc/chromium/src/tcmalloc.cc
+++ b/third_party/tcmalloc/chromium/src/tcmalloc.cc
@@ -178,13 +178,13 @@ using tcmalloc::StackTrace;
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);
@@ -950,7 +950,7 @@ static inline bool CheckCachedSizeClass(void *ptr) {
cached_value == Static::pageheap()->GetDescriptor(p)->sizeclass;
}
-static inline void* CheckedMallocResult(void *result) {
+static inline void* CheckMallocResult(void *result) {
ASSERT(result == NULL || CheckCachedSizeClass(result));
MarkAllocatedRegion(result);
return result;
@@ -959,7 +959,7 @@ static inline void* CheckedMallocResult(void *result) {
static inline void* SpanToMallocResult(Span *span) {
Static::pageheap()->CacheSizeClass(span->start, 0);
return
- CheckedMallocResult(reinterpret_cast<void*>(span->start << kPageShift));
+ CheckMallocResult(reinterpret_cast<void*>(span->start << kPageShift));
}
static void* DoSampledAllocation(size_t size) {
@@ -1096,7 +1096,7 @@ inline void* do_malloc(size_t size) {
} else {
// The common case, and also the simplest. This just pops the
// size-appropriate freelist, after replenishing it if it's empty.
- ret = CheckedMallocResult(heap->Allocate(size, cl));
+ ret = CheckMallocResult(heap->Allocate(size, cl));
}
} else {
ret = do_malloc_pages(heap, size);
@@ -1156,7 +1156,15 @@ inline void do_free_with_callback(void* ptr, void (*invalid_free_fn)(void*)) {
cl = span->sizeclass;
Static::pageheap()->CacheSizeClass(p, cl);
}
+ if (cl == 0) {
+ // Check to see if the object is in use.
+ CHECK_CONDITION_PRINT(span->location == Span::IN_USE,
+ "Object was not in-use");
+ CHECK_CONDITION_PRINT(
+ span->start << kPageShift == reinterpret_cast<uintptr_t>(ptr),
+ "Pointer is not pointing to the start of a span");
+ }
ValidateAllocatedRegion(ptr, cl);
if (cl != 0) {
@@ -1276,7 +1284,7 @@ inline void* do_realloc(void* old_ptr, size_t new_size) {
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 CheckMallocResult(), which is also inside SpanToMallocResult().
AddRoomForMark(&size);
if (size + align < size) return NULL; // Overflow
@@ -1307,7 +1315,7 @@ void* do_memalign(size_t align, size_t size) {
if (cl < kNumClasses) {
ThreadCache* heap = ThreadCache::GetCache();
size = Static::sizemap()->class_to_size(cl);
- return CheckedMallocResult(heap->Allocate(size, cl));
+ return CheckMallocResult(heap->Allocate(size, cl));
}
}
@@ -1698,7 +1706,7 @@ extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW {
#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 +1749,11 @@ static void ValidateAllocatedRegion(void* ptr, size_t cl) {}
#else // TCMALLOC_VALIDATION
static void DieFromDoubleFree() {
- char* p = NULL;
- p++;
- *p += 1; // Segv.
-}
-
-static size_t DieFromBadFreePointer(const void* unused) {
- char* p = NULL;
- p += 2;
- *p += 2; // Segv.
- return 0;
+ Log(kCrash, __FILE__, __LINE__, "Attempt to double free");
}
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 +1767,7 @@ static void DieFromMemoryCorruption() {
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 +1790,9 @@ inline static size_t ExcludeSpaceForMark(size_t size) {
}
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;
}