1 module crash_handler; 2 3 version (unittest) 4 { 5 version (linux) 6 enum BacktraceHandler = true; 7 else version (OSX) 8 enum BacktraceHandler = true; 9 else 10 enum BacktraceHandler = false; 11 12 static if (BacktraceHandler) 13 { 14 extern (C) int backtrace(void** buffer, int size) nothrow @nogc @system; 15 extern (C) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd) nothrow @nogc @system; 16 17 extern (C) void backtrace_handler(int sig) nothrow @nogc @system 18 { 19 import core.sys.posix.stdlib : exit; 20 import core.sys.posix.stdio : fprintf, stderr; 21 22 void*[100] buffer; 23 auto size = backtrace(buffer.ptr, cast(int) buffer.length); 24 25 fprintf(stderr, "Error: signal %d:\n", sig); 26 backtrace_symbols_fd(buffer.ptr, size, 2); 27 exit(-sig); 28 } 29 30 void regsiterErrorHandlers() 31 { 32 import core.sys.posix.stdio : fprintf, stderr; 33 import core.sys.posix.signal : signal, SIGABRT, SIGALRM, SIGILL, SIGINT, 34 SIGKILL, SIGPIPE, SIGSEGV, SIGTRAP; 35 36 static foreach (sig; [ 37 SIGABRT, SIGALRM, SIGILL, SIGINT, SIGKILL, SIGPIPE, SIGSEGV, SIGTRAP 38 ]) 39 signal(sig, &backtrace_handler); 40 41 fprintf(stderr, "Registered backtrace signal handlers\n"); 42 } 43 } 44 } 45 46 version (unittest) 47 { 48 static if (BacktraceHandler) 49 { 50 shared static this() 51 { 52 regsiterErrorHandlers(); 53 } 54 } 55 }