digitalmars.D.bugs - [Issue 8135] New: throwing Error runs finally handler
- d-bugmail puremagic.com (39/39) May 23 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (29/29) May 23 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (12/14) May 23 2012 No they are not when you throw from a nothrow function.
- d-bugmail puremagic.com (22/22) May 23 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (16/16) May 23 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (16/16) May 23 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (12/12) May 23 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (8/8) May 23 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (17/19) May 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (20/20) May 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (9/22) May 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
- d-bugmail puremagic.com (8/9) May 24 2012 You could simply override the behavior by providing your own
- d-bugmail puremagic.com (9/14) May 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8135
http://d.puremagic.com/issues/show_bug.cgi?id=8135 Summary: throwing Error runs finally handler Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: dawg dawgfoto.de --- Comment #0 from dawg dawgfoto.de 2012-05-23 12:34:18 PDT --- cat > bug.d << CODE extern(C) int printf(const char*, ...); void foo() { throw new Error("msg"); } void main() { try foo(); finally printf("finally\n"); } CODE dmd -run bug prints: finally object.Error: msg expected: object.Error: msg ---- The expected behavior was discussed in bug 7018 and on the mailing list. Throwing Errors (http://forum.dlang.org/thread/1566418.J7qGkEti3s lyonel) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 23 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 Jonathan M Davis <jmdavisProg gmx.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED CC| |jmdavisProg gmx.com Resolution| |INVALID --- Comment #1 from Jonathan M Davis <jmdavisProg gmx.com> 2012-05-23 14:06:36 PDT --- This is not a bug. Per the lanugage, there is no guarantee that finally blocks, scope statements, or destructors will be run when an Error is thrown, but neither is there any guarantee that they _won't_ be. So, while relying on them being executed when an Error is thrown is a bad idea, relying on them _not_ being executed when an Error is thrown is also a bad idea. The current implementation _does_ always execute finally blocks, scope statements, and destructors with Errors just like would occur with Exceptions, and there is quite a lot of debate over whether the language should be changed to reflect that. Walter is against it, but he's also one of the few who even realized that the language didn't guarantee that they would be executed for Errors. Other people who have been working on the exception handling in the compiler and druntime _did_ think that it was guaranteed, and they wrote that code with that in mind. In addition, I believe that the spec itself is actually silent on the matter. So, the short answer is that you should never rely on scope statements, finally blocks, or destructors being run or not run when an Error is thrown. A more thorough discussion of the issues is in this thread on dmd-internals: http://forum.dlang.org/post/1566418.J7qGkEti3s lyonel -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 23 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 --- Comment #2 from dawg dawgfoto.de 2012-05-23 19:40:45 PDT ---The current implementation _does_ always execute finally blocks, scope statements, and destructors with Errors just like would occur with ExceptionsNo they are not when you throw from a nothrow function. This is even worse when nothrow is inferred, because the actual behavior becomes instable.So, the short answer is that you should never rely on scope statements, finally blocks, or destructors being run or not run when an Error is thrown.This is not an acceptable solution. The problem needs a clean decision and an according implementation or it will continue to create confusion. https://github.com/D-Programming-Language/druntime/pull/225#issuecomment-5857155 I'm wondering how the decision to use EH for fatal errors was made. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 23 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 --- Comment #3 from Jonathan M Davis <jmdavisProg gmx.com> 2012-05-23 19:53:36 PDT --- Well, unstable behavior from an Error is pretty much a given if your program doesn't die from it, unless it were treated completely like an Exception, in which case you couldn't throw an Error (including OutOfMemoryError) from a nothrow function, which would be unacceptable. Your program is pretty much instantly in an unstable state as soon as an Error is thrown. It's just a question of _how_ unstable, and the given implementation attempts far more cleanup than is technically required according to Walter, which is a double-edged sword, since that tends to make the code more stable when an Error is thrown, but if your program is in a bad state thanks to whatever caused the Error to be thrown, trying to do that cleanup could just make things worse. Regardless, I completely agree that the situation needs to be clarified. We've got the implementation going one way and Walter arguing another. And it would certainly be better if it were guaranteed that finally and friends were never executed when an Error is thrown than having them executed right now but possibly not later when the implementation is tweaked. So, in principle, I agree with the bug report, but as it stands, the current implementation is within the required behavior. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 23 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 Alex Rønne Petersen <alex lycus.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |alex lycus.org --- Comment #4 from Alex Rønne Petersen <alex lycus.org> 2012-05-24 04:59:41 CEST --- FWIW, I'm all for making Errors actually fatal and terminating the runtime immediately, but then OutOfMemory*Error* HAS GOT TO GO. I use D as a systems language, not as an applications language, and I *have* to be able to catch an out of memory condition. I don't know why this was made an Error in the first place, and in a systems language of all things. Yes, most developers may get it wrong, but what about the few of us that *don't*? Just my 2 cents/frustration as a developer writing a virtual machine in D... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 23 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 --- Comment #5 from Jonathan M Davis <jmdavisProg gmx.com> 2012-05-23 20:04:56 PDT --- Walter is of the firm belief that running out of memory is essentially unrecoverable, so I don't see OutOfMemoryError ever being anything other than an Error. If you really can't deal with that, you're probably going to have to use something other than the GC for memory management (or wrap all GC allocations in functions that can catch and deal with OutOfMemoryError immediately after its thrown). Even if the cleanup doesn't occur for Errors, it's quite possible to catch them and handle them, and if you catch them very close to the throw point, you can do so relatively safely. It's catching them far from the throw point that isn't going to work. http://d.puremagic.com/issues/show_bug.cgi?id=8137 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 23 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 --- Comment #6 from Alex Rønne Petersen <alex lycus.org> 2012-05-24 05:10:03 CEST --- From TDPL §9.4: "If you catch a Throwable, you may only perform a number of simple operations; most of the time, you probably want to print a message to the standard error or a log file, attempt to save whatever you can save to a separate file, stiffen that upper lip, and exit with as much dignity as possible." This doesn't seem terribly encouraging... Essentially, I need to catch OOME and continue full-blown program execution, which is very worrying. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 23 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 --- Comment #7 from Jonathan M Davis <jmdavisProg gmx.com> 2012-05-23 20:19:00 PDT --- You should be able to do so under very limited circumstances, but it was definitely a design decision of D that running out of memory would be considered to be unrecoverable. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 23 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 Steven Schveighoffer <schveiguy yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy yahoo.com --- Comment #8 from Steven Schveighoffer <schveiguy yahoo.com> 2012-05-24 07:01:45 PDT --- (In reply to comment #4)FWIW, I'm all for making Errors actually fatal and terminating the runtime immediately, but then OutOfMemory*Error* HAS GOT TO GO.Then you could mark almost nothing as nothrow. I think OutOfMemory should be an error. If you want to override the behavior because you have special circumstances, that should be possible (i.e. somehow prevent out of memory error from being thrown, but instead handle the situation in a different way). What about an enhancement of adding GC.mallocNoError and friends which instead return null when a memory block is not available instead of throwing? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 jens.k.mueller gmx.de changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jens.k.mueller gmx.de --- Comment #9 from jens.k.mueller gmx.de 2012-05-24 07:15:30 PDT --- I don't see why there should be no way to do some simple cleanup on an Error. Testing in contracts is useful and does no harm. Maybe Walter can give a concrete example where handling of Errors caused the program to be in a worse state compared to exit right away given the programmer had a solid understanding of what he was doing. Assuming I get an OutOfMemoryError having chances sending last words is useful. I fail to see how this can make it worse. It may be that he has seen to many misuses of handling errors. I would go with a C++ attitude: "You can catch, scope guard, etc. any Throwable and even try to recover from Exceptions. But Errors are not meant to be recovered from. You have been warned." TDPL also says that it's okay to do some cleanup. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 --- Comment #10 from Alex Rønne Petersen <alex lycus.org> 2012-05-24 18:44:33 CEST --- (In reply to comment #8)(In reply to comment #4)True.FWIW, I'm all for making Errors actually fatal and terminating the runtime immediately, but then OutOfMemory*Error* HAS GOT TO GO.Then you could mark almost nothing as nothrow.I think OutOfMemory should be an error. If you want to override the behavior because you have special circumstances, that should be possible (i.e. somehow prevent out of memory error from being thrown, but instead handle the situation in a different way). What about an enhancement of adding GC.mallocNoError and friends which instead return null when a memory block is not available instead of throwing?That could work too. I really just want the GC to not assume that an allocation error is fatal. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 --- Comment #11 from dawg dawgfoto.de 2012-05-24 12:55:08 PDT ---That could work too. I really just want the GC to not assume that an allocation error is fatal.You could simply override the behavior by providing your own 'extern(C) void onOutOfMemory()'. The linker will pick the one from druntime with the lowest precedence. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8135 --- Comment #12 from Alex Rønne Petersen <alex lycus.org> 2012-05-25 04:35:42 CEST --- (In reply to comment #11)I don't always want out of memory to be handled. In most cases, I do treat it as fatal, but in the few cases I don't, I just want to get a null value back from allocations in the core.memory module. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------That could work too. I really just want the GC to not assume that an allocation error is fatal.You could simply override the behavior by providing your own 'extern(C) void onOutOfMemory()'. The linker will pick the one from druntime with the lowest precedence.
May 24 2012