-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Break into the debugger (if attached) on panics (Windows, Linux, macOS, FreeBSD) #129019
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @workingjubilee (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
r? @wesleywiser |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@kromych Please do not both add public API to the standard library and change the internal behavior of unrelated code in the same PR. |
This is a library change, not a compiler one. |
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.
I strongly recommend you run check builds locally.
Thanks for your help! Should I open two PR instead (adding the |
Why did you ask for wesleywiser's review? |
The change relies on SEH which is handled normally by the compiler, thought there might be some assumption about setting the stack frame up for SEH. This is my first attempt at contribution to the Rust repo, haven't known about the proper process, learning as I go. |
Hm, yes, but why specifically Wesley, the compiler lead that has the least time to review things? In any case, you're probably thinking of code generation of destructors. Those shouldn't be relevant to your PR because that code was already written a long time ago. Most of the SEH code is in the library, here: rust/library/panic_unwind/src/seh.rs Line 4 in 91376f4
I recommend you just remove the parts that expose this to public API from this PR, as exposing new API is its own process, and code review for this will be exciting enough. |
Wesley's also on the wg-debugging group: https://blog.rust-lang.org/inside-rust/2022/02/22/compiler-team-ambitions-2022.html#debugging-initiatives-. That looked to me as an opportunity to bring attention to the value of that PR for the debugging experience besides examining the sanity from the compiler perspective.
Appreciated, will do! |
Ran that command locally, thanks! There was one issue that I could not explain: if something is used inside the panic handler only, that something is considered a dead code. |
Ah, that makes more sense. I don't mean to be so nosy but I would like to see this functionality land and thus want to make sure it happens in the way that is smoothest. Generally T-compiler members don't approve library PRs and vice versa. Thus often a PR that tries to do both compiler changes and internal stdlib changes and expose new library API is doomed because of this split responsibility. We aren't unthinking servants of process but it's best not to fudge anything when it's unnecessary and we can simply pipeline things. More briefly: let's build the bikeshed before we have an argument over how to paint it. For more information on process in general, you may wish to consult the rustc dev guide and the std dev guide. You will want to consult the former anyways as it explains how to add new tests and you may need a fairly specialized test to make sure "break into debugger" works, as I don't think either the normal UI test suite or debuginfo test suite support that. Our library tests only work for code that doesn't need to do weird stuff with a process. If we do need special frame-by-frame code generation for this, it should probably not be implemented as including And those are in core, not std. But I don't know that we do. The Rust compiler already has the necessary infrastructure to handle SEH, because that is how unwinding on Windows works. That is, the following C, calling these two functions: void try_code(void);
void except_code(void);
__declspec(noinline) int try_break_into_debugger()
{
__try
{
try_code();
return 0;
}
__except (1)
{
except_code();
return 1;
}
return 0;
} should be functionally identical to: use other_crate::{try_code, except_code};
if let Err(_) = catch_unwind(|| try_code()) {
except_code();
}; Intrinsics themselves are actually language features and so require rubberstamps from a different group. Isn't process fun? |
This comment has been minimized.
This comment has been minimized.
Something broke down again in the CI, will try to replicate locally |
...? huh, approving it twice feels weird, I'm gonna... @bors r- |
@bors r+ |
☀️ Test successful - checks-actions |
Finished benchmarking commit (7b18b3e): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results (secondary 2.3%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeResults (primary 0.1%, secondary 0.3%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Bootstrap: 756.659s -> 754.738s (-0.25%) |
Tested in the simulator and on the device I had lying around, a 1st generation iPad Mini (which isn't Aarch64, but shows that the `sysctlbyname` calls still work even there, even if they return false). `sysctlbyname` _should_ be safe to use without causing rejections from the app store, as its usage is documented in: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics Also, the standard library will use these soon anyhow, so this shouldn't affect the situation: rust-lang/rust#129019
Tested in the simulator and on the device I had lying around, a 1st generation iPad Mini (which isn't Aarch64, but shows that the `sysctlbyname` calls still work even there, even if they return false). `sysctlbyname` _should_ be safe to use without causing rejections from the app store, as its usage is documented in: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics Also, the standard library will use these soon anyhow, so this shouldn't affect the situation: rust-lang/rust#129019
My apologies if this was debated in the 166 comments I didn't read, but I don't think the quality of implementation here is suitable for shipping on Linux, even in nightly. This behavior is triggered even if the panic is ultimately handled via catch_unwind, and on Linux it triggers for any ptracer, even things that aren't interactive debuggers (e.g. strace). The net result is that Rust programs that use panics at all no longer function under tools like strace or rr after this change. I think this should be reverted. |
In my view, your arguments are enough to revert this for Linux, especially if no one finds that useful at all there. If the latter cannot be known for sure, perhaps wrap the logic in if let Some(bp) = env::get("RUST_BREAKPOINT_ON_PANIC") {
if bp == "1" {
let _ = breakpoint_if_debugging()
}
} i.e. one would need to set an env. variable |
This change makes a ptraced/straced program exit with SIG_TRAP when the program panics, and the core dump is generated. Assuming that panicking implies there is no way of continuing computation, that behaviour doesn't look as a deal breaker to me. That assumption of panic being a catastrophic failure (hence meaning the program exits) is broken by std::panic::catch_unwind(|| /* something that panics */); so that the program does not exit upon panicking although it - quite weirdly - does print the panic message when using I cannot comment if |
@khuey Yeah, I noticed that (after it was merged, and from people discussing this elsewhere) and wondered if that would be a practical issue since the program would often die anyways? But if it's causing problems in rr, I think we should remove the Linux impl. |
This breaks `rr`, see rust-lang#129019 (comment) for the discussion CC @khuey @workingjubilee
Here is the PR #130810 |
Don't trap into the debugger on panics under Linux This breaks `rr`, see rust-lang#129019 (comment) for the discussion CC `@khuey` `@workingjubilee`
Rollup merge of rust-lang#130810 - kromych:master, r=workingjubilee Don't trap into the debugger on panics under Linux This breaks `rr`, see rust-lang#129019 (comment) for the discussion CC `@khuey` `@workingjubilee`
As this is being reverted in #130846, for the folks, who liked this, I've published https://crates.io/crates/dbg_breakpoint:
|
The developer experience for panics is to provide the backtrace and
exit the program. When running under debugger, that might be improved
by breaking into the debugger once the code panics thus enabling
the developer to examine the program state at the exact time when
the code panicked.
Let the developer catch the panic in the debugger if it is attached.
If the debugger is not attached, nothing changes. Providing this feature
inside the standard library facilitates better debugging experience.
Validated under Windows, Linux, macOS 14.6, and FreeBSD 13.3..14.1.