Skip to content

Tracking issue for recover stabilization #27719

Closed

Description

@aturon

The recover function is able, on a single thread, to recover from a panic. There are numerous controversies around this API, including the bounds it applies to its closure, its safety, and its location within std. An open RFC seeks to settle these issues and open the door to stabilization.

cc @alexcrichton

Activity

  1. added
    T-libs-api[DEPRECATED; DO NOT USE]
    B-unstableBlocker: Implemented in the nightly compiler and unstable.
    on Aug 12, 2015
  2. SimonSapin commented on Sep 16, 2015

    @SimonSapin
    Contributor

    I’m playing with making Python bindings for a Rust library, and I got some segfaults when a Rust panic tried to unwind into the Python interpreter’s call stack. I understand that using catch_panic at the FFI boundary is the right thing to do, but what should I do with an Err result? I can establish conventions so that the other side triggers a Python exception, but I’d like to have some more helpful information in it than "Something bad happened somewhere". At least (a string representation of) the message that was given to panic!, ideally also a back trace of the unwinded stack frames.

    catch_panic returns Result<T, Box<Any + Send + 'static>>, but Any is not very helpful here. It implements Debug, but that impl only prints "Any" (literally), which isn’t that helpful.

    @wycats, how do you deal with panics in Rust-inside-Ruby?

  3. abonander commented on Oct 3, 2015

    @abonander
    Contributor

    @SimonSapin Looking at the guts of unwinding, Box<Any + Send + 'static> is always going to either be String (if panic!() had formatting arguments) or &'static str (if panic!() was invoked with just a string literal), so you basically downcast it to one, and if that fails you can probably assume it's the other.

    I agree, though, the type could be a lot more informative here.

  4. SimonSapin commented on Oct 3, 2015

    @SimonSapin
    Contributor

    Yeah, I ended up finding this code: https://github.com/rust-lang/rust/blob/d2047bc97d/src/libstd/panicking.rs#L33-L39 , but it’s not very discoverable. And though String and &'static str are the most common cases, panic!() with a single argument can take any type:

    SimonSapin: panic!(4)
    playbot: thread '<main>' panicked at 'Box<Any>', <anon>:9
    playbot: playpen: application terminated with error code 101
    

    So I wanted to propose changing from this (in std::thread):

    type Result<T> = Result<T, Box<Any + Send + 'static>>;

    to this:

    type Result<T> = Result<T, PanicValue>;
    struct PanicValue(Box<Any + Send + 'static>);
    impl PanicValue {
        fn as_str(&self) -> Option<&str> {
            match self.0.downcast_ref::<&'static str>() {
                Some(s) => Some(*s),
                None => match self.0.downcast_ref::<String>() {
                    Some(s) => Some(&s[..]),
                    None => None,
                }
            }
        }
    }

    … but std::thread::Result is already stable :(

  5. SimonSapin commented on Oct 3, 2015

    @SimonSapin
    Contributor

    Would this as_str belong as a default method on the Any trait?

  6. abonander commented on Oct 3, 2015

    @abonander
    Contributor

    Why not have impl Debug for Any (+ Send) test for the value being String or &'static str before printing "Any"? It would add negligible overhead, and I don't think anyone should be relying on the exact value it prints. Right now, it's pretty much useless anyways.

    In fact, why not cover all the primitives (except obviously &[T], *const T, *mut T, etc)?

  7. alexchandel commented on Dec 2, 2015

    @alexchandel

    Why are we making it easier to use and abuse panics, instead of removing inappropriate ones from the standard library?

  8. 106 remaining items

  9. BurntSushi commented on Apr 6, 2016

    @BurntSushi
    Member

    I think I'm happy as long as unwind is in the name.

  10. pnkfelix commented on Apr 6, 2016

    @pnkfelix
    Contributor

    I thought the barrier suggestion from @cybergeek94 was good. Especially if we put it into an unwind submodule, yielding unwind::barrier

    To me barrier carries the notion that the unwinding will stop here, but there's the hint that you should perhaps trying to "restart it", to keep it going across the boundary introduced by the barrier, if possible, or at least signal that it occurred.


    Update: unwind::guard seems okay too, but for some reason I prefer unwind::barrier; not sure why.

  11. e-oz commented on Apr 6, 2016

    @e-oz

    My vote against "barrier", sounds too non-related to execution flow.

    On Wed, 6 Apr 2016 at 22:32, Felix S Klock II [email protected]
    wrote:

    I thought the barrier suggestion from @cybergeek94
    https://github.com/cybergeek94 was good. Especially if we put it into
    an unwind submodule, yielding unwind::barrier

    To me barrier carries the notion that the unwinding will stop here, but
    there's the hint that you should perhaps trying to "restart it", to keep it
    going across the boundary introduced by the barrier, if possible, or at
    least signal that it occurred.

    —
    You are receiving this because you were mentioned.

    Reply to this email directly or view it on GitHub
    #27719 (comment)

  12. tomaka commented on Apr 6, 2016

    @tomaka
    Contributor

    In system programming, barrier usually means "memory barrier", which has nothing to do with unwinding.

  13. alexcrichton commented on Apr 7, 2016

    @alexcrichton
    Member

    The libs team discussed this during triage yesterday and the decision was to stabilize with the following names:

    • recover -> catch_unwind
    • propagate -> resume_unwind
    • AssertRecoverSafe -> AssertUnwindSafe

    Thanks again for all the discussion everyone!

  14. strega-nil commented on Apr 7, 2016

    @strega-nil
    Contributor

    yay :)

  15. added a commit that references this issue on Apr 11, 2016
    552eda7
  16. added a commit that references this issue on Apr 12, 2016
    bed32d8
  17. added a commit that references this issue on Apr 12, 2016
    1f8f3d7
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-api[DEPRECATED; DO NOT USE]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

      Issue actions