digitalmars.D.learn - Proper way to exit with specific exit code?
- drathier (6/6) Sep 17 2020 What's the proper way to exit with a specific exit code?
- H. S. Teoh (24/31) Sep 17 2020 AFAIK, there still isn't an "official" way to do this besides return
- IGotD- (16/22) Sep 17 2020 The only way is to return from main. The thing is that druntime
- James Blachly (7/12) Sep 17 2020 ...
- H. S. Teoh (21/26) Sep 17 2020 Yes.
- IGotD- (13/30) Sep 18 2020 I think a pragmatic solution is just to mutex protect the D exit
- H. S. Teoh (17/40) Sep 18 2020 That does not solve the problem. If thread 1 calls exit but thread 2 is
- Jacob Carlborg (11/18) Sep 18 2020 The proper way is:
- mw (8/24) Nov 13 2022 I'm facing this problem to exit early from a multi threaded
- mw (8/9) Nov 13 2022 Tried
- Imperatorn (2/11) Nov 13 2022 I have no idea why it would fail. What about assert(0)?
- Ruby The Roobster (4/31) Nov 13 2022 Just give the threads a killswitch, pass the killswitch method to
What's the proper way to exit with a specific exit code? I found a bunch of old threads discussing this, making sure destructors run and the runtime terminates properly, all of which seemingly concluding that it's sad that there isn't a way to do this easily, but hopefully things have changed in the last 5-10 years and I'm just missing the obvious solution.
Sep 17 2020
On Thu, Sep 17, 2020 at 02:58:48PM +0000, drathier via Digitalmars-d-learn wrote:What's the proper way to exit with a specific exit code? I found a bunch of old threads discussing this, making sure destructors run and the runtime terminates properly, all of which seemingly concluding that it's sad that there isn't a way to do this easily, but hopefully things have changed in the last 5-10 years and I'm just missing the obvious solution.AFAIK, there still isn't an "official" way to do this besides return the exit code from main(). My go-to solution is to declare an ExitException that's explicitly caught by main(): class ExitException : Exception { int returnCode; this() { super("exit"); } } void exit(int rc=0) { throw new ExitException(rc); } int main(string[] args) { try { ... // your code here exit(123); ... } catch (ExitException e) { return e.returnCode; } return 0; } Caveat: this may or may not do the Right Thing(tm) in a multithreaded application. T -- Talk is cheap. Whining is actually free. -- Lars Wirzenius
Sep 17 2020
On Thursday, 17 September 2020 at 14:58:48 UTC, drathier wrote:What's the proper way to exit with a specific exit code? I found a bunch of old threads discussing this, making sure destructors run and the runtime terminates properly, all of which seemingly concluding that it's sad that there isn't a way to do this easily, but hopefully things have changed in the last 5-10 years and I'm just missing the obvious solution.The only way is to return from main. The thing is that druntime runs initialization before main and then returning from main it runs all the tear down code including cleaning up the GC. This means there is no equivalent of the exit function in the C library. Calling exit from D means that there will be no cleanup in D environment. This is a bit limiting for my needs for example. I would like that exiting from main will not tear down the D runtime because my system is a message driven system and main just sets up the program and then returns but the programs continues to react on messages. Many libraries like Qt circumvents this just by parking the main thread as a event handler but this doesn't fit my system and will waste one thread resource. Finally to exit the program I have equivalent to the C library exit function. Creating a similar exit function in D would be trivial really.
Sep 17 2020
On 9/17/20 12:46 PM, IGotD- wrote:The only way is to return from main. The thing is that druntime runs initialization before main and then returning from main it runs all the tear down code including cleaning up the GC. This means there is no equivalent of the exit function in the C library. Calling exit from D means that there will be no cleanup in D environment.... I never considered this -- so when I call core.stdc.stdlib : exit, none of my destructors get called? Presumably also not scope(exit) blocks? If this is the case, could we simply add a publically-accessible shutdown hook in the runtime?
Sep 17 2020
On Thu, Sep 17, 2020 at 09:53:07PM -0400, James Blachly via Digitalmars-d-learn wrote: [...]I never considered this -- so when I call core.stdc.stdlib : exit, none of my destructors get called?Yes.Presumably also not scope(exit) blocks?Yes.If this is the case, could we simply add a publically-accessible shutdown hook in the runtime?That's the obvious solution, except that actually implementing it is not so simple. When you have multiple threads listening for each other and/or doing work, there is no 100% guaranteed way of cleanly shutting all of them down at the same time. You can't just clean up the calling thread and leave the others running, because the other threads might hold references to your data, etc.. But there's no universal protocol for shutting down the other threads too -- they could be in a busy loop with some long-running computation, or they may not be checking for thread messages, or they could be in a server loop that is designed to keep running, etc.. It's one of those annoying things that reduce to the halting problem in the general case. Unless we adopt some kind of exit protocol that will apply to *all* threads in *all* D programs, I don't see any way to implement something that will work in the general case. T -- If blunt statements had a point, they wouldn't be blunt...
Sep 17 2020
On Friday, 18 September 2020 at 05:02:21 UTC, H. S. Teoh wrote:That's the obvious solution, except that actually implementing it is not so simple. When you have multiple threads listening for each other and/or doing work, there is no 100% guaranteed way of cleanly shutting all of them down at the same time. You can't just clean up the calling thread and leave the others running, because the other threads might hold references to your data, etc.. But there's no universal protocol for shutting down the other threads too -- they could be in a busy loop with some long-running computation, or they may not be checking for thread messages, or they could be in a server loop that is designed to keep running, etc.. It's one of those annoying things that reduce to the halting problem in the general case. Unless we adopt some kind of exit protocol that will apply to *all* threads in *all* D programs, I don't see any way to implement something that will work in the general case. TI think a pragmatic solution is just to mutex protect the D exit function in case several threads tries to use simultaneously. Then if more threads call exit, it will do nothing as the first one that called exit actually do the tear down. Also, it should be responsibility of the program to ensure that its tear down code runs before calling the D exit function. That's the only way I can think of because waiting for all other threads to release their resources and exit isn't really realistic either as that might do that the program exit never happens. Whatever you do you, you have to resort to some "manual" solution". I suggest keeping it simple and stupid.
Sep 18 2020
On Fri, Sep 18, 2020 at 08:20:59AM +0000, IGotD- via Digitalmars-d-learn wrote:On Friday, 18 September 2020 at 05:02:21 UTC, H. S. Teoh wrote:[...]That's the obvious solution, except that actually implementing it is not so simple. When you have multiple threads listening for each other and/or doing work, there is no 100% guaranteed way of cleanly shutting all of them down at the same time. You can't just clean up the calling thread and leave the others running, because the other threads might hold references to your data, etc.. But there's no universal protocol for shutting down the other threads too -- they could be in a busy loop with some long-running computation, or they may not be checking for thread messages, or they could be in a server loop that is designed to keep running, etc.. It's one of those annoying things that reduce to the halting problem in the general case.I think a pragmatic solution is just to mutex protect the D exit function in case several threads tries to use simultaneously. Then if more threads call exit, it will do nothing as the first one that called exit actually do the tear down.That does not solve the problem. If thread 1 calls exit but thread 2 is still running and processing data via a shared reference with thread 1's data, you absolutely do not want to run dtors and tear-down code until thread 2 is done, otherwise you have a problem. OTOH, waiting for thread 2 to finish first comes with its own problems: what if thread 2 never calls exit? Then no cleanup will be done, which may not be desirable either (maybe you had thread 1 call exit because you wanted to release unused resources).Also, it should be responsibility of the program to ensure that its tear down code runs before calling the D exit function. That's the only way I can think of because waiting for all other threads to release their resources and exit isn't really realistic either as that might do that the program exit never happens. Whatever you do you, you have to resort to some "manual" solution".[...] If you're prepared to do manual teardown, then you do not need a D-specific exit function. Just call core.sys.stdc.stdlib.exit and call it a day. :-) T -- Never trust an operating system you don't have source for! -- Martin Schulze
Sep 18 2020
On 2020-09-17 16:58, drathier wrote:What's the proper way to exit with a specific exit code? I found a bunch of old threads discussing this, making sure destructors run and the runtime terminates properly, all of which seemingly concluding that it's sad that there isn't a way to do this easily, but hopefully things have changed in the last 5-10 years and I'm just missing the obvious solution.The proper way is: int main() { return 42; } I highly recommend against trying to terminate the application using `exit` or any other way. Just let the control flow return back to the `main` function. -- /Jacob Carlborg
Sep 18 2020
On Saturday, 19 September 2020 at 06:11:15 UTC, Jacob Carlborg wrote:On 2020-09-17 16:58, drathier wrote:I'm facing this problem to exit early from a multi threaded program for mem profiling purpose: https://forum.dlang.org/thread/zbdevevgghtdgfryuymh forum.dlang.org So what the simplest and reliable way to terminate all threads and exit to os? I even tried core.stdc.stdlib.exit(-1), it does not work.What's the proper way to exit with a specific exit code? I found a bunch of old threads discussing this, making sure destructors run and the runtime terminates properly, all of which seemingly concluding that it's sad that there isn't a way to do this easily, but hopefully things have changed in the last 5-10 years and I'm just missing the obvious solution.The proper way is: int main() { return 42; } I highly recommend against trying to terminate the application using `exit` or any other way. Just let the control flow return back to the `main` function.
Nov 13 2022
On Sunday, 13 November 2022 at 21:16:32 UTC, mw wrote:I even tried core.stdc.stdlib.exit(-1), it does not work.Tried ``` import core.runtime; Runtime.terminate(); core.stdc.stdlib.exit(-1); ``` Still does not work.
Nov 13 2022
On Sunday, 13 November 2022 at 21:37:47 UTC, mw wrote:On Sunday, 13 November 2022 at 21:16:32 UTC, mw wrote:I have no idea why it would fail. What about assert(0)?I even tried core.stdc.stdlib.exit(-1), it does not work.Tried ``` import core.runtime; Runtime.terminate(); core.stdc.stdlib.exit(-1); ``` Still does not work.
Nov 13 2022
On Sunday, 13 November 2022 at 22:06:09 UTC, Imperatorn wrote:On Sunday, 13 November 2022 at 21:37:47 UTC, mw wrote:I guess these two calls somehow only terminate the calling thread (? this is strange for core.stdc.stdlib.exit), the whole program just hangs after the call, and can only be terminated by `kill -9`. I have to manually go thru each of the treads and plug in some kind of early exit logic to stop the whole program. Will try assert(0) later.On Sunday, 13 November 2022 at 21:16:32 UTC, mw wrote:I have no idea why it would fail. What about assert(0)?I even tried core.stdc.stdlib.exit(-1), it does not work.Tried ``` import core.runtime; Runtime.terminate(); core.stdc.stdlib.exit(-1); ``` Still does not work.
Nov 13 2022
On Sunday, 13 November 2022 at 22:17:32 UTC, mw wrote:On Sunday, 13 November 2022 at 22:06:09 UTC, Imperatorn wrote:tried: ``` core.runtime.Runtime.terminate(); core.stdc.stdlib.exit(-1); assert(0); enforce(false); ``` Still not working, not even "Ctrl+C", have to `kill -9` to terminate it.On Sunday, 13 November 2022 at 21:37:47 UTC, mw wrote:I guess these two calls somehow only terminate the calling thread (? this is strange for core.stdc.stdlib.exit), the whole program just hangs after the call, and can only be terminated by `kill -9`. I have to manually go thru each of the treads and plug in some kind of early exit logic to stop the whole program. Will try assert(0) later.On Sunday, 13 November 2022 at 21:16:32 UTC, mw wrote:I have no idea why it would fail. What about assert(0)?I even tried core.stdc.stdlib.exit(-1), it does not work.Tried ``` import core.runtime; Runtime.terminate(); core.stdc.stdlib.exit(-1); ``` Still does not work.
Nov 13 2022
On Sunday, 13 November 2022 at 22:42:45 UTC, mw wrote:On Sunday, 13 November 2022 at 22:17:32 UTC, mw wrote:Tried put assert(0) at the top: ``` assert(0); enforce(false); core.runtime.Runtime.terminate(); core.stdc.stdlib.exit(-1); ``` Seems cannot even terminate the calling thread, since I got that assertion error thousands of times in the log.On Sunday, 13 November 2022 at 22:06:09 UTC, Imperatorn wrote:tried: ``` core.runtime.Runtime.terminate(); core.stdc.stdlib.exit(-1); assert(0); enforce(false); ``` Still not working, not even "Ctrl+C", have to `kill -9` to terminate it.On Sunday, 13 November 2022 at 21:37:47 UTC, mw wrote:I guess these two calls somehow only terminate the calling thread (? this is strange for core.stdc.stdlib.exit), the whole program just hangs after the call, and can only be terminated by `kill -9`. I have to manually go thru each of the treads and plug in some kind of early exit logic to stop the whole program. Will try assert(0) later.On Sunday, 13 November 2022 at 21:16:32 UTC, mw wrote:I have no idea why it would fail. What about assert(0)?I even tried core.stdc.stdlib.exit(-1), it does not work.Tried ``` import core.runtime; Runtime.terminate(); core.stdc.stdlib.exit(-1); ``` Still does not work.
Nov 13 2022
On Sunday, 13 November 2022 at 21:16:32 UTC, mw wrote:On Saturday, 19 September 2020 at 06:11:15 UTC, Jacob Carlborg wrote:Just give the threads a killswitch, pass the killswitch method to all of the threads, wait for all the threads to exit, and then return. If this doesn't work, than I don't know what will.On 2020-09-17 16:58, drathier wrote:I'm facing this problem to exit early from a multi threaded program for mem profiling purpose: https://forum.dlang.org/thread/zbdevevgghtdgfryuymh forum.dlang.org So what the simplest and reliable way to terminate all threads and exit to os? I even tried core.stdc.stdlib.exit(-1), it does not work.What's the proper way to exit with a specific exit code? I found a bunch of old threads discussing this, making sure destructors run and the runtime terminates properly, all of which seemingly concluding that it's sad that there isn't a way to do this easily, but hopefully things have changed in the last 5-10 years and I'm just missing the obvious solution.The proper way is: int main() { return 42; } I highly recommend against trying to terminate the application using `exit` or any other way. Just let the control flow return back to the `main` function.
Nov 13 2022