Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Conversation

Marenz
Copy link

@Marenz Marenz commented Apr 7, 2016

This way you can do

extern extern (C) __gshared bool rt_trapExceptions;
static this ( )
{
        rt_trapExceptions = false;
}

to change the runtime behavior before main() is called.

@CyberShadow
Copy link
Member

Interesting, I thought rt_trapExceptions applies to unit tests / constructors as well. I think it should.

Perhaps update its documentation to reflect that it is now also settable from a static constructor?

@Marenz
Copy link
Author

Marenz commented Apr 7, 2016

Updated documentation for the variable

@Marenz
Copy link
Author

Marenz commented Apr 8, 2016

Updated unit test to account for changed line numbers

@Marenz
Copy link
Author

Marenz commented Apr 15, 2016

Ping.

@Marenz
Copy link
Author

Marenz commented May 1, 2016

Ping

@Marenz
Copy link
Author

Marenz commented May 1, 2016

It would be nice to get some feedback or at least any reaction to this.

@rainers
Copy link
Member

rainers commented May 3, 2016

I have not tried, but I don't think it works to set the flag in a ctor: there is an outer tryExec(&runAll) that will still catch excetions and errors (including those from static ctors).
I guess it might make sense together with applying the same flag to fibers, though.

@CyberShadow
Copy link
Member

I have not tried, but I don't think it works to set the flag in a ctor: there is an outer tryExec(&runAll) that will still catch excetions and errors (including those from static ctors).

That's what I thought too, but it appears to be (no longer?) so.

@Marenz Marenz force-pushed the runttrap branch 2 times, most recently from e9bf524 to c7df340 Compare May 5, 2016 15:04
@Marenz
Copy link
Author

Marenz commented May 5, 2016

You were right, it didn't work. I did test it and something did work before but I guess not this.
I updated the PR so that it is a runtime config option now. I tested it with

void main()
{
    assert(1==2);
}
dub build
Performing "debug" build using dmd for x86.
test ~master: building configuration "application"...
Linking...
(gdb) r
Starting program: /home/marenz/projekte/test/test 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/i686/cmov/libthread_db.so.1".
core.exception.AssertError@source/app.d(3): Assertion failure
----------------
??:? _d_assert [0x806654e]
??:? void app.__assert(int) [0x8066494]
source/app.d:3 _Dmain [0x806644c]
??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0x80668aa]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x80667ff]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x8066866]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x80667ff]
??:? _d_run_main [0x8066792]
??:? main [0x80664d3]
??:? __libc_start_main [0xb7d9ea62]
[Inferior 1 (process 28082) exited with code 01]
(gdb) bt
No stack.
(gdb) r --DRT-noTrapExceptions=1
Starting program: /home/marenz/projekte/test/test --DRT-noTrapExceptions=1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/i686/cmov/libthread_db.so.1".
uncaught exception
dwarfeh(224) fatal error

Program received signal SIGABRT, Aborted.
0xb7fdcd40 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7fdcd40 in __kernel_vsyscall ()
#1  0xb7db3367 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#2  0xb7db4a23 in __GI_abort () at abort.c:89
#3  0x08066a78 in _d_throwdwarf ()
#4  0x0806654f in _d_assert ()
#5  0x08066495 in app.__assert() ()
#6  0x0806644d in D main () at source/app.d:3
#7  0x080668ab in rt.dmain2._d_run_main() ()
#8  0x08066838 in rt.dmain2._d_run_main() ()
#9  0x08066867 in rt.dmain2._d_run_main() ()
#10 0x08066838 in rt.dmain2._d_run_main() ()
#11 0x08066793 in _d_run_main ()
#12 0x080664d4 in main ()

Or outside GDB:

➜  test  ./test --DRT-noTrapExceptions=1
uncaught exception
dwarfeh(224) fatal error
[1]    28317 abort (core dumped)  ./test --DRT-noTrapExceptions=1
➜  test  ./test                         
core.exception.AssertError@source/app.d(3): Assertion failure
----------------
??:? _d_assert [0x806654e]
??:? void app.__assert(int) [0x8066494]
source/app.d:3 _Dmain [0x806644c]
??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0x80668aa]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x80667ff]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x8066866]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x80667ff]
??:? _d_run_main [0x8066792]
??:? main [0x80664d3]
??:? __libc_start_main [0xb74a2a62]

