Open
Description
@kcc @morehouse
I think the issue we encountered is related to #788, which was fixed in
llvm/llvm-project@52fd169. (The underlying cause is different, but the solution should also work for our issue.)
Unfortunately, part of the fix was reverted because it made tests fail on Darwin: llvm/llvm-project@7764a04
I put up a revision which attempts to configure the test setup so that the code doesn't have to worry about the special needs of Darwin (and other abort_on_error=1
platforms).
https://reviews.llvm.org/D57465
Path of the deadlock we encountered:
- Fuzzing with ASan encounters OOM error
- ASan tries to print stack trace, which uses
SymbolizePC
- SymbolizePC takes lock and uses
InternalAlloc
- InternalAlloc (fails because oom), calls
Die
- Die would normally
_exit
, but on Darwin (and otherabort_on_error=1
platforms) it callsabort
- libFuzzer has a signal handler for ABRT, calls
Fuzzer::CrashCallback
- Fuzzer::CrashCallback does not short-circuit, instead tries to print stack trace
- SymbolizePC deadlocks when it tries to take the lock again
The proposed fix re-activates short-circuiting in Fuzzer::CrashCallback
.
Please let me know whether my understanding is correct and if the fix seems reasonable.
Stacktrace:
thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
* frame #0: 0x000000019615cfc4 libsystem_kernel.dylib`syscall_thread_switch + 8
frame #1: 0x00000001962d98b8 libsystem_platform.dylib`_OSSpinLockLockYield + 116
frame #2: 0x0000000101aabd70 libclang_rt.asan_ios_dynamic.dylib`__sanitizer::Symbolizer::SymbolizePC(unsigned long) + 44
frame #3: 0x0000000101aaa5c8 libclang_rt.asan_ios_dynamic.dylib`__sanitizer::StackTrace::Print() const + 472
frame #4: 0x0000000101a9451c libclang_rt.asan_ios_dynamic.dylib`__sanitizer_print_stack_trace + 236
frame #5: 0x00000001000314c4 fuzzer.exe`fuzzer::PrintStackTrace() + 48
frame #6: 0x0000000100015188 fuzzer.exe`fuzzer::Fuzzer::CrashCallback() + 68
frame #7: 0x0000000100015144 fuzzer.exe`fuzzer::Fuzzer::StaticCrashSignalCallback() + 20
frame #8: 0x00000001962d9964 libsystem_platform.dylib`_sigtramp + 40
frame #9: 0x0000000196387424 libsystem_pthread.dylib`pthread_kill$VARIANT$mp + 380
frame #10: 0x00000001961dcfb4 libsystem_c.dylib`abort + 140
frame #11: 0x0000000101aa7e9c libclang_rt.asan_ios_dynamic.dylib`__sanitizer::Abort() + 64
frame #12: 0x0000000101aa783c libclang_rt.asan_ios_dynamic.dylib`__sanitizer::Die() + 176
frame #13: 0x0000000101a983e4 libclang_rt.asan_ios_dynamic.dylib`__sanitizer::ReportInternalAllocatorOutOfMemory(unsigned long) + 56
frame #14: 0x0000000101a983ac libclang_rt.asan_ios_dynamic.dylib`__sanitizer::InternalAlloc(unsigned long, __sanitizer::SizeClassAllocatorLocalCache<__sanitizer::SizeClassAllocator32<__sanitizer::AP32> >*, unsigned long) + 232
frame #15: 0x0000000101aab454 libclang_rt.asan_ios_dynamic.dylib`__sanitizer::SymbolizedStack::New(unsigned long) + 32
frame #16: 0x0000000101aabd78 libclang_rt.asan_ios_dynamic.dylib`__sanitizer::Symbolizer::SymbolizePC(unsigned long) + 52
frame #17: 0x0000000101aaa5c8 libclang_rt.asan_ios_dynamic.dylib`__sanitizer::StackTrace::Print() const + 472
frame #18: 0x0000000101a47e38 libclang_rt.asan_ios_dynamic.dylib`__asan::ErrorOutOfMemory::Print() + 124
frame #19: 0x0000000101a912b4 libclang_rt.asan_ios_dynamic.dylib`__asan::ScopedInErrorReport::~ScopedInErrorReport() + 68
frame #20: 0x0000000101a904cc libclang_rt.asan_ios_dynamic.dylib`__asan::ReportOutOfMemory(unsigned long, __sanitizer::BufferedStackTrace*) + 216
frame #21: 0x0000000101a3fbb0 libclang_rt.asan_ios_dynamic.dylib`__asan::Allocator::Allocate(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) + 1920
frame #22: 0x0000000101a4012c libclang_rt.asan_ios_dynamic.dylib`__asan::asan_memalign(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
frame #23: 0x0000000101a8af40 libclang_rt.asan_ios_dynamic.dylib`wrap_valloc + 368
...
frame #27: 0x000000010000929c fuzzer.exe`LLVMFuzzerTestOneInput