Issue 152459
Summary Very slow symbolizer invocation in libfuzzer with Go c-archive library
Labels compiler-rt, compiler-rt:fuzzer
Assignees
Reporter chfast
    I have a relatively simple fuzzing tool using libfuzzer. It is fuzzing C++ and Go code. The Go code is built to the "c-archive" with `go build -buildmode=c-archive -tags=libfuzzer -gcflags=-d=libfuzzer`. All seems to work correctly, except the moment the libfuzzer needs the function names (e.g. to print a stack trace or to focus a function or to report new functions covered) there is a big minutes long pause.

My investigation lead me to the `llvm-symbolizer` subprocess invocation. The below is libfuzzer output with UBSAN verbosity increased. The second module with 2 PCs seems to be the Go code.

```
export UBSAN_OPTIONS=verbosity=4
fuzz ../corpus -use_value_profile=1 -focus_function=FUNC -runs=0 
==145033==Using llvm-symbolizer found at: /usr/bin/llvm-symbolizer-21
==145033==Installed the sigaction for signal 11
==145033==Installed the sigaction for signal 7
==145033==Installed the sigaction for signal 8
INFO: Seed: 32135115
INFO: Loaded 2 modules   (11211 inline 8-bit counters): 11209 [0x5f4829450bf2, 0x5f48294537bb), 2 [0x5f4829e18e00, 0x5f4829e18e02), 
INFO: Loaded 2 PC tables (11211 PCs): 11209 [0x5f48294537c0,0x5f482947f450), 2 [0xc00001a120,0xc00001a140), 
INFO: 224 files found in ../corpus
==145033==Launching Symbolizer process: /usr/bin/llvm-symbolizer-21 --demangle --inlines --default-arch=x86_64
(PAUSE)
ERROR: Failed to set focus function. Make sure the function name is valid (FUNC) and symbolization is enabled.
```

However, I'm not sure the `llvm-symbolizer` is slow. Some perf tracing suggest this is the subprocess management. According to `perf record` mostly of the time is spent on closing file descriptors.

```
 94.97%    19.76%  fuzz             fuzz                  [.] __sanitizer::internal_close(int)
            |          
 |--89.99%--__sanitizer::internal_close(int)
            |          | 
            |          |--32.39%--entry_SYSCALL_64_after_hwframe
 |          |          |          
            |          | |--26.76%--do_syscall_64
            |          |          |          | 
            |          |          |          |--12.98%--x64_sys_call
 |          |          |          |          |          
 |          |          |          |          |--10.60%--__x64_sys_close
 |          |          |          |          |          |          
 |          |          |          |          | |--6.06%--_raw_spin_lock
            |          |          |          | |          |          
            |          |          |          | |          |--2.44%--file_close_fd
            |          |          | |          |          |          |          
            | |          |          |          |          | --0.52%--file_close_fd_locked
            |          |          |          | |          |          
            |          |          | |          |          |--0.90%--file_close_fd_locked
            | |          |          |          |          |          
            | |          |          |          |           --0.58%--_raw_spin_unlock
 |          |          |          |          |          
 |          |          |          |           --0.53%--file_close_fd
 |          |          |          |          
            |          | |          |--7.25%--syscall_exit_to_user_mode
            |          | |          |          |          
            |          | |          |          |--3.34%--arch_exit_to_user_mode_prepare.isra.0
 |          |          |          |          |          |          
 |          |          |          |          | --0.66%--fpregs_assert_state_consistent
            |          |          | |          |          
            |          |          | |          |--1.26%--syscall_exit_to_user_mode_prepare
            | |          |          |          |          
            |          | |          |           --0.65%--fpregs_assert_state_consistent
 |          |          |          |          
            |          | |          |--1.16%--arch_exit_to_user_mode_prepare.isra.0
            | |          |          |          
            |          | |           --0.58%--syscall_exit_to_user_mode_prepare
            | |          |          
            |          | --0.71%--syscall_exit_to_user_mode
            |          |          
 |          |--28.62%--entry_SYSCALL_64
            |          | 
            |          |--5.53%--entry_SYSRETQ_unsafe_stack
 |          |          
            | |--1.71%--syscall_return_via_sysret
            |          |          
 |          |--1.36%--entry_SYSCALL_64_safe_stack
            | |          
            |           --0.68%--do_syscall_64
            | 
             --4.99%--__sanitizer::StartSubprocess(char const*, char const* const*, char const* const*, int, int, int)
```

The `llvm-symbolizer` run is only 2% if I interpret the perf report correctly.

```
     1.97%     0.00%  llvm-symbolizer  llvm-symbolizer [.] 0x0000564172f90db5
            |
            ---0x564172f90db5
 __libc_start_main@@GLIBC_2.34
 __libc_start_call_main
               0x564172f977c3
               | 
                --1.86%--0x564172f927e6
 0x564172f941a6
                          0x564172f95622
 llvm::symbolize::LLVMSymbolizer::symbolizeInlinedCode(llvm::StringRef, llvm::object::SectionedAddress)
 llvm::Expected<llvm::DIInliningInfo> llvm::symbolize::LLVMSymbolizer::symbolizeInlinedCodeCommon<llvm::StringRef>(llvm::StringRef const&, llvm::object::SectionedAddress)
                          | 
 --1.82%--llvm::symbolize::SymbolizableObjectFile::symbolizeInlinedCode(llvm::object::SectionedAddress, llvm::DILineInfoSpecifier, bool) const
 llvm::DWARFContext::getInliningInfoForAddress(llvm::object::SectionedAddress, llvm::DILineInfoSpecifier)
                                     | 
 --1.61%--llvm::DWARFUnit::getInlinedChainForAddress(unsigned long, llvm::SmallVectorImpl<llvm::DWARFDie>&)
 llvm::DWARFUnit::getSubroutineForAddress(unsigned long)
 |          
 |--1.03%--llvm::DWARFUnit::tryExtractDIEsIfNeeded(bool)
 |          |          
 | --1.01%--llvm::DWARFUnit::extractDIEsToVector(bool, bool, std::vector<llvm::DWARFDebugInfoEntry, std::allocator<llvm::DWARFDebugInfoEntry> >&) const
 |          
 --0.58%--llvm::DWARFUnit::updateAddressDieMap(llvm::DWARFDie)
 llvm::DWARFUnit::updateAddressDieMap(llvm::DWARFDie)
 |          
 --0.51%--llvm::DWARFUnit::updateAddressDieMap(llvm::DWARFDie)
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to