Commit 43b6c44f authored by Gabriel Marin's avatar Gabriel Marin Committed by Commit Bot

tcmalloc: enable large object pointer offset check

Original CL: https://chromiumcodereview.appspot.com/10391178

  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".

BUG=724399,b:70905156

Change-Id: I77b71593373d0c279b95f27cb4931be41c8605b0
Reviewed-on: https://chromium-review.googlesource.com/1184335Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Commit-Queue: Gabriel Marin <gmx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585555}
parent 67734bf8
......@@ -114,12 +114,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
......
......@@ -1152,15 +1152,15 @@ static inline bool CheckCachedSizeClass(void *ptr) {
return cached_value == Static::pageheap()->GetDescriptor(p)->sizeclass;
}
static inline ATTRIBUTE_ALWAYS_INLINE void* CheckedMallocResult(void *result) {
static inline ATTRIBUTE_ALWAYS_INLINE void* CheckedMallocResult(void* result) {
ASSERT(result == NULL || CheckCachedSizeClass(result));
return result;
}
static inline ATTRIBUTE_ALWAYS_INLINE void* SpanToMallocResult(Span *span) {
Static::pageheap()->InvalidateCachedSizeClass(span->start);
return
CheckedMallocResult(reinterpret_cast<void*>(span->start << kPageShift));
return CheckedMallocResult(
reinterpret_cast<void*>(span->start << kPageShift));
}
static void* DoSampledAllocation(size_t size) {
......@@ -1375,7 +1375,8 @@ ATTRIBUTE_ALWAYS_INLINE inline void* do_malloc(size_t size) {
// The common case, and also the simplest. This just pops the
// size-appropriate freelist, after replenishing it if it's empty.
return CheckedMallocResult(cache->Allocate(allocated_size, cl, nop_oom_handler));
return CheckedMallocResult(
cache->Allocate(allocated_size, cl, nop_oom_handler));
}
static void *retry_malloc(void* size) {
......@@ -1411,6 +1412,13 @@ inline void free_null_or_invalid(void* ptr, void (*invalid_free_fn)(void*)) {
}
static ATTRIBUTE_NOINLINE void do_free_pages(Span* span, void* ptr) {
// 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");
SpinLockHolder h(Static::pageheap_lock());
if (span->sample) {
StackTrace* st = reinterpret_cast<StackTrace*>(span->objects);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment