diff --git a/src/core/exception.d b/src/core/exception.d index 701dff2c30..bc43f01d4b 100644 --- a/src/core/exception.d +++ b/src/core/exception.d @@ -416,6 +416,21 @@ deprecated void setAssertHandler( AssertHandler h ) @trusted nothrow @nogc assertHandler = h; } +private __gshared bool assertEHEnabled = false; +extern(C) void _d_setAssertEHEnabled( bool enabled ) +{ + assertEHEnabled = enabled; +} + +private void defaultAssertHandler( string file, size_t line, string msg ) nothrow +{ + if ( assertEHEnabled ) + throw msg ? new AssertError( msg, file, line ) : new AssertError( file, line ); + + import core.internal.abort; + abort( file, line, "Assertion failure during runtime startup/teardown", + msg ? ": " : ".", msg ); +} /////////////////////////////////////////////////////////////////////////////// // Overridable Callbacks @@ -434,7 +449,7 @@ deprecated void setAssertHandler( AssertHandler h ) @trusted nothrow @nogc extern (C) void onAssertError( string file = __FILE__, size_t line = __LINE__ ) nothrow { if( _assertHandler is null ) - throw new AssertError( file, line ); + defaultAssertHandler( file, line, null ); _assertHandler( file, line, null); } @@ -452,7 +467,7 @@ extern (C) void onAssertError( string file = __FILE__, size_t line = __LINE__ ) extern (C) void onAssertErrorMsg( string file, size_t line, string msg ) nothrow { if( _assertHandler is null ) - throw new AssertError( msg, file, line ); + defaultAssertHandler( file, line, msg ); _assertHandler( file, line, msg ); } diff --git a/src/core/internal/abort.d b/src/core/internal/abort.d index d2d0eb8724..de5d94daff 100644 --- a/src/core/internal/abort.d +++ b/src/core/internal/abort.d @@ -5,6 +5,11 @@ module core.internal.abort; * code, and druntime is -release compiled. */ void abort(string msg, string filename = __FILE__, size_t line = __LINE__) @nogc nothrow @safe +{ + abort(filename, line, msg); +} + +void abort(string filename, size_t line, const(char)[][] msgs...) @nogc nothrow @safe { import core.stdc.stdlib: c_abort = abort; // use available OS system calls to print the message to stderr @@ -23,7 +28,7 @@ void abort(string msg, string filename = __FILE__, size_t line = __LINE__) @nogc auto h = (() @trusted => GetStdHandle(STD_ERROR_HANDLE))(); if(h == INVALID_HANDLE_VALUE) // attempt best we can to print the message - assert(0, msg); + assert(0, msgs[0]); void writeStr(const(char)[][] m...) @nogc nothrow @trusted { foreach(s; m) @@ -40,6 +45,7 @@ void abort(string msg, string filename = __FILE__, size_t line = __LINE__) @nogc UnsignedStringBuf strbuff; // write an appropriate message, then abort the program - writeStr("Aborting from ", filename, "(", line.unsignedToTempString(strbuff, 10), ") ", msg); + writeStr("Aborting from ", filename, "(", line.unsignedToTempString(strbuff, 10), "): "); + writeStr(msgs); c_abort(); } diff --git a/src/rt/dmain2.d b/src/rt/dmain2.d index 59f4b4ef4e..3441a56277 100644 --- a/src/rt/dmain2.d +++ b/src/rt/dmain2.d @@ -50,6 +50,7 @@ extern (C) void rt_moduleTlsDtor(); extern (C) void thread_joinAll(); extern (C) bool runModuleUnitTests(); extern (C) void _d_initMonoTime(); +extern (C) void _d_setAssertEHEnabled(bool enabled); version (OSX) { @@ -180,6 +181,7 @@ extern (C) int rt_init() initStaticDataGC(); lifetime_init(); rt_moduleCtor(); + _d_setAssertEHEnabled(true); rt_moduleTlsCtor(); return 1; } @@ -205,6 +207,7 @@ extern (C) int rt_term() { rt_moduleTlsDtor(); thread_joinAll(); + _d_setAssertEHEnabled(false); rt_moduleDtor(); gc_term(); finiSections(); diff --git a/test/exceptions/line_trace.exp b/test/exceptions/line_trace.exp index bec4cab697..f4faca6fc9 100644 --- a/test/exceptions/line_trace.exp +++ b/test/exceptions/line_trace.exp @@ -2,8 +2,8 @@ object.Exception@src/line_trace.d(17): exception ---------------- src/line_trace.d:17 void line_trace.f1() [ADDR] src/line_trace.d:5 _Dmain [ADDR] -src/rt/dmain2.d:472 _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [ADDR] -src/rt/dmain2.d:447 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [ADDR] -src/rt/dmain2.d:472 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [ADDR] -src/rt/dmain2.d:447 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [ADDR] -src/rt/dmain2.d:480 _d_run_main [ADDR] +src/rt/dmain2.d:475 _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [ADDR] +src/rt/dmain2.d:450 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [ADDR] +src/rt/dmain2.d:475 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [ADDR] +src/rt/dmain2.d:450 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [ADDR] +src/rt/dmain2.d:483 _d_run_main [ADDR]