@Marenz Marenz changed the title Allow changing of exc. trapping behavior from module c'tors Add runtime config option to change exception trapping behavior May 5, 2016
@Marenz
Copy link
Author

Marenz commented May 5, 2016

@MartinNowak trying a direct hilight

@adamdruppe
Copy link
Contributor

Yes, yes, yes, merge this!

BTW if it isn't merged, since it is an extern(C) variable, you can also redefine it yourself and instruct the linker to use your version instead of the druntime one. hacky sure but hey.

extern(C) __gshared bool rt_trapExceptions = false;

compile:
dmd test.d -L-zmuldefs -g

but this is a trivial change that has clear value, looks very good to me.

@dnadlinger
Copy link
Contributor

How do we test the command line switch?

@Marenz
Copy link
Author

Marenz commented May 6, 2016

@klickverbot I wrote it above already: you pass --DRT-noTrapExceptions=1 to your application (one of the ways) and any assert failure will cause a coredump now instead of just outputting the stack trace.

@dnadlinger
Copy link
Contributor

@Marenz: I realised that. What I was pointed out is that this PR is currently missing regression tests. Due to the nature of the feature, you'd probably need to add a new standalone test executable to test/.

@Marenz
Copy link
Author

Marenz commented May 6, 2016

Do you want to test the switch itself or just whether the runtime behaves correctly when the option is enabled?

@Marenz
Copy link
Author

Marenz commented May 6, 2016

I am asking because the parsing etc of that switch is all functionality that is already present.

@dnadlinger
Copy link
Contributor

I want something that breaks if the code part of this PR is reverted (well, except for the line numbers^^).

@Marenz
Copy link
Author

Marenz commented May 6, 2016

Will that test need to be cross-platform?

@@ -477,6 +474,13 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
result = (result == EXIT_SUCCESS) ? EXIT_FAILURE : result;
}

import rt.config : rt_configOption;

if (rt_configOption("noTrapExceptions") !is null)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest using options without negative: trapExceptions

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gladly, but that means the default will be changed, right? Is that acceptable @MartinNowak

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's not necessary (nor desirable, I think). Just make it default to 1, not 0.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Certainly not desirable :) It would mean that programs will segfault instead of showing an exception stack trace on uncaught exceptions by default.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have different definitions of "desirable", but sure, I see if I can change it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you're using the result of rt_configOption like a bool here... which means that --DRT-noTrapExceptions=1 and --DRT-noTrapExceptions=0 will both do the same thing. This is not ideal.

I looked to see if we have a precedent for this, and here is how #1798 added callStructDtorsDuringGC, also a boolean option:

extern (C) void lifetime_init()
{
// this is run before static ctors, so it is safe to modify immutables
import rt.config;
string s = rt_configOption("callStructDtorsDuringGC");
if (s != null)
cast() callStructDtorsDuringGC = s[0] == '1' || s[0] == 'y' || s[0] == 'Y';
else
cast() callStructDtorsDuringGC = true;
}

I suggest to parse this option in a similar way, which would also allow e.g. overriding the default behaviour of disabling rt_trapExceptions when running under a debugger on Windows. That also solves the "double negation" issue. If you're feeling up for it, refactoring the bool checks into a new function in the rt.config module, which also rejects invalid values, would be a bonus.

@adamdruppe
Copy link
Contributor

why is this still in limbo?

@CyberShadow
Copy link
Member

Looks good to me. @MartinNowak ?

Copy link
Member

@CyberShadow CyberShadow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Marenz Are you still up for this? Since apparently no one has any feedback, let's clean this up & merge it.

A changelog entry with an example of enabling this via the command-line or environment would be nice.

BTW, this is closely related to #1533 and #1673.

@wilzbach
Copy link
Contributor

Superseded by #2035

@wilzbach wilzbach closed this Jun 26, 2018
@leandro-lucarella-sociomantic
Copy link
Contributor

It is superseded even if the title of the new issue says is for the CLI but also via a similar trick in the source code, right?

@wilzbach
Copy link
Contributor

AFAICT this stagnated/orphaned PR was about allowing --DRT-noTrapExceptions=1 (or environment config) and #2035 is exactly about this too (just that a different naming was used).
__gshared bool rt_trapExceptions already exists in DRuntime.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Needs Rebase needs a `git rebase` performed Needs Work stalled
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants