authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-15 20:15:19-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-16 03:17:15-04:00
logcaefaf781e22a7b053426621719a6f1d0f69d7cb
treed77cc3e0e7841a83d6dbfa438a6f256396ff7c39
parent88724217dd1e1fe4b20fed27c8a662b66df55088

std.debug: dumpStackTrace & friends use DirectAllocator

this has the downside of failing to print a stack trace when the system is out of memory (maybe we could add a FallbackAllocator which tries DirectAllocator and falls back on the 200KB preallocated buffer). but for the more common use case when the system is not out of memory, but the debug info cannot fit in std.debug.global_allocator, now stack traces will work. this is the case for the self hosted compiler.

1 files changed, 20 insertions(+), 5 deletions(-)

std/debug/index.zig+20-5
......@@ -38,7 +38,7 @@ pub fn getSelfDebugInfo() !&ElfStackTrace {
3838 if (self_debug_info) |info| {
3939 return info;
4040 } else {
41 const info = try openSelfDebugInfo(global_allocator);
41 const info = try openSelfDebugInfo(getDebugInfoAllocator());
4242 self_debug_info = info;
4343 return info;
4444 }
......@@ -51,7 +51,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
5151 stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
5252 return;
5353 };
54 writeCurrentStackTrace(stderr, global_allocator, debug_info, stderr_file.isTty(), start_addr) catch |err| {
54 writeCurrentStackTrace(stderr, getDebugInfoAllocator(), debug_info, stderr_file.isTty(), start_addr) catch |err| {
5555 stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
5656 return;
5757 };
......@@ -64,7 +64,7 @@ pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) void {
6464 stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
6565 return;
6666 };
67 writeStackTrace(stack_trace, stderr, global_allocator, debug_info, stderr_file.isTty()) catch |err| {
67 writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, stderr_file.isTty()) catch |err| {
6868 stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
6969 return;
7070 };
......@@ -592,8 +592,8 @@ fn getString(st: &ElfStackTrace, offset: u64) ![]u8 {
592592}
593593
594594fn readAllocBytes(allocator: &mem.Allocator, in_stream: var, size: usize) ![]u8 {
595 const buf = try global_allocator.alloc(u8, size);
596 errdefer global_allocator.free(buf);
595 const buf = try allocator.alloc(u8, size);
596 errdefer allocator.free(buf);
597597 if ((try in_stream.read(buf)) < size) return error.EndOfFile;
598598 return buf;
599599}
......@@ -1126,6 +1126,21 @@ fn readILeb128(in_stream: var) !i64 {
11261126 }
11271127}
11281128
1129/// This should only be used in temporary test programs.
11291130pub const global_allocator = &global_fixed_allocator.allocator;
11301131var global_fixed_allocator = std.heap.FixedBufferAllocator.init(global_allocator_mem[0..]);
11311132var global_allocator_mem: [100 * 1024]u8 = undefined;
1133
1134
1135// TODO make thread safe
1136var debug_info_allocator: ?&mem.Allocator = null;
1137var debug_info_direct_allocator: std.heap.DirectAllocator = undefined;
1138var debug_info_arena_allocator: std.heap.ArenaAllocator = undefined;
1139fn getDebugInfoAllocator() &mem.Allocator {
1140 if (debug_info_allocator) |a| return a;
1141
1142 debug_info_direct_allocator = std.heap.DirectAllocator.init();
1143 debug_info_arena_allocator = std.heap.ArenaAllocator.init(&debug_info_direct_allocator.allocator);
1144 debug_info_allocator = &debug_info_arena_allocator.allocator;
1145 return &debug_info_arena_allocator.allocator;
1146}