Ignore panic functions in backtraces. Print inlined functions on Windows#45637
Ignore panic functions in backtraces. Print inlined functions on Windows#45637Zoxc wants to merge 4 commits intorust-lang:masterfrom
Conversation
|
SGTM! |
src/libsyntax/ext/tt/macro_parser.rs
Outdated
There was a problem hiding this comment.
All the previous matchers went through RFC process.
Well, at least I'm pretty sure this addition should not be hidden in a PR named "Ignore panic functions in backtraces".
2507e67 to
d046344
Compare
|
I removed the This does not seem to work on OS X, probably because the backtraces are incorrect there. |
|
I changed how the implemented worked. Now panic functions passes a pointer to themselves into the panic handler. Backtraces then ignore functions in the backtrace before that pointer. Any functions after |
src/libcore/panicking.rs
Outdated
There was a problem hiding this comment.
How come this is passed as &usize? Can't this just be a usize?
There was a problem hiding this comment.
I think passing locals by reference also prevents tail call optimization. I'm not really sure that this or the asm! trick works for function which never return. Currently these do not get tail call optimization applied, but I don't see a reason for that. Perhaps LLVM skips that optimization on cold functions?
There was a problem hiding this comment.
I'm a little wary to have this and rely on this, are we sure that this doesn't get optimized away even with LTO? If we leave this in can it at least be documented in the source as to why it's a reference?
There was a problem hiding this comment.
My guess for why this isn't optimized is because fmt::Arguments is a pretty big struct that's copied around the stack, and LLVM is probably conservative with the tail-call for now. Despite that though this seems like something that's pretty brittle to rely on?
src/libstd/panicking.rs
Outdated
There was a problem hiding this comment.
How come pub(crate) is needed here?
There was a problem hiding this comment.
Probably just a leftover from the earlier version.
src/libstd/sys_common/backtrace.rs
Outdated
There was a problem hiding this comment.
Does #[inline(never)] not work for inhibiting inlining and providing this as a marker?
There was a problem hiding this comment.
It does not. It just prevents inlining, not the removal of stack frames.
There was a problem hiding this comment.
Instead of asm!, does std::sync::atomic::compiler_fence() work?
src/libstd/sys_common/backtrace.rs
Outdated
There was a problem hiding this comment.
Couldn't this just store fn(...) instead of using casts and unsafe impls?
There was a problem hiding this comment.
I think so. An earlier version had an array of functions, which needed casts.
src/libtest/lib.rs
Outdated
There was a problem hiding this comment.
This presumably no longer works now that the libstd implementation was updated?
There was a problem hiding this comment.
Yeah this is now broken. We could work around it by exporting mark_start as an unstable item.
|
☔ The latest upstream changes (presumably #45725) made this pull request unmergeable. Please resolve the merge conflicts. |
15bff34 to
915b654
Compare
|
Now this also prints inlined functions in backtraces on Windows. @alexcrichton I'd like this to get merged in time for the next beta so I can get more complete backtraces in rustc. cc @retep998 |
d63555a to
03e28c9
Compare
src/libcore/panicking.rs
Outdated
|
Ping @alexcrichton (also @retep998) is there any unresolved questions for this PR? |
|
Triage ping @alexcrichton! There are some responses from @Zoxc on #45637 (review) and #45637 (comment) cc @rust-lang/libs |
src/libtest/lib.rs
Outdated
There was a problem hiding this comment.
Does this need to be either #[inline] or #[inline(always)]? If so, can it be documented as to why?
There was a problem hiding this comment.
I don't think the attribute is needed here.
|
Nice on the windows bits! Could those perhaps be moved to a separate PR? They seem unambiguously good to me while I'm still pretty uneasy on the other parts. It seems like relying on the exact addresses of functions is quite brittle? I'm worried that this will cause regressions over time as we continue to upgrade LLVM. Is there perhaps something we can do to make this more bullet-proof rather than "insert something and pray llvm doesn't optimize it"? |
|
I don't think there's anything we can do to make it bulletproof without modifying LLVM. If it breaks, it will just return to the status quo, so I don't think that's a good reason to avoid landing this. Backtraces are unfortunately best effort due to other reasons anyway. |
|
I'm personally sort of wary for that though in that this if we go down this road it's a commitment for us to make that we will receive, review, and maintain patches to fix this functionality as it regresses over time. In that sense I'm not comfortable myself r+'ing this but would want a larger sign-off from perhaps @rust-lang/libs on this functionality. |
src/libstd/panicking.rs
Outdated
|
|
||
| #[cold] | ||
| #[inline(never)] | ||
| #[cfg_attr(not(stage0), notail_when_called)] |
There was a problem hiding this comment.
Could you add comment as well to functions in this crate for why this attribute is applied?
|
Looks good to me, thanks! A few comments and a fixup to some indentation and otherwise looks ready to go. |
src/librustc_trans/mir/block.rs
Outdated
| this.store_return(&ret_bcx, ret_dest, &fn_ty.ret, invokeret); | ||
| } | ||
|
|
||
| None |
There was a problem hiding this comment.
This should probably be invokeret.
There was a problem hiding this comment.
That would be bad, since InvokeInst is unrelated to CallInst and does not have a notail attribute.
There was a problem hiding this comment.
I don't think that has a setTailCallKind method.
There was a problem hiding this comment.
Oh, my bad, I just checked again and that is indeed that case. That's a big troubling, because an invoke can become a call through optimizations :/.
There was a problem hiding this comment.
We should probably panic if we need to add notail on invokes then. I'll do that to check that we don't emit any invokes here.
There was a problem hiding this comment.
It seems like we do emit invokes here.
There was a problem hiding this comment.
I guess the attribute should require non-Rust ABI which implies nounwind?
Err, it should always be an invoke if it's calling a panic entry-point with unwinding enabled.
There was a problem hiding this comment.
Isn't invoke only used when you need cleanup? Normal call instructions can also unwind and should be used here
| // except according to those terms. | ||
|
|
||
| #[notail_when_called] | ||
| fn main() {} No newline at end of file |
There was a problem hiding this comment.
Missing newline at the end of file.
src/rustllvm/RustWrapper.cpp
Outdated
| } | ||
|
|
||
| extern "C" void LLVMRustSetCallNoTail(LLVMValueRef Call) { | ||
| dyn_cast<CallInst>(unwrap(Call))->setTailCallKind(CallInst::TCK_NoTail); |
There was a problem hiding this comment.
Okay, then I'd make this if (auto CI = dyn_cast<CallInst>(unwrap(Call))) CI->... just so you can pass an invoke instruction.
|
☔ The latest upstream changes (presumably #46436) made this pull request unmergeable. Please resolve the merge conflicts. |
|
@alexcrichton It turns out |
|
☔ The latest upstream changes (presumably #46914) made this pull request unmergeable. Please resolve the merge conflicts. |
|
@Zoxc that's unfortunate :( Would it be possible to land the fixes for inlined functions on Windows and perhaps follow-up with an upstream bug with LLVM to add this feature? |
|
Hi @Zoxc, is this PR currently blocked by #47252, and is there a workaround for |
|
There isn't any workaround nor have I filed a LLVM issue. I should still split out the fixes to mark the start of backtraces though, which addresses #47429. |
Print inlined functions on Windows Split from #45637 r? @alexcrichton
Print inlined functions on Windows Split from #45637 r? @alexcrichton
|
Ping from triage, @Zoxc ! Have you "split out the fixes to mark the start of backtraces"? If so, should this PR be closed? |
For the following program,
we now get this stack trace:
instead of this one:
This introduces a
strmacro fragment used to redirectpanic!called with string literals to a non-generic function. This redirection is also an optimization (and matches what libcore does).