#[naked] function emits no DWARF info
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
I looks as if #[naked] functions are not being associated with the usual function debug information (e.g, a DW_TAG_subprogram entry in .debug_info). This results in debuggers and symbolizers being unable to resolve source locations for addresses within naked functions. This seems broadly relevant to embedded Rust (the context in which this came up for me).
My understanding is that the "naked" contract concerns codegen (i.e., no prologue/epilogue), but not debug metadata. For contrast, Clang and GCC both emit full debug info for naked functions in C. I've included a minimal reproducer of the debug info not being present with rustc, as well as reproducers of it being present with Clang and GCC.
Rust reproducer:
// naked_debug.rs
#[no_mangle]
#[unsafe(naked)]
pub extern "C" fn naked_func() {
std::arch::naked_asm!("ret")
}
#[no_mangle]
pub fn normal_func() {}
fn main() {
println!("{:#x?}", normal_func as *const ());
println!("{:#x?}", naked_func as *const ());
}
We see normal_func in the same translation unit gets a DW_TAG_subprogram with name, file, and line, but not with naked_func:
$ rustc -g --target x86_64-unknown-linux-gnu --emit obj naked_debug.rs -o naked_debug.o
$ llvm-dwarfdump --name=normal_func naked_debug.o
naked_debug.o: file format elf64-x86-64
0x0000039f: DW_TAG_subprogram
DW_AT_low_pc (0x0000000000000000)
DW_AT_high_pc (0x0000000000000001)
DW_AT_frame_base (DW_OP_reg7 RSP)
DW_AT_name ("normal_func")
DW_AT_decl_file ("/home/joshuaseaton/temp/naked_debug.rs")
DW_AT_decl_line (10)
DW_AT_external (true)
$ llvm-dwarfdump --name=naked_func naked_debug.o
naked_debug.o: file format elf64-x86-64
Clang and GCC reproducer:
// naked_debug.c
__attribute__((naked)) void naked_func(void) { __asm__ volatile("ret"); }
void normal_func(void) {}
$ clang -g --target=x86_64-unknown-linux-gnu -c naked_debug.c -o naked_debug.clang.o
$ llvm-dwarfdump --name=normal_func naked_debug.clang.o
naked_debug.c.o: file format elf64-x86-64
0x0000002e: DW_TAG_subprogram
DW_AT_low_pc (0x0000000000000010)
DW_AT_high_pc (0x0000000000000016)
DW_AT_frame_base (DW_OP_reg6 RBP)
DW_AT_name ("normal_func")
DW_AT_decl_file ("/home/joshuaseaton/temp/naked_debug.c")
DW_AT_decl_line (3)
DW_AT_prototyped (true)
DW_AT_external (true)
$ llvm-dwarfdump --name=naked_func naked_debug.clang.o
naked_debug.c.o: file format elf64-x86-64
0x00000023: DW_TAG_subprogram
DW_AT_low_pc (0x0000000000000000)
DW_AT_high_pc (0x0000000000000001)
DW_AT_frame_base (DW_OP_reg7 RSP)
DW_AT_name ("naked_func")
DW_AT_decl_file ("/home/joshuaseaton/temp/naked_debug.c")
DW_AT_decl_line (1)
DW_AT_prototyped (true)
DW_AT_external (true)
$ x86_64-linux-gnu-gcc -g -c naked_debug.c -o naked_debug.gcc.o
$ llvm-dwarfdump --name=normal_func naked_debug.gcc.o
naked_debug.gcc.o: file format elf64-x86-64
0x00000033: DW_TAG_subprogram
DW_AT_external (true)
DW_AT_name ("normal_func")
DW_AT_decl_file ("/home/joshuaseaton/temp/naked_debug.c")
DW_AT_decl_line (3)
DW_AT_decl_column (6)
DW_AT_prototyped (true)
DW_AT_low_pc (0x0000000000000004)
DW_AT_high_pc (0x000000000000000b)
DW_AT_frame_base (DW_OP_call_frame_cfa)
DW_AT_call_all_calls (true)
$ llvm-dwarfdump --name=naked_func naked_debug.gcc.o
naked_debug.gcc.o: file format elf64-x86-64
0x0000004c: DW_TAG_subprogram
DW_AT_external (true)
DW_AT_name ("naked_func")
DW_AT_decl_file ("/home/joshuaseaton/temp/naked_debug.c")
DW_AT_decl_line (1)
DW_AT_decl_column (29)
DW_AT_prototyped (true)
DW_AT_low_pc (0x0000000000000000)
DW_AT_high_pc (0x0000000000000004)
DW_AT_frame_base (DW_OP_call_frame_cfa)
DW_AT_call_all_calls (true)
Meta
$ rustc --version --verbose
rustc 1.93.0 (254b59607 2026-01-19)
binary: rustc
commit-hash: 254b59607d4417e9dffbc307138ae5c86280fe4c
commit-date: 2026-01-19
host: x86_64-unknown-linux-gnu
release: 1.93.0
LLVM version: 21.1.8
I have also reproduced this with the 01.01.2026 nightly aarch64-apple-darwin toolchain targeting riscv32 and riscv64.
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 Rust reproducer in the issue and inspect the compiler's debug-info emission for #[naked] functions, comparing rustc output with the shown Clang and GCC DWARF dumps. Use rustc -g --emit obj and llvm-dwarfdump to verify that naked_func receives a DW_TAG_subprogram with its name, file, line, and address range.
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
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100