Commit b6da6b18 authored by kaiwang@chromium.org's avatar kaiwang@chromium.org

Add a chromium version abort function for tcmalloc: Abort().

This is because on some platform (e.g. Windows), the way to implement abort()
is different so chrome's crash service can not detect the crash but treat as
normal exit. See http://code.google.com/p/chromium/issues/detail?id=118665 for
some detail.
In this implementation, a segment fault will be triggered and this will be
treated as crash on all platforms.

BUG=127724

Review URL: https://chromiumcodereview.appspot.com/10384117

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137013 0039d316-1c4b-4281-b951-d872f2087c98
parent 0f8afe8e
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ---
// On some platforms abort() is implemented in a way that Chrome's crash
// reporter treats it as a normal exit. See issue:
// http://code.google.com/p/chromium/issues/detail?id=118665
// So we replace abort with a
// segmentation fault, that crash reporter can always detect.
#ifndef BASE_ABORT_H_
#define BASE_ABORT_H_
#if defined(TCMALLOC_USE_SYSTEM_ABORT)
#include <stdlib.h>
namespace tcmalloc {
inline void Abort() {
abort();
}
} // namespace tcmalloc
#else
namespace tcmalloc {
inline void Abort() {
// Make a segmentation fault to force abort.
*reinterpret_cast<int*>(NULL) = 0x2001;
}
} // namespace tcmalloc
#endif
#endif // BASE_ABORT_H_
......@@ -38,7 +38,7 @@
#define BASE_ATOMICOPS_INTERNALS_ARM_GENERIC_H_
#include <stdio.h>
#include <stdlib.h>
#include "base/abort.h"
#include "base/basictypes.h"
typedef int32_t Atomic32;
......@@ -160,7 +160,7 @@ inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
inline void NotImplementedFatalError(const char *function_name) {
fprintf(stderr, "64-bit %s() not implemented on this platform\n",
function_name);
abort();
tcmalloc::Abort();
}
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
......
......@@ -40,6 +40,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "base/abort.h"
#include "base/basictypes.h" // For COMPILE_ASSERT
// The LDREXD and STREXD instructions in ARM all v7 variants or above. In v6,
......@@ -287,7 +288,7 @@ inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
inline void NotImplementedFatalError(const char *function_name) {
fprintf(stderr, "64-bit %s() not implemented on this platform\n",
function_name);
abort();
tcmalloc::Abort();
}
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
......
......@@ -40,6 +40,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "base/abort.h"
#include "base/basictypes.h" // For COMPILE_ASSERT
typedef int32 Atomic32;
......@@ -350,7 +351,7 @@ inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
inline void NotImplementedFatalError(const char *function_name) {
fprintf(stderr, "64-bit %s() not implemented on this platform\n",
function_name);
abort();
tcmalloc::Abort();
}
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
......
......@@ -45,6 +45,7 @@
#include <string.h> // for strlen(), strcmp()
#include <assert.h>
#include <errno.h> // for errno
#include "base/abort.h"
#include "base/commandlineflags.h"
// On some systems (like freebsd), we can't call write() at all in a
......@@ -85,7 +86,7 @@ DECLARE_int32(verbose);
if (!(condition)) { \
WRITE_TO_STDERR("Check failed: " #condition "\n", \
sizeof("Check failed: " #condition "\n")-1); \
abort(); \
tcmalloc::Abort(); \
} \
} while (0)
......@@ -95,7 +96,7 @@ DECLARE_int32(verbose);
if (!(condition)) { \
WRITE_TO_STDERR("Check failed: " #condition ": " message "\n", \
sizeof("Check failed: " #condition ": " message "\n")-1);\
abort(); \
tcmalloc::Abort(); \
} \
} while (0)
......@@ -118,7 +119,7 @@ enum { DEBUG_MODE = 1 };
sizeof("Check failed: " #condition ": ")-1); \
WRITE_TO_STDERR(strerror(err_no), strlen(strerror(err_no))); \
WRITE_TO_STDERR("\n", sizeof("\n")-1); \
abort(); \
tcmalloc::Abort(); \
} \
} while (0)
......@@ -135,7 +136,7 @@ enum { DEBUG_MODE = 1 };
do { \
if (!((val1) op (val2))) { \
fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \
abort(); \
tcmalloc::Abort(); \
} \
} while (0)
......@@ -204,8 +205,10 @@ inline void LogPrintf(int severity, const char* pat, va_list ap) {
strcat(buf, "\n");
}
WRITE_TO_STDERR(buf, strlen(buf));
if ((severity) == FATAL)
abort(); // LOG(FATAL) indicates a big problem, so don't run atexit() calls
if ((severity) == FATAL) {
// LOG(FATAL) indicates a big problem, so don't run atexit() calls
tcmalloc::Abort();
}
}
// Note that since the order of global constructors is unspecified,
......
......@@ -138,7 +138,7 @@
#endif
#include <assert.h>
#include <stdlib.h> // for abort()
#include "base/abort.h"
#define MUTEX_NAMESPACE perftools_mutex_namespace
......@@ -234,16 +234,16 @@ void Mutex::ReaderUnlock() { Unlock(); }
#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
if (is_safe_ && fncall(&mutex_) != 0) abort(); \
if (is_safe_ && fncall(&mutex_) != 0) tcmalloc::Abort(); \
} while (0)
Mutex::Mutex() : destroy_(true) {
SetIsSafe();
if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) tcmalloc::Abort();
}
Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
SetIsSafe();
if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) tcmalloc::Abort();
}
Mutex::~Mutex() { if (destroy_) SAFE_PTHREAD(pthread_rwlock_destroy); }
void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); }
......@@ -257,16 +257,16 @@ void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
#elif defined(HAVE_PTHREAD)
#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
if (is_safe_ && fncall(&mutex_) != 0) abort(); \
if (is_safe_ && fncall(&mutex_) != 0) tcmalloc::Abort(); \
} while (0)
Mutex::Mutex() : destroy_(true) {
SetIsSafe();
if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) tcmalloc::Abort();
}
Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
SetIsSafe();
if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) tcmalloc::Abort();
}
Mutex::~Mutex() { if (destroy_) SAFE_PTHREAD(pthread_mutex_destroy); }
void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); }
......
......@@ -68,6 +68,7 @@
#include <gperftools/malloc_hook.h>
#include <gperftools/stacktrace.h>
#include "addressmap-inl.h"
#include "base/abort.h"
#include "base/commandlineflags.h"
#include "base/googleinit.h"
#include "base/logging.h"
......@@ -889,7 +890,7 @@ static void TracePrintf(int fd, const char *fmt, ...) {
write(STDERR_FILENO, "Unimplemented TracePrintf format\n", 33);
write(STDERR_FILENO, p, 2);
write(STDERR_FILENO, "\n", 1);
abort();
tcmalloc::Abort();
}
p++;
if (base != 0) {
......
......@@ -44,8 +44,8 @@
// consider that allocation to be a leak, even though it's not (since
// the allocated object is reachable from global data and hence "live").
#include <stdlib.h> // for abort()
#include <gperftools/malloc_extension.h>
#include "base/abort.h"
// A dummy variable to refer from heap-checker.cc. This is to make
// sure this file is not optimized out by the linker.
......@@ -76,7 +76,7 @@ class HeapLeakCheckerGlobalPrePost {
++count_;
}
~HeapLeakCheckerGlobalPrePost() {
if (count_ <= 0) abort();
if (count_ <= 0) tcmalloc::Abort();
--count_;
if (count_ == 0) HeapLeakChecker_AfterDestructors();
}
......
......@@ -41,6 +41,7 @@
#endif
#include <gperftools/malloc_extension.h>
#include "base/abort.h"
#include "base/logging.h" // for perftools_vsnprintf
#include "base/spinlock.h" // for SpinLockHolder, SpinLock
......@@ -116,7 +117,7 @@ void Log(LogMode mode, const char* filename, int line,
(*log_message_writer)(stats_buffer, strlen(stats_buffer));
}
abort();
Abort();
}
bool Logger::Add(const LogItem& item) {
......
......@@ -76,7 +76,7 @@ DEFINE_int64(memfs_malloc_limit_mb,
"specified number of MiB. 0 == no limit.");
DEFINE_bool(memfs_malloc_abort_on_fail,
EnvToBool("TCMALLOC_MEMFS_ABORT_ON_FAIL", false),
"abort() whenever memfs_malloc fails to satisfy an allocation "
"abort whenever memfs_malloc fails to satisfy an allocation "
"for any reason.");
DEFINE_bool(memfs_malloc_ignore_mmap_fail,
EnvToBool("TCMALLOC_MEMFS_IGNORE_MMAP_FAIL", false),
......
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