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 }