mirror of
https://github.com/ziglang/zig.git
synced 2024-11-30 09:02:32 +00:00
refactor stack trace code to remove global state
This commit is contained in:
parent
60b2031831
commit
3b3649b86f
@ -9,7 +9,6 @@ const macho = std.macho;
|
||||
const ArrayList = std.ArrayList;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub var stack_trace_start_address: ?usize = null;
|
||||
pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator;
|
||||
|
||||
/// Tries to write to stderr, unbuffered, and ignores any error returned.
|
||||
@ -46,13 +45,13 @@ pub fn getSelfDebugInfo() !&ElfStackTrace {
|
||||
}
|
||||
|
||||
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
|
||||
pub fn dumpCurrentStackTrace() void {
|
||||
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
||||
const stderr = getStderrStream() catch return;
|
||||
const debug_info = getSelfDebugInfo() catch |err| {
|
||||
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
|
||||
return;
|
||||
};
|
||||
writeCurrentStackTrace(stderr, global_allocator, debug_info, stderr_file.isTty()) catch |err| {
|
||||
writeCurrentStackTrace(stderr, global_allocator, debug_info, stderr_file.isTty(), start_addr) catch |err| {
|
||||
stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
|
||||
return;
|
||||
};
|
||||
@ -97,10 +96,18 @@ pub fn assertOrPanic(ok: bool) void {
|
||||
}
|
||||
}
|
||||
|
||||
var panicking: u8 = 0; // TODO make this a bool
|
||||
/// This is the default panic implementation.
|
||||
pub fn panic(comptime format: []const u8, args: ...) noreturn {
|
||||
@setCold(true);
|
||||
const first_trace_addr = @ptrToInt(@returnAddress());
|
||||
panicExtra(null, first_trace_addr, format, args);
|
||||
}
|
||||
|
||||
var panicking: u8 = 0; // TODO make this a bool
|
||||
|
||||
pub fn panicExtra(trace: ?&const builtin.StackTrace, first_trace_addr: ?usize,
|
||||
comptime format: []const u8, args: ...) noreturn
|
||||
{
|
||||
@setCold(true);
|
||||
|
||||
if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) {
|
||||
// Panicked during a panic.
|
||||
@ -110,25 +117,12 @@ pub fn panic(comptime format: []const u8, args: ...) noreturn {
|
||||
// which first called panic can finish printing a stack trace.
|
||||
os.abort();
|
||||
}
|
||||
|
||||
const stderr = getStderrStream() catch os.abort();
|
||||
stderr.print(format ++ "\n", args) catch os.abort();
|
||||
dumpCurrentStackTrace();
|
||||
|
||||
os.abort();
|
||||
}
|
||||
|
||||
pub fn panicWithTrace(trace: &const builtin.StackTrace, comptime format: []const u8, args: ...) noreturn {
|
||||
@setCold(true);
|
||||
|
||||
if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) {
|
||||
// See TODO in above function
|
||||
os.abort();
|
||||
if (trace) |t| {
|
||||
dumpStackTrace(t);
|
||||
}
|
||||
const stderr = getStderrStream() catch os.abort();
|
||||
stderr.print(format ++ "\n", args) catch os.abort();
|
||||
dumpStackTrace(trace);
|
||||
dumpCurrentStackTrace();
|
||||
dumpCurrentStackTrace(first_trace_addr);
|
||||
|
||||
os.abort();
|
||||
}
|
||||
@ -161,18 +155,17 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var,
|
||||
}
|
||||
|
||||
pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator,
|
||||
debug_info: &ElfStackTrace, tty_color: bool) !void
|
||||
debug_info: &ElfStackTrace, tty_color: bool, start_addr: ?usize) !void
|
||||
{
|
||||
const AddressState = union(enum) {
|
||||
NotLookingForStartAddress,
|
||||
LookingForStartAddress: usize,
|
||||
FoundStartAddress,
|
||||
};
|
||||
// TODO: I want to express like this:
|
||||
//var addr_state = if (stack_trace_start_address) |addr| AddressState { .LookingForStartAddress = addr }
|
||||
//var addr_state = if (start_addr) |addr| AddressState { .LookingForStartAddress = addr }
|
||||
// else AddressState.NotLookingForStartAddress;
|
||||
var addr_state: AddressState = undefined;
|
||||
if (stack_trace_start_address) |addr| {
|
||||
if (start_addr) |addr| {
|
||||
addr_state = AddressState { .LookingForStartAddress = addr };
|
||||
} else {
|
||||
addr_state = AddressState.NotLookingForStartAddress;
|
||||
@ -183,15 +176,14 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator,
|
||||
const return_address = *@intToPtr(&const usize, fp + @sizeOf(usize));
|
||||
|
||||
switch (addr_state) {
|
||||
AddressState.NotLookingForStartAddress => continue,
|
||||
AddressState.NotLookingForStartAddress => {},
|
||||
AddressState.LookingForStartAddress => |addr| {
|
||||
if (return_address == addr) {
|
||||
addr_state = AddressState.FoundStartAddress;
|
||||
addr_state = AddressState.NotLookingForStartAddress;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
},
|
||||
AddressState.FoundStartAddress => {},
|
||||
}
|
||||
try printSourceAtAddress(debug_info, out_stream, return_address);
|
||||
}
|
||||
|
@ -14,11 +14,8 @@ pub fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) noreturn
|
||||
while (true) {}
|
||||
},
|
||||
else => {
|
||||
std.debug.stack_trace_start_address = @ptrToInt(@returnAddress());
|
||||
if (error_return_trace) |trace| {
|
||||
std.debug.panicWithTrace(trace, "{}", msg);
|
||||
}
|
||||
std.debug.panic("{}", msg);
|
||||
const first_trace_addr = @ptrToInt(@returnAddress());
|
||||
std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user