digitalmars.D.internals - Dlang structured exception handling on Windows
- KytoDragon (22/22) Mar 19 2018 I currently have a problem i don't know how to fix:
- Adam D. Ruppe (36/40) Mar 19 2018 Look in druntime src/rt/dmain2.d for "trapExceptions". It is set
- KytoDragon (8/17) Mar 20 2018 I think you missunderstood my problem. I don't mean D-Exceptions,
- KytoDragon (10/12) Mar 20 2018 EDIT 2: Its not my IDE, it is DUB.
- Adam D. Ruppe (5/9) Mar 20 2018 On 32 bit, D exceptions ARE seh exceptions and try/catch works on
- Petar Kirov [ZombineDev] (21/43) Mar 19 2018 I'm not familiar with the neither the implementation details nor
I currently have a problem i don't know how to fix: Programms compiled in D (either compiler) have the annoying property that they absorb all windows seh-exceptions, print the error code and terminate the process. For example, the following programm will print "Program exited with code -1073741819" and exit: module test.Test; void main() { *cast(int*)cast(void*)0 = 1; } But what I expected was the following: https://imgur.com/LH8gUtt (translated for your language) The problem with this is, that this "feature" somehow even manages to catch windows fail-fast exceptions, which are supossed to bypass all exception handling (and debuggers!) and go directly to WER (Windows Error Reporting). This makes it impossible to debug these types of exceptions, as D nearly silently swallows them. My questions are now: What exactly causes this behaviour? (e.q. which part of druntime/phobos/dmd/ldc2) Is there a way to disable that? Has anybody an other solution?
Mar 19 2018
On Monday, 19 March 2018 at 18:39:30 UTC, KytoDragon wrote:What exactly causes this behaviour? (e.q. which part of druntime/phobos/dmd/ldc2)Look in druntime src/rt/dmain2.d for "trapExceptions". It is set to true except "IsDebuggerPresent". That catches everything. You can't reset it to false since it makes a copy of the global var before any user code is run! And the command line switch to disable it that I'm sure I saw the PR for apparently never got in, since I can't find that code in live. So we have to hack around it.Is there a way to disable that? Has anybody an other solution?Behold: --- import core.runtime; import std.stdio; extern(C) int _d_run_main(int argc, char** argv) { Runtime.initialize(); scope(exit) Runtime.terminate(); writeln("here"); int* n = null; *n = 1; writeln("there"); return 0; } // a dummy to trick the compiler into actually linking in the runtime void main() {} --- _d_run_main is an internal function that does a bunch of setup work. This defines our own to override the one in dmain2 and duplicates a bit of its work (though not all, there may be some things that are broken with this!) With this overridden we can get some code running without the exception catch wrapper. Works on 32 bit windows at least. Ideally, we'd just get the commandline/envvar switch to disable... and the PR stalled for ages then the author moved on https://github.com/dlang/druntime/pull/1538 we just should revive that and get it up ASAP. Much better solution than the filthy hack above.
Mar 19 2018
On Monday, 19 March 2018 at 19:09:01 UTC, Adam D. Ruppe wrote:Look in druntime src/rt/dmain2.d for "trapExceptions". It is set to true except "IsDebuggerPresent". That catches everything. With this overridden we can get some code running without the exception catch wrapper. Works on 32 bit windows at least. Ideally, we'd just get the commandline/envvar switch to disable... and the PR stalled for ages then the author moved on https://github.com/dlang/druntime/pull/1538 we just should revive that and get it up ASAP. Much better solution than the filthy hack above.I think you missunderstood my problem. I don't mean D-Exceptions, I mean Windows SEH-Exceptions. These are not caught by D's try ... catch and even your example shows the exact same behaviour. (on DMD at least, LDC complains about the redefined symbol "_d_run_main") EDIT: Ignore everything. It was my IDE that was swallowing exceptions not the compiler.
Mar 20 2018
EDIT: Ignore everything. It was my IDE that was swallowing exceptions not the compiler.EDIT 2: Its not my IDE, it is DUB. dub/generators/build.d, line 532: ------------ auto prg_pid = spawnProcess(exe_path_string ~ run_args); auto result = prg_pid.wait(); enforce(result == 0, "Program exited with code "~to!string(result)); ------------ and std.procedd.PID.wait only gets the exit code, ignoring anything else.
Mar 20 2018
On Tuesday, 20 March 2018 at 17:14:02 UTC, KytoDragon wrote:I think you missunderstood my problem. I don't mean D-Exceptions, I mean Windows SEH-Exceptions. These are not caught by D's try ... catch and even your example shows the exact same behaviour.On 32 bit, D exceptions ARE seh exceptions and try/catch works on both. But if you are on 64 bit, the implementation is different anyway...
Mar 20 2018
On Monday, 19 March 2018 at 18:39:30 UTC, KytoDragon wrote:I currently have a problem i don't know how to fix: Programms compiled in D (either compiler) have the annoying property that they absorb all windows seh-exceptions, print the error code and terminate the process. For example, the following programm will print "Program exited with code -1073741819" and exit: module test.Test; void main() { *cast(int*)cast(void*)0 = 1; } But what I expected was the following: https://imgur.com/LH8gUtt (translated for your language) The problem with this is, that this "feature" somehow even manages to catch windows fail-fast exceptions, which are supossed to bypass all exception handling (and debuggers!) and go directly to WER (Windows Error Reporting). This makes it impossible to debug these types of exceptions, as D nearly silently swallows them. My questions are now: What exactly causes this behaviour? (e.q. which part of druntime/phobos/dmd/ldc2) Is there a way to disable that? Has anybody an other solution?I'm not familiar with the neither the implementation details nor why it swallows all SEH exceptions, but anyway here's a few starting points: * most (all?) of the exception handling support code is in the druntime 'src/rt/' folder - look for files starting with 'deh', e.g. https://github.com/dlang/druntime/blob/master/src/rt/deh_win32.d for dmd -m32 (Digital Mars C runtime) and https://github.com/dlang/druntime/blob/master/src/rt/deh_win64_posix.d for the rest of the dmd platform support * additionally, LDC has a modified or completely reworked version of this: https://github.com/ldc-developers/druntime/tree/ldc/src/rt * for example, for 1.7 LDC release there was significant work in this area, which among other things added C++ exception handling support: https://github.com/ldc-developers/ldc/pull/2405/files * If you see differences between the DMD and LDC behavior, the quickest way to get an answer is to post in their forums: https://forum.dlang.org/group/ldc, or on their issue tracker: https://github.com/ldc-developers/ldc/issues
Mar 19 2018