Skip to content
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 RFC 1328 Custom Panic Handlers #30485

Merged
merged 1 commit into from
Dec 25, 2015
Merged

Conversation

sfackler
Copy link
Member

@sfackler
Copy link
Member Author

I'm unfortunately not sure how to test the panic when modifying the handler during a panic behavior because compiletest is unhappy with a SIGABRT.

@sfackler sfackler changed the title Panic handler Implement RFC 1328 Custom Panic Handlers Dec 19, 2015
@sfackler
Copy link
Member Author

cc #30449

@alexcrichton
Copy link
Member

Looks like there may be a legit travis failure

@@ -21,6 +21,8 @@ use sync::{Arc, Mutex, RwLock};
use sys_common::unwind;
use thread::Result;

pub use panicking::{take_handler, set_handler, PanicInfo, Location};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to define these in this module? They seems closely related to it at least.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to, but the panicking module needs access to all of the internals and the privacy doesn't work in a reasonable way. They could be moved in a world with rust-lang/rfcs#1422.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, that's fine for now

@alexcrichton
Copy link
Member

Could you also add some tests for cases like:

  • Lots of concurrency mixed in, e.g. threads panicking, setting a panic handler, and taking a panic handler all in a mixed bag
  • Calling a previous panic handler via take then set
  • Setting a panic handler twice to ensure it overrides
  • Set a panic handler and then panic in another thread to ensure it was called there
  • Setting a panic handler in a panic handler (or taking a panic handler)

Some of these may be best as a run-pass instead of run-fail as well, and some may also require the "age-old trick" of exec-self-again and then looking at the return status of that.

}

/// Returns information about the location from which the panic originated,
/// if available.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this explain a bit more that although Some is always returned today it's not guaranteed to always be available?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@sfackler
Copy link
Member Author

Something seems to be bogus with fat pointer comparisons. Does it not compare each component? This lldb output seems to imply that we should not be inside of this if block.

   88           drop(lock);
   89
   90           if old_handler != &default_handler {
-> 91               Box::from_raw(old_handler as *mut (Fn(&PanicInfo) + 'static + Sync + Send));
   92           }
   93       }
   94   }
(lldb) p default_handler
(void (*)(std::panicking::PanicInfo *)) $17 = &0x1000c4300
(lldb) expr -f hex -- **((size_t **) &old_handler + 0)
(size_t) $18 = 0x00000001000c4300 0x00000001000c4300

@ranma42
Copy link
Contributor

ranma42 commented Dec 22, 2015

We might also want to test the interaction with double panics (including panic->panic->abort and panic->set_handler->panic->abort).

@sfackler
Copy link
Member Author

Ok, it appears that comparison isn't working because the two fat pointers are ending up with different vtables, which is pretty weird but may or may not be intended. I guess I'll add an extra layer of indirection and store a *const Box<Fn()>.

@sfackler
Copy link
Member Author

@alexcrichton Updated.

unsafe {
let lock = HANDLER_LOCK.write();
let old_handler = HANDLER;
HANDLER = Handler::Custom(Box::into_raw(Box::new(handler)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Box::new allocation here can probably move outside the lock

@alexcrichton
Copy link
Member

Just one nit but otherwise looks good to me, thanks @sfackler! r=me with that

@sfackler
Copy link
Member Author

@bors r=alexcrichton

@bors
Copy link
Contributor

bors commented Dec 23, 2015

📌 Commit f1148a5 has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Dec 25, 2015

⌛ Testing commit f1148a5 with merge dd40b17...

@bors
Copy link
Contributor

bors commented Dec 25, 2015

⛄ The build was interrupted to prioritize another pull request.

bors added a commit that referenced this pull request Dec 25, 2015
@bors
Copy link
Contributor

bors commented Dec 25, 2015

⌛ Testing commit f1148a5 with merge 24580e6...

@bors
Copy link
Contributor

bors commented Dec 25, 2015

⛄ The build was interrupted to prioritize another pull request.

@bors bors merged commit f1148a5 into rust-lang:master Dec 25, 2015
@sfackler sfackler deleted the panic-handler branch November 26, 2016 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants