From: Vitaly Buka Date: Thu, 2 Nov 2017 04:12:10 +0000 (+0000) Subject: [fuzzer] Fix nested mallocs X-Git-Tag: llvmorg-6.0.0-rc1~4355 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7d22324b879003e1e4c3d25b8c3ae2d11eefea50;p=platform%2Fupstream%2Fllvm.git [fuzzer] Fix nested mallocs Summary: Nested mallocs are possible with internal symbolizer. Reviewers: kcc Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39397 llvm-svn: 317186 --- diff --git a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp index 9bea05f..f4771e1 100644 --- a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp @@ -70,18 +70,39 @@ struct MallocFreeTracer { std::atomic Mallocs; std::atomic Frees; int TraceLevel = 0; + + std::recursive_mutex TraceMutex; + bool TraceDisabled = false; }; static MallocFreeTracer AllocTracer; -static std::mutex MallocFreeStackMutex; +// Locks printing and avoids nested hooks triggered from mallocs/frees in +// sanitizer. +class TraceLock { +public: + TraceLock() : Lock(AllocTracer.TraceMutex) { + AllocTracer.TraceDisabled = !AllocTracer.TraceDisabled; + } + ~TraceLock() { AllocTracer.TraceDisabled = !AllocTracer.TraceDisabled; } + + bool IsDisabled() const { + // This is already inverted value. + return !AllocTracer.TraceDisabled; + } + +private: + std::lock_guard Lock; +}; ATTRIBUTE_NO_SANITIZE_MEMORY void MallocHook(const volatile void *ptr, size_t size) { size_t N = AllocTracer.Mallocs++; F->HandleMalloc(size); if (int TraceLevel = AllocTracer.TraceLevel) { - std::lock_guard Lock(MallocFreeStackMutex); + TraceLock Lock; + if (Lock.IsDisabled()) + return; Printf("MALLOC[%zd] %p %zd\n", N, ptr, size); if (TraceLevel >= 2 && EF) EF->__sanitizer_print_stack_trace(); @@ -92,7 +113,9 @@ ATTRIBUTE_NO_SANITIZE_MEMORY void FreeHook(const volatile void *ptr) { size_t N = AllocTracer.Frees++; if (int TraceLevel = AllocTracer.TraceLevel) { - std::lock_guard Lock(MallocFreeStackMutex); + TraceLock Lock; + if (Lock.IsDisabled()) + return; Printf("FREE[%zd] %p\n", N, ptr); if (TraceLevel >= 2 && EF) EF->__sanitizer_print_stack_trace();