Backtraces/stacktraces with line numbers, without leaking source code

I'm working on proprietary software, so don't want to leak source code. It's a shared library (a .so) so I don't want to have a crash reporting tool built-in, that's too intrusive given it's running in someone else's application.

But, I do want Rust backtraces (and stacktraces from gdb) to have line numbers, so I can debug bug reports more easily.

There's the debug option in Cargo.toml's profile. If I set it to 0, I get function names but not line numbers:

stack backtrace:
   0: rust_begin_unwind
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/core/src/panicking.rs:116:14
   2: stacktraces_in_rust::panics
   3: stacktraces_in_rust::main

If I do debug = 1, I get line numbers:

stack backtrace:
   0: rust_begin_unwind
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/core/src/panicking.rs:116:14
   2: stacktraces_in_rust::panics
             at ./src/main.rs:13:5
   3: stacktraces_in_rust::main
             at ./src/main.rs:5:9
   4: core::ops::function::FnOnce::call_once
             at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/core/src/ops/function.rs:227:5

The problem is that with debug = 1 my proprietary source code is embedded in the resulting file, which I don't want.

So how can I do this? First thought was debug = 1 and stripping out source code, but so far I've failed to figure out how to strip source code while still allowing informative backtraces.

Source code is never embedded in the generated binaries, AFAIK, only symbols and filenames. Have you observed otherwise?

Been testing this with a simple binary, just to get faster testing, and for example:

$ objdump -S target/release/stacktraces-in-rust | grep if | head
    if std::env::var("BLAH") == Ok("foo".to_string()) {

This is with debug = 1.

This is an artifact of objdump, which reads source files referenced by the binary. If you run strings target/release/stacktraces-in-rust, you'll find no trace of the source code. (Alternatively, remove the source file and run objdump -S again.)

3 Likes

objdump here is reading paths to source code location, from debuginfo, if the sources exist on the filesystem it then reads them. You should also try moving your sources elsewhere where objdump can't find them, then rerun that.
debug is definitely leaking a lot more information than non-debug though.

2 Likes

Ah, just tested, and yeah, it's reading it locally.

I'm not super-worried about leaking information beyond source code, at the moment at least, so I guess debug=1 it is.