# Cleanly exiting the program in Rust

**URL:** <https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501>\
**Category:** language design\
**Created:** [July 7, 2017, 6:44pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501 "2017-07-07T18:44:41Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![marmistrz](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@marmistrz](https://internals.rust-lang.org/u/marmistrz)\
**Post date:** [July 7, 2017, 6:44pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/1 "2017-07-07T18:44:41Z")

</div>

There was a similar thread [here](https://internals.rust-lang.org/t/why-doesnt-exit-unwind/1806) but I don’t want to necrobump.

Currently, we only have `std::process::exit()`. It does exactly what its name does - exits. Without cleaning up anything. In particular, without calling destructors.

In some programming cases, we may find out that we have no more work to do and just need to exit. This may happen very deep in the call tree. The currently possible solutions, which came up in a discussion on IRC, are:

1. Use `std::process::exit`. This, as said before, invokes no destructors and may be a source of bugs. There’s no use duplicating code and writing custom cleanup functions (which do exactly the same as the Drop trait) and at some time forget that we have this buffered logger in completely separate part of code we forgot about, or a created temporary file we were to delete, or some Unix socket we wanted to delete, …
2. Propagate the “end of program” condition. Here, if we use `Result` - we create nonsense in our code, using the `Err` variant for cases where no error has occurred. If use something else, e.g. an `enum`, we can’t simply use the `try!` or `?` macro, so we clutter the code at any exit point. Of course, we can write our own, make it a crate, … And what if we were using `Command::new` to launch a command and just want to exit with the child’s exit code… `std::process::exit` at the last line…?

But remember, we were just to exit the program. And this is not an error, no exception - just time to finish our work.

I perfectly know that stack unwinding is very costly in Rust - but the program is going to terminate anyway in a while, so I don’t find it a big problem in this case. It is the whole power of destructors that they get invoked without the programmer having not to forget about them.

Is this a design decision not to support `exit` with unwinding or is it just something that is planned for future releases?

---

<div class="post-metadata">

**Author:** ![sfackler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sfackler/32/9_2.png) [@sfackler](https://internals.rust-lang.org/u/sfackler)\
**Post date:** [July 7, 2017, 6:49pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/2 "2017-07-07T18:49:22Z")

</div>

What do you want to have happen to threads other than the main one when this happens?

---

<div class="post-metadata">

**Author:** ![marmistrz](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@marmistrz](https://internals.rust-lang.org/u/marmistrz)\
**Post date:** [July 13, 2017, 1:45pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/3 "2017-07-13T13:45:41Z")

</div>

I see that `panic!` properly unwinds the stack, even with multiple threads. What’s the `panic!`'s policy here?

I think that this _unwindive_ exit could do the same.

---

<div class="post-metadata">

**Author:** ![sfackler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sfackler/32/9_2.png) [@sfackler](https://internals.rust-lang.org/u/sfackler)\
**Post date:** [July 13, 2017, 2:25pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/4 "2017-07-13T14:25:01Z")

</div>

A panic unwinds the stack of the thread it occurred on, after which that thread the exits. If the main thread exits, the program terminates.

---

<div class="post-metadata">

**Author:** ![steveklabnik](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steveklabnik/32/4524_2.png) [@steveklabnik](https://internals.rust-lang.org/u/steveklabnik)\
**Post date:** [July 13, 2017, 2:34pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/5 "2017-07-13T14:34:11Z")

</div>

Small note, panic _may_ unwind the stack. It may also abort.

---

<div class="post-metadata">

**Author:** ![marmistrz](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@marmistrz](https://internals.rust-lang.org/u/marmistrz)\
**Post date:** [July 13, 2017, 4:12pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/6 "2017-07-13T16:12:55Z")

</div>

What with the other threads?

Sometimes the whole process just gets killed: [https://play.rust-lang.org/?gist=8f46c76c07bd49b4790f2c2c23136fe1&version=stable](https://play.rust-lang.org/?gist=8f46c76c07bd49b4790f2c2c23136fe1&version=stable) but I don’t know if it’s a general rule with multiple threads.

---

<div class="post-metadata">

**Author:** ![marmistrz](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@marmistrz](https://internals.rust-lang.org/u/marmistrz)\
**Post date:** [July 13, 2017, 4:13pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/7 "2017-07-13T16:13:13Z")

</div>

Yep, I know, this can be set at compilation time. I meant the default panic behavior.

---

<div class="post-metadata">

**Author:** ![sfackler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sfackler/32/9_2.png) [@sfackler](https://internals.rust-lang.org/u/sfackler)\
**Post date:** [July 13, 2017, 4:30pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/8 "2017-07-13T16:30:37Z")

</div>

A panic in one thread does not affect other threads.

---

<div class="post-metadata">

**Author:** ![marmistrz](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@marmistrz](https://internals.rust-lang.org/u/marmistrz)\
**Post date:** [July 14, 2017, 10:05am UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/9 "2017-07-14T10:05:35Z")

</div>

Ok, but in my example a panic in one thread killed all the others.

---

<div class="post-metadata">

**Author:** ![sfackler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sfackler/32/9_2.png) [@sfackler](https://internals.rust-lang.org/u/sfackler)\
**Post date:** [July 14, 2017, 4:37pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/10 "2017-07-14T16:37:29Z")

</div>

It looks like that program hits the playground timeout when I run it.

---

<div class="post-metadata">

**Author:** ![marmistrz](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@marmistrz](https://internals.rust-lang.org/u/marmistrz)\
**Post date:** [July 17, 2017, 8:45am UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/11 "2017-07-17T08:45:47Z")

</div>

So why not do the same for the “clean exit”? And the exitcode would be the exitcode from the main thread.

---

<div class="post-metadata">

**Author:** ![cristicbz](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cristicbz/32/935_2.png) [@cristicbz](https://internals.rust-lang.org/u/cristicbz)\
**Post date:** [July 17, 2017, 1:41pm UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/12 "2017-07-17T13:41:01Z")

</div>

Panic also aborts in the case of double panics, not only when `panic=abort` is set.

---

<div class="post-metadata">

**Author:** ![marmistrz](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@marmistrz](https://internals.rust-lang.org/u/marmistrz)\
**Post date:** [August 1, 2017, 8:46am UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/13 "2017-08-01T08:46:15Z")

</div>

In fact, the C `exit` function **will** do some cleanup: [http://en.cppreference.com/w/c/program/exit](http://en.cppreference.com/w/c/program/exit)

---

<div class="post-metadata">

**Author:** ![retep998](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/retep998/32/729_2.png) [@retep998](https://internals.rust-lang.org/u/retep998)\
**Post date:** [August 11, 2017, 2:49am UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/14 "2017-08-11T02:49:45Z")

</div>

The C `exit` function will do some internal cleanup of the C standard library’s internal stuff, such as flushing the C standard library stdout buffer, as well as calling any handlers registered via `atexit`. It will **not** do any cleanup of Rust destructors.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:28am UTC](https://internals.rust-lang.org/t/cleanly-exiting-the-program-in-rust/5501/15 "2019-03-25T08:28:43Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
