`-Zcoverage-options=branch`: `llvm-cov export` SIGSEGVs in `llvm::coverage::CoverageMapping::getInstantiationGroups` (regression in LLVM 21.1.1)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Summary
Generating branch coverage (cargo llvm-cov --branch, i.e. -Zcoverage-options=branch)
for a generic, async_trait-using crate makes the bundled llvm-cov crash with SIGSEGV
while reading the coverage mapping. The same crate exports fine:
- with line coverage (no
--branch), and - with branch coverage on older toolchains (LLVM ≤ 21.1.0).
The crash first appears around LLVM 21.1.4/21.1.5 (rustc 1.93.0-nightly) and is also present
in the current nightly (LLVM 22); LLVM ≤ 21.1.3 is fine. It is a hard crash, so branch coverage
is currently unusable on affected toolchains for such crates.
Steps to reproduce
git clone https://github.com/cloudflare/pingora # any recent checkout
cd pingora
rustup toolchain install nightly-2025-12-01 --component llvm-tools # rustc 1.93.0-nightly, LLVM 21.1.5
cargo +nightly-2025-12-01 install cargo-llvm-cov --locked
# crashes:
cargo +nightly-2025-12-01 llvm-cov --branch --cobertura \
--output-path cov.xml -p pingora-memory-cache --lib
Result:
error: failed to generate report: process didn't exit successfully:
`.../nightly-2025-12-01-.../bin/llvm-cov export -format=lcov ... -object .../pingora_memory_cache-<hash>` (signal: 11 (SIGSEGV) (core dumped))
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/
(cargo-llvm-cov only shells out to llvm-cov export; calling that llvm-cov directly on
the single object + profdata reproduces the SIGSEGV, so this is not a cargo-llvm-cov issue.)
Backtrace
#0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int)
#1 SignalHandler(int, siginfo_t*, void*)
#2 __restore_rt
#3 llvm::coverage::CoverageMapping::getInstantiationGroups(llvm::StringRef) const
libLLVM.so.21.1-rust-1.93.0-nightly
#4 llvm::CoverageReport::prepareSingleFileReport(...) CoverageReport.cpp
#5 std::_Function_handler<void (), ...>::_M_invoke(...) CoverageReport.cpp
#6 ... CodeCoverage.cpp
#7 std::__future_base::_State_baseV2::_M_do_set(...) CodeCoverage.cpp
#8 __pthread_once_slow
...
What narrows it down
- Branch-specific: removing
--branch(plain line coverage) exports fine on the same toolchain. - Module-specific: the crate has two modules. Building coverage for
lib.rsalone (sync,
genericMemoryCache) exports fine even on LLVM 22. Re-adding theasync_trait-based
read_through.rs(#[async_trait] trait Lookup/MultiLookup, genericRTCache<K, T, CB>)
is what triggers the crash → the trigger involvesasync_trait+ generics + branch regions
(getInstantiationGroupshandles per-instantiation grouping of monomorphized functions). - A trivial generic+branch crate, and a small
async_trait+generic+branch crate, did not
reproduce — the trigger needs the fuller generic-async-cache shape, so the smallest
self-contained reproducer I have is thepingora-memory-cachecrate above.
Version bisection (export of the same crate, --branch)
Exporting --branch for the pingora-memory-cache crate, per toolchain (actually tested):
| toolchain | rustc | LLVM | branch export |
|---|---|---|---|
| nightly-2025-08-01 | 1.90.0-nightly | 20.1.8 | ✅ ok |
| nightly-2025-09-01 | 1.91.0-nightly | 21.1.0 | ✅ ok |
| nightly-2025-09-15 | 1.92.0-nightly | 21.1.1 | ✅ ok |
| nightly-2025-10-01 | 1.92.0-nightly | 21.1.2 | ✅ ok |
| nightly-2025-11-01 | 1.93.0-nightly | 21.1.3 | ✅ ok |
| nightly-2025-12-01 | 1.93.0-nightly | 21.1.5 | ❌ SIGSEGV |
| latest (2026-05) | 1.98.0-nightly | 22.1.6 | ❌ SIGSEGV |
→ regression introduced between LLVM 21.1.3 and 21.1.5 (21.1.4 not tested).
Note on attribution: each toolchain rebuilds the objects with its own rustc/LLVM, so I cannot
cleanly separate "rustc emits bad mapping" from "llvm-cov mishandles valid mapping" — the
coverage-mapping format version also changes across LLVM releases. Reporting the observation;
attribution is for the maintainers.
rustc -Vv (a crashing version)
rustc 1.93.0-nightly (b84478a1c 2025-11-30)
host: x86_64-unknown-linux-gnu
release: 1.93.0-nightly
LLVM version: 21.1.5
Host OS: Alibaba Cloud Linux 3 (glibc 2.32), x86_64. cargo-llvm-cov 0.8.7.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the crash with the pingora-memory-cache command and affected nightly toolchain, then inspect llvm::coverage::CoverageMapping::getInstantiationGroups in the backtrace and CoverageReport.cpp. Compare branch exports with LLVM 21.1.3 and 21.1.5; done means the affected generic async_trait crate exports branch coverage without SIGSEGV.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100