Skip to content

Custom panic handlers in the standard library #30449

Closed
@alexcrichton

Description

@alexcrichton
Member

Tracking issue for rust-lang/rfcs#1328

Activity

sfackler

sfackler commented on Jan 5, 2016

@sfackler
Member

See rust-lang/log#67 for one usage example.

yberreby

yberreby commented on Jan 12, 2016

@yberreby

Is there a good reason for the global panic handler to run even if the panic is recovered from?

#![feature(std_panic, recover)]
use std::panic;

fn main() {
    panic::recover(|| {
        panic!("hello");
    }).unwrap_err();
}

http://is.gd/HP4EyO

This prints thread '<main>' panicked at 'hello', <anon>:6. It seems unexpected to me, since the panic was caught, it shouldn't trigger the global handler, should it? IMO, only uncaught panics should trigger the handler and print a message. If a message needs to be printed, it can be, explicitly, at the recover call site.

sfackler

sfackler commented on Jan 12, 2016

@sfackler
Member

There's some talk about this in the RFC PR, but the main reason is that it's very important for the handler to be able to take stack traces.

In addition, the intended use cases for recover are fairly limited, and almost all of them involve rethrowing the panic payload at a different location after catching it. The thread did panic, so it makes sense that the handler would be called IMO.

added
T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.
B-unstableBlocker: Implemented in the nightly compiler and unstable.
and removed
B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.
on Jan 12, 2016
shahn

shahn commented on Jan 14, 2016

@shahn
Contributor

My biggest usecase for this is #1089, so I'd love a way to suppress the std panic handler, too. I would like to present my users with an error message, set an appropriate exit code, and be assured that desctructors ran without wrapping basically all my return values in Results when an error happens very rarely, is dependant on certain combinations of user input that can't be checked early/not very deep in the call chain.

sfackler

sfackler commented on Jan 14, 2016

@sfackler
Member

@shahn panic::set_handler(|_| ()); should do that for you.

fables-tales

fables-tales commented on Jan 17, 2016

@fables-tales
Contributor

I'm trying to do something of the form:

let orig_handler = panic::take_handler();
panic::set_handler(|_| ());
<an actual thing>
panic::set_handler(orig_handler);

and getting the error

src/example_group.rs:41:13: 41:31 error: the trait `for<'r, 'r> core::ops::Fn<(&'r std::panicking::PanicInfo<'r>,)>` is not implemented for the type `Box<for<'r, 'r> core::ops::Fn(&'r std::panicking::PanicInfo<'r>) + Send + Sync>` [E0277]
src/example_group.rs:41             panic::set_handler(orig_panic_handler);
                                    ^~~~~~~~~~~~~~~~~~
src/example_group.rs:41:13: 41:31 help: run `rustc --explain E0277` to see a detailed explanation
src/example_group.rs:41:13: 41:31 note: required by `std::panicking::set_handler`
src/example_group.rs:41:13: 41:31 error: the trait `for<'r, 'r> core::ops::FnOnce<(&'r std::panicking::PanicInfo<'r>,)>` is not implemented for the type `Box<for<'r, 'r> core::ops::Fn(&'r std::panicking::PanicInfo<'r>) + Send + Sync>` [E0277]
src/example_group.rs:41             panic::set_handler(orig_panic_handler);
                                    ^~~~~~~~~~~~~~~~~~
src/example_group.rs:41:13: 41:31 help: run `rustc --explain E0277` to see a detailed explanation
src/example_group.rs:41:13: 41:31 help: the following implementations were found:
src/example_group.rs:41:13: 41:31 help:   <Box<alloc::boxed::FnBox<A, Output=R> + 'a> as core::ops::FnOnce<A>>
src/example_group.rs:41:13: 41:31 help:   <Box<alloc::boxed::FnBox<A, Output=R> + Send + 'a> as core::ops::FnOnce<A>>
src/example_group.rs:41:13: 41:31 note: required by `std::panicking::set_handler`
error: aborting due to 2 previous errors
Could not compile `descriptor`.

I tried taking ownership of the value inside the box with

panic::set_handler(*orig_handler);

but this gives the error

src/example_group.rs:41:13: 41:31 error: the trait `core::marker::Sized` is not implemented for the type `for<'r, 'r> core::ops::Fn(&'r std::panicking::PanicInfo<'r>) + Send + Sync` [E0277]
src/example_group.rs:41             panic::set_handler(*orig_panic_handler);
                                    ^~~~~~~~~~~~~~~~~~
src/example_group.rs:41:13: 41:31 help: run `rustc --explain E0277` to see a detailed explanation
src/example_group.rs:41:13: 41:31 note: `for<'r, 'r> core::ops::Fn(&'r std::panicking::PanicInfo<'r>) + Send + Sync` does not have a constant size known at compile-time
src/example_group.rs:41:13: 41:31 note: required by `std::panicking::set_handler`
error: aborting due to previous error
Could not compile `descriptor`.

I feel like it should be easy to set_handler the result from take_handler and I might be missing a trick here. Does anyone have any advice for me? I really like this API and I'd appreciate any help ^_^

yberreby

yberreby commented on Jan 17, 2016

@yberreby

@samphippen This is ugly, but it works.

#![feature(std_panic, panic_handler)]
use std::panic;

fn main() {
    let orig_handler = panic::take_handler();
    panic::set_handler(|_| ());
    // <an actual thing>
    panic::set_handler(move |info| (*orig_handler)(info));
}

http://is.gd/CzXxcb

fables-tales

fables-tales commented on Jan 17, 2016

@fables-tales
Contributor

thanks!

39 remaining items

added a commit that references this issue on May 24, 2016
cae91d7
added a commit that references this issue on May 26, 2016
a2141e2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    B-unstableBlocker: Implemented in the nightly compiler and unstable.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @hank@alexcrichton@fables-tales@shahn@SimonSapin

        Issue actions

          Custom panic handlers in the standard library · Issue #30449 · rust-lang/rust