shorten backtraces when called as a cdylib, not just for executables
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
currently, backtraces for rust cdylibs called from a C main function look like this:
thread '<unnamed>' panicked at lib.rs:5:34:
oops
stack backtrace:
0: std::panicking::begin_panic
1: lib::foo::{{closure}}
2: std::panicking::try::do_call
3: __rust_try
4: std::panic::catch_unwind
5: foo
6: main
7: __libc_start_call_main
at ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
8: __libc_start_main_impl
at ./csu/../csu/libc-start.c:392:3
9: _start
(the catch_unwind -> do_call stack should be included, i had a manual catch_unwind in my program.)
this does ok for frames after main, but it shows three irrelevant frames before main. that happens because rustc doesn't control the final link, so it can't generate a __rust_start_short_backtrace frame. it would be nice if we could omit those.
to avoid making this dependent on the libc in use, i think we should:
- determine whether
mainwas generated by rustc. we have a reliable signal for this at runtime, which is "isstd::rt::lang_startpresent anywhere in the backtrace". - if not, treat
mainthe same as__rust_start_short_backtrace, except we also print themainframe in addition to toggling the state machine.
code that replicates this backtrace
; cat lib.rs main.c Makefile
File: lib.rs
use std::ffi::c_int;
use std::panic::catch_unwind;
#[no_mangle]
pub extern "C" fn foo() -> c_int {
let _panic = catch_unwind(|| panic!("oops")).unwrap_err();
1
}
────────────────────────────────────────────────────────
File: main.c
#include <stdio.h>
int foo();
int main() {
printf("%d\n", foo());
}
────────────────────────────────────────────────────────
File: Makefile
.PHONY: run
run: main
LD_LIBRARY_PATH=. RUST_BACKTRACE=1 ./main
main: main.o librust.so
gcc main.o -L. -lrust -o main
librust.so: lib.rs
rustc --crate-type cdylib lib.rs -o librust.so
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 std::rt::lang_start and __rust_start_short_backtrace to understand how Rust-generated executables shorten backtraces. Reproduce the cdylib case using lib.rs, main.c, and Makefile, then trace the backtrace state handling. Done means C-hosted cdylib panics omit the irrelevant frames while retaining main and manually caught frames.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- developer-experience
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100