| ... | @@ -41,10 +41,21 @@ fn getStderrStream() -> %&io.OutStream { | ... | @@ -41,10 +41,21 @@ fn getStderrStream() -> %&io.OutStream { |
| 41 | } | 41 | } |
| 42 | } | 42 | } |
| 43 | | 43 | |
| | 44 | var self_debug_info: ?&ElfStackTrace = null; |
| | 45 | pub fn getSelfDebugInfo() -> %&ElfStackTrace { |
| | 46 | if (self_debug_info) |info| { |
| | 47 | return info; |
| | 48 | } else { |
| | 49 | const info = try openSelfDebugInfo(global_allocator); |
| | 50 | self_debug_info = info; |
| | 51 | return info; |
| | 52 | } |
| | 53 | } |
| | 54 | |
| 44 | /// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned. | 55 | /// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned. |
| 45 | pub fn dumpCurrentStackTrace() { | 56 | pub fn dumpCurrentStackTrace() { |
| 46 | const stderr = getStderrStream() catch return; | 57 | const stderr = getStderrStream() catch return; |
| 47 | const debug_info = openSelfDebugInfo(global_allocator) catch |err| { | 58 | const debug_info = getSelfDebugInfo() catch |err| { |
| 48 | stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return; | 59 | stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return; |
| 49 | return; | 60 | return; |
| 50 | }; | 61 | }; |
| ... | @@ -58,7 +69,7 @@ pub fn dumpCurrentStackTrace() { | ... | @@ -58,7 +69,7 @@ pub fn dumpCurrentStackTrace() { |
| 58 | /// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned. | 69 | /// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned. |
| 59 | pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) { | 70 | pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) { |
| 60 | const stderr = getStderrStream() catch return; | 71 | const stderr = getStderrStream() catch return; |
| 61 | const debug_info = openSelfDebugInfo(global_allocator) catch |err| { | 72 | const debug_info = getSelfDebugInfo() catch |err| { |
| 62 | stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return; | 73 | stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return; |
| 63 | return; | 74 | return; |
| 64 | }; | 75 | }; |
| ... | @@ -119,6 +130,20 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn { | ... | @@ -119,6 +130,20 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn { |
| 119 | os.abort(); | 130 | os.abort(); |
| 120 | } | 131 | } |
| 121 | | 132 | |
| | 133 | pub fn panicWithTrace(trace: &const builtin.StackTrace, comptime format: []const u8, args: ...) -> noreturn { |
| | 134 | if (panicking) { |
| | 135 | os.abort(); |
| | 136 | } else { |
| | 137 | panicking = true; |
| | 138 | } |
| | 139 | const stderr = getStderrStream() catch os.abort(); |
| | 140 | stderr.print(format ++ "\n", args) catch os.abort(); |
| | 141 | dumpStackTrace(trace); |
| | 142 | dumpCurrentStackTrace(); |
| | 143 | |
| | 144 | os.abort(); |
| | 145 | } |
| | 146 | |
| 122 | const GREEN = "\x1b[32;1m"; | 147 | const GREEN = "\x1b[32;1m"; |
| 123 | const WHITE = "\x1b[37;1m"; | 148 | const WHITE = "\x1b[37;1m"; |
| 124 | const DIM = "\x1b[2m"; | 149 | const DIM = "\x1b[2m"; |