forked from OSchip/llvm-project
[Sanitizer] Get rid of dependency between sanitizer_common and asan/tsan runtimes: implement tool-specific Die and CheckFailed functions via callbacks
llvm-svn: 163603
This commit is contained in:
parent
1a471772b0
commit
5c6b93bc33
|
@ -27,10 +27,9 @@
|
||||||
#include "sanitizer_common/sanitizer_libc.h"
|
#include "sanitizer_common/sanitizer_libc.h"
|
||||||
#include "sanitizer_common/sanitizer_symbolizer.h"
|
#include "sanitizer_common/sanitizer_symbolizer.h"
|
||||||
|
|
||||||
namespace __sanitizer {
|
namespace __asan {
|
||||||
using namespace __asan;
|
|
||||||
|
|
||||||
void Die() {
|
static void AsanDie() {
|
||||||
static atomic_uint32_t num_calls;
|
static atomic_uint32_t num_calls;
|
||||||
if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
|
if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
|
||||||
// Don't die twice - run a busy loop.
|
// Don't die twice - run a busy loop.
|
||||||
|
@ -49,8 +48,8 @@ void Die() {
|
||||||
Exit(flags()->exitcode);
|
Exit(flags()->exitcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
static void AsanCheckFailed(const char *file, int line, const char *cond,
|
||||||
void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) {
|
u64 v1, u64 v2) {
|
||||||
Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n",
|
Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n",
|
||||||
file, line, cond, (uptr)v1, (uptr)v2);
|
file, line, cond, (uptr)v1, (uptr)v2);
|
||||||
// FIXME: check for infinite recursion without a thread-local counter here.
|
// FIXME: check for infinite recursion without a thread-local counter here.
|
||||||
|
@ -58,10 +57,6 @@ void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) {
|
||||||
ShowStatsAndAbort();
|
ShowStatsAndAbort();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace __sanitizer
|
|
||||||
|
|
||||||
namespace __asan {
|
|
||||||
|
|
||||||
// -------------------------- Flags ------------------------- {{{1
|
// -------------------------- Flags ------------------------- {{{1
|
||||||
static const int kDeafultMallocContextSize = 30;
|
static const int kDeafultMallocContextSize = 30;
|
||||||
|
|
||||||
|
@ -291,6 +286,9 @@ void __asan_init() {
|
||||||
// Make sure we are not statically linked.
|
// Make sure we are not statically linked.
|
||||||
AsanDoesNotSupportStaticLinkage();
|
AsanDoesNotSupportStaticLinkage();
|
||||||
|
|
||||||
|
// Install tool-specific callbacks in sanitizer_common.
|
||||||
|
SetDieCallback(AsanDie);
|
||||||
|
SetCheckFailedCallback(AsanCheckFailed);
|
||||||
SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
|
SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
|
||||||
|
|
||||||
// Initialize flags. This must be done early, because most of the
|
// Initialize flags. This must be done early, because most of the
|
||||||
|
|
|
@ -16,6 +16,33 @@
|
||||||
|
|
||||||
namespace __sanitizer {
|
namespace __sanitizer {
|
||||||
|
|
||||||
|
static void (*DieCallback)(void);
|
||||||
|
void SetDieCallback(void (*callback)(void)) {
|
||||||
|
DieCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NORETURN Die() {
|
||||||
|
if (DieCallback) {
|
||||||
|
DieCallback();
|
||||||
|
}
|
||||||
|
Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CheckFailedCallbackType CheckFailedCallback;
|
||||||
|
void SetCheckFailedCallback(CheckFailedCallbackType callback) {
|
||||||
|
CheckFailedCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NORETURN CheckFailed(const char *file, int line, const char *cond,
|
||||||
|
u64 v1, u64 v2) {
|
||||||
|
if (CheckFailedCallback) {
|
||||||
|
CheckFailedCallback(file, line, cond, v1, v2);
|
||||||
|
}
|
||||||
|
Report("Sanitizer CHECK failed: %s:%d %s (%zd, %zd)\n", file, line, cond,
|
||||||
|
v1, v2);
|
||||||
|
Die();
|
||||||
|
}
|
||||||
|
|
||||||
void RawWrite(const char *buffer) {
|
void RawWrite(const char *buffer) {
|
||||||
static const char *kRawWriteError = "RawWrite can't output requested buffer!";
|
static const char *kRawWriteError = "RawWrite can't output requested buffer!";
|
||||||
uptr length = (uptr)internal_strlen(buffer);
|
uptr length = (uptr)internal_strlen(buffer);
|
||||||
|
|
|
@ -120,11 +120,23 @@ void DisableCoreDumper();
|
||||||
void DumpProcessMap();
|
void DumpProcessMap();
|
||||||
void SleepForSeconds(int seconds);
|
void SleepForSeconds(int seconds);
|
||||||
void SleepForMillis(int millis);
|
void SleepForMillis(int millis);
|
||||||
void NORETURN Exit(int exitcode);
|
|
||||||
void NORETURN Abort();
|
|
||||||
int Atexit(void (*function)(void));
|
int Atexit(void (*function)(void));
|
||||||
void SortArray(uptr *array, uptr size);
|
void SortArray(uptr *array, uptr size);
|
||||||
|
|
||||||
|
// Exit
|
||||||
|
void NORETURN Abort();
|
||||||
|
void NORETURN Exit(int exitcode);
|
||||||
|
void NORETURN Die();
|
||||||
|
void NORETURN SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
|
||||||
|
|
||||||
|
// Specific tools may override behavior of "Die" and "CheckFailed" functions
|
||||||
|
// to do tool-specific job.
|
||||||
|
void SetDieCallback(void (*callback)(void));
|
||||||
|
typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
|
||||||
|
u64, u64);
|
||||||
|
void SetCheckFailedCallback(CheckFailedCallbackType callback);
|
||||||
|
|
||||||
// Math
|
// Math
|
||||||
INLINE bool IsPowerOfTwo(uptr x) {
|
INLINE bool IsPowerOfTwo(uptr x) {
|
||||||
return (x & (x - 1)) == 0;
|
return (x & (x - 1)) == 0;
|
||||||
|
|
|
@ -43,14 +43,6 @@
|
||||||
|
|
||||||
extern "C" int arch_prctl(int code, __sanitizer::uptr *addr);
|
extern "C" int arch_prctl(int code, __sanitizer::uptr *addr);
|
||||||
|
|
||||||
namespace __sanitizer {
|
|
||||||
|
|
||||||
void Die() {
|
|
||||||
_exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace __sanitizer
|
|
||||||
|
|
||||||
namespace __tsan {
|
namespace __tsan {
|
||||||
|
|
||||||
#ifndef TSAN_GO
|
#ifndef TSAN_GO
|
||||||
|
|
|
@ -37,14 +37,6 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
|
||||||
namespace __sanitizer {
|
|
||||||
|
|
||||||
void Die() {
|
|
||||||
_exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace __sanitizer
|
|
||||||
|
|
||||||
namespace __tsan {
|
namespace __tsan {
|
||||||
|
|
||||||
ScopedInRtl::ScopedInRtl() {
|
ScopedInRtl::ScopedInRtl() {
|
||||||
|
|
|
@ -165,6 +165,9 @@ void Initialize(ThreadState *thr) {
|
||||||
if (is_initialized)
|
if (is_initialized)
|
||||||
return;
|
return;
|
||||||
is_initialized = true;
|
is_initialized = true;
|
||||||
|
// Install tool-specific callbacks in sanitizer_common.
|
||||||
|
SetCheckFailedCallback(TsanCheckFailed);
|
||||||
|
|
||||||
ScopedInRtl in_rtl;
|
ScopedInRtl in_rtl;
|
||||||
#ifndef TSAN_GO
|
#ifndef TSAN_GO
|
||||||
InitializeAllocator();
|
InitializeAllocator();
|
||||||
|
|
|
@ -65,6 +65,8 @@ typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
|
||||||
Allocator *allocator();
|
Allocator *allocator();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void TsanCheckFailed(const char *file, int line, const char *cond,
|
||||||
|
u64 v1, u64 v2);
|
||||||
void TsanPrintf(const char *format, ...);
|
void TsanPrintf(const char *format, ...);
|
||||||
|
|
||||||
// FastState (from most significant bit):
|
// FastState (from most significant bit):
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
#include "tsan_mman.h"
|
#include "tsan_mman.h"
|
||||||
#include "tsan_flags.h"
|
#include "tsan_flags.h"
|
||||||
|
|
||||||
namespace __sanitizer {
|
namespace __tsan {
|
||||||
using namespace __tsan;
|
|
||||||
|
|
||||||
void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) {
|
void TsanCheckFailed(const char *file, int line, const char *cond,
|
||||||
|
u64 v1, u64 v2) {
|
||||||
ScopedInRtl in_rtl;
|
ScopedInRtl in_rtl;
|
||||||
TsanPrintf("FATAL: ThreadSanitizer CHECK failed: "
|
TsanPrintf("FATAL: ThreadSanitizer CHECK failed: "
|
||||||
"%s:%d \"%s\" (0x%zx, 0x%zx)\n",
|
"%s:%d \"%s\" (0x%zx, 0x%zx)\n",
|
||||||
|
@ -34,10 +34,6 @@ void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) {
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace __sanitizer
|
|
||||||
|
|
||||||
namespace __tsan {
|
|
||||||
|
|
||||||
// Can be overriden by an application/test to intercept reports.
|
// Can be overriden by an application/test to intercept reports.
|
||||||
#ifdef TSAN_EXTERNAL_HOOKS
|
#ifdef TSAN_EXTERNAL_HOOKS
|
||||||
bool OnReport(const ReportDesc *rep, bool suppressed);
|
bool OnReport(const ReportDesc *rep, bool suppressed);
|
||||||
|
|
Loading…
Reference in New Issue