1 module core.internal.abort; 2 3 /* 4 * Use instead of assert(0, msg), since this does not print a message for -release compiled 5 * code, and druntime is -release compiled. 6 */ 7 void abort(scope string msg, scope string filename = __FILE__, size_t line = __LINE__) @nogc nothrow @safe 8 { 9 import core.stdc.stdlib: c_abort = abort; 10 // use available OS system calls to print the message to stderr version(Posix)11 version (Posix) 12 { 13 import core.sys.posix.unistd: write; 14 static void writeStr(scope const(char)[][] m...) @nogc nothrow @trusted 15 { 16 foreach (s; m) 17 write(2, s.ptr, s.length); 18 } 19 } version(Windows)20 else version (Windows) 21 { 22 import core.sys.windows.winbase : GetStdHandle, STD_ERROR_HANDLE, WriteFile, INVALID_HANDLE_VALUE; 23 auto h = (() @trusted => GetStdHandle(STD_ERROR_HANDLE))(); 24 if (h == INVALID_HANDLE_VALUE) 25 { 26 // attempt best we can to print the message 27 28 /* Note that msg is scope. 29 * assert() calls _d_assert_msg() calls onAssertErrorMsg() calls _assertHandler() but 30 * msg parameter isn't scope and can escape. 31 * Give up and use our own immutable message instead. 32 */ 33 assert(0, "Cannot get stderr handle for message"); 34 } 35 void writeStr(scope const(char)[][] m...) @nogc nothrow @trusted 36 { 37 foreach (s; m) 38 { 39 assert(s.length <= uint.max); 40 WriteFile(h, s.ptr, cast(uint)s.length, null, null); 41 } 42 } 43 } 44 else 45 static assert(0, "Unsupported OS"); 46 47 import core.internal.string; 48 UnsignedStringBuf strbuff = void; 49 50 // write an appropriate message, then abort the program 51 writeStr("Aborting from ", filename, "(", line.unsignedToTempString(strbuff), ") ", msg); 52 c_abort(); 53 } 54