add debug code to chase down a rare crash in asan/lsan https://github.com/google/sanitizers/issues/1193

Summary: add debug code to chase down a rare crash in asan/lsan https://github.com/google/sanitizers/issues/1193

Reviewers: vitalybuka

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D80967
This commit is contained in:
Kostya Serebryany 2020-06-01 17:33:49 -07:00
parent 8a8d703be0
commit 2e6c3e3e7b
2 changed files with 19 additions and 0 deletions

View File

@ -1037,8 +1037,19 @@ uptr PointsIntoChunk(void* p) {
return 0;
}
// Debug code. Delete once issue #1193 is chased down.
extern "C" SANITIZER_WEAK_ATTRIBUTE const char *__lsan_current_stage;
uptr GetUserBegin(uptr chunk) {
__asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(chunk);
if (!m)
Printf(
"ASAN is about to crash with a CHECK failure.\n"
"The ASAN developers are trying to chaise down this bug,\n"
"so if you've encountered this bug please let us know.\n"
"See also: https://github.com/google/sanitizers/issues/1193\n"
"chunk: %p caller %p __lsan_current_stage %s\n",
chunk, GET_CALLER_PC(), __lsan_current_stage);
CHECK(m);
return m->Beg();
}

View File

@ -25,6 +25,8 @@
#include "sanitizer_common/sanitizer_thread_registry.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"
extern "C" const char *__lsan_current_stage = "unknown";
#if CAN_SANITIZE_LEAKS
namespace __lsan {
@ -34,6 +36,7 @@ BlockingMutex global_mutex(LINKER_INITIALIZED);
Flags lsan_flags;
void DisableCounterUnderflow() {
if (common_flags()->detect_leaks) {
Report("Unmatched call to __lsan_enable().\n");
@ -363,6 +366,7 @@ static void FloodFillTag(Frontier *frontier, ChunkTag tag) {
// ForEachChunk callback. If the chunk is marked as leaked, marks all chunks
// which are reachable from it as indirectly leaked.
static void MarkIndirectlyLeakedCb(uptr chunk, void *arg) {
__lsan_current_stage = "MarkIndirectlyLeakedCb";
chunk = GetUserBegin(chunk);
LsanMetadata m(chunk);
if (m.allocated() && m.tag() != kReachable) {
@ -375,6 +379,7 @@ static void MarkIndirectlyLeakedCb(uptr chunk, void *arg) {
// frontier.
static void CollectIgnoredCb(uptr chunk, void *arg) {
CHECK(arg);
__lsan_current_stage = "CollectIgnoredCb";
chunk = GetUserBegin(chunk);
LsanMetadata m(chunk);
if (m.allocated() && m.tag() == kIgnored) {
@ -404,6 +409,7 @@ struct InvalidPCParam {
static void MarkInvalidPCCb(uptr chunk, void *arg) {
CHECK(arg);
InvalidPCParam *param = reinterpret_cast<InvalidPCParam *>(arg);
__lsan_current_stage = "MarkInvalidPCCb";
chunk = GetUserBegin(chunk);
LsanMetadata m(chunk);
if (m.allocated() && m.tag() != kReachable && m.tag() != kIgnored) {
@ -479,6 +485,7 @@ static void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads,
// ForEachChunk callback. Resets the tags to pre-leak-check state.
static void ResetTagsCb(uptr chunk, void *arg) {
(void)arg;
__lsan_current_stage = "ResetTagsCb";
chunk = GetUserBegin(chunk);
LsanMetadata m(chunk);
if (m.allocated() && m.tag() != kIgnored)
@ -495,6 +502,7 @@ static void PrintStackTraceById(u32 stack_trace_id) {
static void CollectLeaksCb(uptr chunk, void *arg) {
CHECK(arg);
LeakReport *leak_report = reinterpret_cast<LeakReport *>(arg);
__lsan_current_stage = "CollectLeaksCb";
chunk = GetUserBegin(chunk);
LsanMetadata m(chunk);
if (!m.allocated()) return;