Bug 7018 – thrown Error from different thread should lead to program abort

Status
REOPENED
Severity
normal
Priority
P3
Component
druntime
Product
D
Version
D2
Platform
Other
OS
All
Creation time
2011-11-26T15:01:32Z
Last change time
2024-12-07T13:31:38Z
Assigned to
No Owner
Creator
Martin Nowak
Moved to GitHub: dmd#17236 →

Comments

Comment #0 by code — 2011-11-26T15:01:32Z
void main(string[] args) { try { assert(args.length > 1); } finally { extern(C) void printf(const char* format, ...); printf("finally\n"); } } --- The issue is that AssertExp is marked as nothrow. This bug is responsible for the deadlocks in druntime unittests. synchronized(foo) { assert(exp); } is rewritten as _d_monitorenter(__sync); assert(exp); _d_monitorexit(__sync);
Comment #1 by bugzilla — 2011-11-26T20:45:19Z
The behavior is correct. assert throws a non-recoverable exception, which means that finally blocks are not executed. If a test depends on finally being executed after an assert, then the test case is wrong.
Comment #2 by braddr — 2011-11-26T21:40:25Z
I'm going to re-open for a second. I don't disagree with the part about assert + try/catch/finally, I agree that there's, at a minimum, a diagnostic issue here. There's no case in which synchronized { assert } is valid. Additionally, if this is indeed the source of the druntime deadlock, THAT bug isn't invalid and still needs to be fixed.
Comment #3 by bugzilla — 2011-11-26T22:08:27Z
(In reply to comment #2) > There's no case in which synchronized { assert } is valid. There is because assert is for checking for logic errors, and then it is supposed to abort the program. It is not expected to clean up finally blocks, release mutexes, etc. AssertExp *is* nothrow. If there are bugs in the druntime tests, those need to be identified and submitted.
Comment #4 by code — 2011-11-27T04:34:47Z
I agree with nothrow. Not sure how to handle synchronized { assert }. Maybe the root cause is that the runtime fails to abort a program with Errors being thrown in different threads, is it?
Comment #5 by sean — 2011-11-30T16:34:21Z
If no cleanup should be performed, why is an assertion failure represented as an exception in the first place? And what about the other Errors that can legally be generated within a nothrow block (like OutOfMemoryError) but are technically recoverable?
Comment #6 by issues.dlang — 2011-11-30T16:57:07Z
They're Errors, not Exceptions, so they are _not_ expected to be recoverable. The fact that they are exceptions allows you to get more meaningful data on failures (e.g. stack traces), and you _can_ technically recover from them in very controlled circumstances but _only_ in very controlled circumstances where you really know what you're doing and you're very careful to make sure that it's actually safe to do the recovery. In the general case, they are _not_ expected to be recoverable and so are not treated that way. Once an Error is thrown, the program is in an undefined state, so it's questionable that you even _can_ recover except in very controlled circumstances.
Comment #7 by lt.infiltrator — 2014-03-19T22:08:06Z
So, should we mark this off as closed, with Errors not being recoverable?
Comment #8 by code — 2014-11-19T20:30:38Z
We still need to abort the whole program when an error terminates a single thread. This problem has already caused a lot of grief.
Comment #9 by code — 2014-11-19T20:34:55Z
(In reply to Martin Nowak from comment #8) > We still need to abort the whole program when an error terminates a single > thread. This problem has already caused a lot of grief. To clarify this a little. Any Throwables in a thread are catched and are supposed to be rethrown when someone joins the thread. Most of the time your program will stall or loop infinitely, because the main thread is waiting on data from the died thread. Joining would only happen much later.
Comment #10 by robert.schadek — 2024-12-07T13:31:38Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17236 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB