`alloc` contributes unwind info despite `-C force-unwind-tables=false`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I'm seeing unwind info being emitted in a force-unwind-tables=false, build-std context. Specifically I'm seeing this emitted for two alloc shim functions (see below).
This surfaced in an embedded project in which I naturally want all debug info to be 'offline'. To help ensure that, I had an linker script assert on there being no .eh_frame contents in the final link. This assert started firing once I started linking in the alloc crate, which prompted this bug report.
I'm sure this could be reproduced by poking at the debug info in the object files in liballoc.rlib, but I figured compiling and linking this minimal program would make for a more convenient repro:
#![no_std]
#![no_main]
extern crate alloc;
use alloc::alloc::{GlobalAlloc, Layout};
use alloc::vec::Vec;
struct NoOpAllocator;
unsafe impl GlobalAlloc for NoOpAllocator {
unsafe fn alloc(&self, _: Layout) -> *mut u8 {
core::ptr::null_mut()
}
unsafe fn dealloc(&self, _: *mut u8, _: Layout) {}
}
#[global_allocator]
static ALLOC: NoOpAllocator = NoOpAllocator;
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[unsafe(no_mangle)]
pub extern "C" fn _start() -> ! {
let mut v: Vec<u8> = Vec::new();
v.push(1);
loop {}
}
Repro script:
SYSROOT=$(rustc --print sysroot)
SRC="$SYSROOT/lib/rustlib/src/rust/library"
TARGET=riscv32imac-unknown-none-elf
# Build core, compiler_builtins, and alloc from source.
rustc --edition 2024 --crate-type rlib --crate-name core \
--target $TARGET \
"$SRC/core/src/lib.rs" -o libcore.rlib
rustc --edition 2024 --crate-type rlib --crate-name compiler_builtins \
--target $TARGET \
--extern core=libcore.rlib \
--cfg 'feature="compiler-builtins"' \
--cfg 'feature="mem"' \
"$SRC/compiler-builtins/compiler-builtins/src/lib.rs" \
-o libcompiler_builtins.rlib
rustc --edition 2024 --crate-type rlib --crate-name alloc \
--target $TARGET \
--extern core=libcore.rlib \
--extern compiler_builtins=libcompiler_builtins.rlib \
"$SRC/alloc/src/lib.rs" -o liballoc.rlib
rustc --edition 2024 --crate-type bin --target $TARGET \
-L . \
--extern core=libcore.rlib \
--extern alloc=liballoc.rlib \
--extern compiler_builtins=libcompiler_builtins.rlib \
-o repro repro.rs
llvm-readelf --unwind repro &> unwind.txt
llvm-objdump --disassemble --demangle repro &> dis.txt
In unwind.txt I see two entries that point to these functions:
00015190 <__rustc::__rust_alloc_error_handler>:
15190: 00000317 auipc t1, 0x0
15194: 0de30067 jr 0xde(t1) <__rustc::__rdl_alloc_error_handler>
00015198 <__rustc::__rust_no_alloc_shim_is_unstable_v2>:
15198: 8082 ret
Meta
$ rustc --version --verbose
rustc 1.95.0-nightly (859951e3c 2026-02-24)
binary: rustc
commit-hash: 859951e3c7c9d0322c39bad49221937455bdffcd
commit-date: 2026-02-24
host: x86_64-unknown-linux-gnu
release: 1.95.0-nightly
LLVM version: 22.1.0
(I also saw the same with a 2026-01-01 nightly on a macbook)
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
Start with the provided no_std repro script and inspect the generated liballoc.rlib and final binary with llvm-readelf --unwind and llvm-objdump --disassemble --demangle. Trace how the two alloc shim functions receive unwind information under -C force-unwind-tables=false; done means the repro no longer reports .eh_frame entries for those functions.
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
- 48/100