I'm having the following problem: in my backtrace dump (from backtrace-rs crate), certain frames that I expect to be present are not. Is it possible that opt-level 3 is optimizing certain functions away ?
What if you set
[profile.release] debug = 2 in your
Why profile.release? I'm currently trying:
[profile.dev] lto = false opt-level = 2 [profile.test] lto = false opt-level = 2 [profile.dev.overrides."*"] lto = false opt-level = 2
(btw, on opt-level = 3, even the CodeLLDB debugger doesn't get the stack frame either, which makes me suspect it being inlined / optimized away.)
(ps2: opt-level = 3 + #[inline(never)] ==> stackframe still missing)
opt-level = 2 ==> missing some stackframe
opt-level = 0 ==> all stackframes
trying opt-level = 1 next
Ah, never mind if you're not building with
cargo test --package ....
test profile already has
debug = 2
opt-level = 3, 2, 1 => missing some stackframe
opt-level = 0 => all stackframes
This is annoying, as I'm writing numerical code, and I want some optimization ; but I'm also doing tdd, so I want all my stackframes.
Your tests rely on knowing stackframes?
[profile.dev] lto = false opt-level = 2 debuginfo=2 debug-assertions=true force-frame-pointers = true force-unwind-tables = true [profile.test] lto = false opt-level = 2 debuginfo=2 debug-assertions=true force-frame-pointers = true force-unwind-tables = true [profile.dev.overrides."*"] lto = false opt-level = 2 debuginfo=2 debug-assertions=true force-frame-pointers = true force-unwind-tables = true
@Mark Drobnak : My code has lots of "todo!()"'s -- when a unit test fails, I'd like to be able to see the entire callstack. Currently some of the frames are being optimized away when opt-level > 0.
Can't you just set
opt-level = 0 for tests and leave everything else alone?
There alot of code that operates on tensors of f32's. The tests run really really slow at opt-level = 0.
Unless there's a flag to avoid inlining, that sounds like your only option.
I've already tried #[inline(never)] and #[no_mangle].
Optimizations generally reduce the quality of stack traces
I'm going to throw in the towel now. This was an interesting excuse to study rustc compiler flags. Thanks to everyone for patience / ideas / suggestions.
Could the missing stack frames have tail calls? (a call just before returning from a function without any destructors running afterwards) In that case LLVM likely replaced the call with a jump, which means that there is no way to recover the original call frame.
JIC, you can do
todo!("thing 1") instead of just
todo!(). That text is printed out when triggered
@bjorn3 : I have no idea how you guessed this -- but it often is of the form:
panic!() todo!() return Err(...)
and the last statement/expr in a function (if not directly, then the last in that particular match branch)[
@zeroexcuses Rust used to hide all libstd internal stack frames at the end of the backtrace. This unfortunately broke because LLVM decided to tail call from the function that indicated the start of the libstd internal stack frames (
__rust_begin_short_backtrace) to the function it called. This meant that
__rust_begin_short_backtrace wouldn't be part of the backtrace anymore. I remembered this problem, and thought that your problem may have been similar.