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

Gracefully handle assertion errors during runtime startup/teardown #1651

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/core/exception.d
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}

Expand All @@ -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 );
}

Expand Down
10 changes: 8 additions & 2 deletions src/core/internal/abort.d
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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();
}
3 changes: 3 additions & 0 deletions src/rt/dmain2.d
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -180,6 +181,7 @@ extern (C) int rt_init()
initStaticDataGC();
lifetime_init();
rt_moduleCtor();
_d_setAssertEHEnabled(true);
rt_moduleTlsCtor();
return 1;
}
Expand All @@ -205,6 +207,7 @@ extern (C) int rt_term()
{
rt_moduleTlsDtor();
thread_joinAll();
_d_setAssertEHEnabled(false);
rt_moduleDtor();
gc_term();
finiSections();
Expand Down
10 changes: 5 additions & 5 deletions test/exceptions/line_trace.exp
Original file line number Diff line number Diff line change
Expand Up @@ -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]