-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement printing of stack traces on LLVM segfaults and aborts #80182
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @matthewjasper (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
r? @tmandry Just saw this. I'll give it a full review next week. Thanks! |
@in42 It looks like you'll want a |
This is a very basic implementation, the stack trace printed is barely readable, I will improve it this weekend. |
That's why I was thinking we might want to use LLVM's hooks when using it as a backend; we already get all the nice stuff "for free." Not sure if it's actually feasible and reachable through a public API, though I remember thinking it was. |
Yeah basically there is no point in re implementing all of the functionality in rust - will look into how the llvm functions can be used. |
You can also use |
This comment has been minimized.
This comment has been minimized.
Ok will look into this |
I tried to use it in the following way:
and run the compiler like this:
but no backtrace is getting printed. |
Using
|
Hm, maybe if we get something like #77384 merged we could use that. |
Yeah, that will be better, I won’t have to implement the backtrace myself. 😃 |
Talking with @yaahc gave me another idea: call the panic hook! The default panic hook prints a backtrace without allocating. If we call that we'll get a backtrace, and then we can abort. The compiler does install another panic hook, but saves a handle to the default hook here. So we can call it directly from librustc_driver. Worth a shot, I think.. |
ok will try this |
@in42 following up here, have you had a chance to try the panic hook approach? |
Sorry was a little busy these last few weeks, will try this weekend. |
Hi, I had a doubt, will the |
On the other hand, I found out I just need to port this function to rust and I will able to print backtrace with function names based on the approach I was following earlier. It uses the llvm-symbolizer binary to symbolize the backtrace. I am not sure whether it will be available for rustc though. Or I can try to directly call the llvm library function from rust code. The relevant code is present here. |
compiler/rustc_driver/src/lib.rs
Outdated
fn print_stack_trace(_: libc::c_int) { | ||
unsafe { | ||
static mut STACK_TRACE: [*mut libc::c_void; 256] = [std::ptr::null_mut(); 256]; | ||
let _depth = libc::backtrace(STACK_TRACE.as_mut_ptr(), 256); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Libc's backtrace
function does a naive walk of frame pointers. Rustc and LLVM are normally compiled with frame pointers omitted, meaning that only DWARF based unwinding is reliable.
https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
[...] frame pointer elimination will stop
backtrace
from interpreting the stack contents correctly.
In addition it is not safe to call it from asynchronous signals like SIGSEGV.
[...] AS-Unsafe init heap dlopen plugin lock [...]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I noticed inside the llvm code, using the backtrace c api was one of the ways they were generating the backtrace. I will try to add the other ways too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, forgot about that. It's a bit hacky, but it seems like the most straightforward way to follow this approach would be, roughly:
We can exit the process afterward so don't have to worry about cleaning up. |
This comment has been minimized.
This comment has been minimized.
Ok as far as I have understood the panic hook approach, the other panic hook the compiler installs calls the default hook here, so I do not reinstall it. I can actually just panic, and the default hook will be called. So I tried that using this code:
and ran the compiler like this:
However, as you can see, the backtrace is not getting printed. |
I took the liberty of squashing the intermediate commits and adding a few small fixes. With that I think this PR is ready to land. @bors r+ |
@bors r+ |
@bors r+ |
📌 Commit ec6a85a has been approved by |
Implement printing of stack traces on LLVM segfaults and aborts Implement rust-lang#79153 Based on discussion, try to extend the rust_backtrace=1 feature to handle segfault or aborts in the llvm backend
⌛ Testing commit ec6a85a with merge 12a28971e51436adf4d00c42bc7ddae1017f99e9... |
This comment has been minimized.
This comment has been minimized.
💔 Test failed - checks-actions |
This comment has been minimized.
This comment has been minimized.
@bors r+ rollup=iffy |
📌 Commit 162ed4d has been approved by |
☀️ Test successful - checks-actions |
Implement #79153
Based on discussion, try to extend the rust_backtrace=1 feature to handle segfault or aborts in the llvm backend