I was reading the issue Better runtime panic message for RefCell borrow and noticed "this is probably just missing a few
#[track_caller]". But then I thought, sometimes it is probably useful to have the full backtrace, although the default should be short ones.
My first idea was to have a
RUST_BACKTRACE=short, but while digging around before posting this I found the issue Rust never lets you know about RUST_BACKTRACE=full which led me to this parsing part of it in the code and I saw that the "short" option is already present. The book does not mention
full backtraces unless I missed it, and maybe it could be useful if it taught about full backtraces too.
The main question is then, does
RUST_BACKTRACE=1 honours it? If that's the case, great, there's nothing new on my original idea as things work as intended (but could be documented to avoid questions like these).
If it doesn't though (all of them honour
#[track_caller]), then I guess my proposed idea boils down to
RUST_BACKTRACE=full to ignore
#[track_caller] because we already have a short one, which is the one honouring
#[track_caller] has no effect at all on backtraces.
Thanks for the answer, in that case "full" is not truly full. But I don't know how worth or easy looking into my idea would be.
I think this would be hard to do in general, since backtraces use debuginfo, while
#[track_caller] is more of a "Rust ABI" thing (i.e. it lowers to an extra function argument).
Although we've moved to parsing DWARF ourselves just recently, so maybe we could flag some functions as
#[track_caller] in the DWARF debuginfo (not sure LLVM allows us to do that though).
Also, presumably that wouldn't work for non-DWARF platforms (i.e. MSVC Windows targets).
cc @bjorn3 @anp
Yes instead of omitting they would need to be flagged in some special way, although as you say different platforms may make this complicated. I guess adding this information within the mangled is a no-go (would be weird and not work for
#[no_mangle], not the right place for the information, etc.).
None::<()>.unwrap() give as short backtrace? It currently gives:
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
I think the backtrace should start at frame 14 in this case. However how would this be handled when a
#[track_caller] function calls a non-
#[track_caller] function? To get the backtrace to start at frame 14, it would have to skip all non-
#[track_caller] functions before the last
#[track_caller] function. However what if a
#[track_caller] function calls a closure provided by the caller. It probably shouldn't trim that part of the backtrace.
I think it would make sense to annotate functions in the debug info if they’re tracked. If I’m honest, I’d love for
Location to be linked with debug symbols somehow to allow for stripping them from binaries without losing the ability to reconstruct the message from debug symbols.
That said, I don’t think that’s possible with LLVM today but I could be wrong.
My understanding is that, on short backtraces, any function annotated
#[track_caller] would not show at all (and instead the next parent non-annotated function would show in its place). However, I don't actually know much about how
#[track_caller] works precisely, or what should happen when one encounters normal-tracked-normal-tracked.
I think of
#[track_caller] functions as "inlined" that never even exist or show up anywhere even if underneath there is a call.
unwrap I would expect the
unwrap to be part of the backtrace, as that is the action that the caller performed causing the panic. For the panic location, it makes sense to show the call site. However for backtraces, excluding the
unwrap would make the backtrace much less useful when debuginfo is disabled, as you can't see the call site, only the function that contained the call site.
I think I was misunderstanding what
#[track_caller] does. I was understanding it as a way of "ignore my current location and pretend I'm the caller instead", but re-reading the RFC on it made it obvious that all it does is "guarantees a function has access to the caller information".
So I guess what I meant is an attribute that says "ignore me on backtraces", sorry for the confusion. After understanding it, yeah it doesn't make much sense to exclude track caller's from backtraces but rather an attribute to be able to shorten them.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.