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

Add a way to exit a thread early and run destructors, akin to panic!(), without displaying an error message to the user #1089

Closed
yberreby opened this issue Apr 26, 2015 · 10 comments

Comments

@yberreby
Copy link

Unwinding the stack and running destructors is useful to abort a particular thread, without having to add early returns all the way up the call stack. panic!() provides this functionality, but also displays a message to the user, even if the panic is caught, which is disturbing: you don't want to expose debugging info such as line number to the end user.

This would provide a clean exit mechanism while avoiding adding functionality that's already there, as you get (correct me if I'm wrong) similar results with either early returns and panic!(): the stack unwinds, destructors are run, and the thread exits cleanly. This is not a problem for single-threaded programs, which can use std::process::exit and let the OS clean up resources, but would be useful for multi-threaded programs.

Essentially, I'm proposing a silent version of panic!(), that does not actually panic (does not change the return value of http://doc.rust-lang.org/1.0.0-beta.2/std/thread/fn.panicking.html , for example), but acts as if all currently called functions returned early. Being able to panic!() without cluttering logs would probably also be useful.

EDIT: actually, a silent version of panic!() would be simpler to implement and probably better overall (avoid having separate panic mechanisms, as pointed by @Diggsey)

@Diggsey
Copy link
Contributor

Diggsey commented Apr 26, 2015

I don't think introducing a separate panicking mechanism is a good idea. I'm not sure where the panic message is printed, but I think the intended way to achieve this (if you really can't add early returns up the call stack) is to spawn the thread with a wrapper which silently ignores panics. The return value of panicking() should still be true.

@nagisa
Copy link
Member

nagisa commented Apr 26, 2015

There’s currently no way to make panic!() not print anything if you’re using stdlib (see rust-lang/rust#24099).

I think it would be great if panic!() didn’t print anything and just unwound the calling thread.

@yberreby
Copy link
Author

@Diggsey how would you achieve that? http://is.gd/aDT4F7 prints the panic message.

@nagisa I agree, panic!() should be a simple wrapper adding logging around a silent panic function.

@Diggsey
Copy link
Contributor

Diggsey commented Apr 26, 2015

@filsmick I didn't mean it was actually possible today, unfortunately, just that in the long term that's likely how it should be done (rather than introducing a new unwinding mechanism, to fix the problems with the existing one).

@yberreby
Copy link
Author

@Diggsey I don't think it's a good idea. Rust emphasizes performance, and spawning a new thread just to avoid logging isn't exactly efficient. There is no need to introduce a new unwinding mechanism either. The idea is to remove logging from std::rt::unwind::begin_unwind_inner, wrap its functionality in another function that will provide logging and be called by panic!(), and provide something like panic_silent!() that uses the new begin_unwind_inner without adding logging on top of it.

Or, to preserve backward compatibility, add a new function without logging and deprecate the old one. That's not "a new unwinding mechanism", that's moving functionality out of the old one and deprecating it.

@Diggsey
Copy link
Contributor

Diggsey commented Apr 26, 2015

@filsmick That's exactly how I was saying it should behave, the only reason I was talking about spawning threads is because that was your example.

edit:
Actually no, it's similar, but instead of introducing a "panic_silent!()" method, I was suggesting adding a panic handler to the thread which might panic, which ignores the panic, in addition to the chagnes to begin_unwind. The default panic handler would print the message. I'm not sure what you mean by "spawning a new thread to avoid logging" - even if it's the main thread you want to terminate, there should still be a way to attach a custom panic handler (although if it's the main thread, you can just terminate the whole process, since that what happens when the main thread exits anyway).

@yberreby
Copy link
Author

@Diggsey

I was suggesting adding a panic handler to the thread which might panic, which ignores the panic, in addition to the chagnes to begin_unwind.

My bad. I thought you meant spawn a new thread around an existing one to somehow catch the panic without logging it.

I think that's a good idea, clean and flexible. It could be also be implemented easily in terms of panic_silent!(), that said.

@yberreby
Copy link
Author

I've thought about it, and the best way to do this would be to make panic!() silent - that is, instead of getting thread '<main>' panicked at 'explicit panic', <foo>:2, nothing is output to stdout.

No deprecation, no addition of a new panic mechanism, just what makes the most sense: if you want a message to be displayed, you should be passing it as an argument to the macro anyway!

@steveklabnik
Copy link
Member

#1328 being merged should help with this!

@alexcrichton
Copy link
Member

I believe this is basically handled by std::panic::catch_panic which is being tracked by rust-lang/rust#30449, so closing.

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

No branches or pull requests

5 participants