diff options
author | Vitaly Buka <vitalybuka@google.com> | 2017-11-02 04:12:10 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2017-11-02 04:12:10 +0000 |
commit | bcc227ee4af1ef3e63033b35dcb1d5627a3b2941 (patch) | |
tree | 1772d0d4f25219059bc98e9c65baeef15d268524 /lib/fuzzer/FuzzerLoop.cpp | |
parent | a638156d40e40dd33b5363204b33e3a9c5a026d6 (diff) |
[fuzzer] Fix nested mallocs
Summary: Nested mallocs are possible with internal symbolizer.
Reviewers: kcc
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D39397
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317186 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/fuzzer/FuzzerLoop.cpp')
-rw-r--r-- | lib/fuzzer/FuzzerLoop.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/lib/fuzzer/FuzzerLoop.cpp b/lib/fuzzer/FuzzerLoop.cpp index 9bea05f18..f4771e1df 100644 --- a/lib/fuzzer/FuzzerLoop.cpp +++ b/lib/fuzzer/FuzzerLoop.cpp @@ -70,18 +70,39 @@ struct MallocFreeTracer { std::atomic<size_t> Mallocs; std::atomic<size_t> 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<std::recursive_mutex> 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<std::mutex> 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<std::mutex> Lock(MallocFreeStackMutex); + TraceLock Lock; + if (Lock.IsDisabled()) + return; Printf("FREE[%zd] %p\n", N, ptr); if (TraceLevel >= 2 && EF) EF->__sanitizer_print_stack_trace(); |