Open lolbinarycat opened 3 years ago
Currently it seems like we are doing nothing about segfaults/stack overflows.
A segfault handler is installed by default and we emit stack probes on i386/x86_64, I wouldn't say we're not not doing anything. What code are you running that doesn't give you any stack trace?
fn stackOverflow() void {
var x: [200]usize = undefined;
@call(.{ .modifier = .never_tail }, stackOverflow, .{});
}
pub fn main() void {
stackOverflow();
}
zig has no output and returns 1. building an executable and running it results in a shell-specific message about a segmentation fault/SIGSEGV
zig version is 0.6.0+006b780d4
, I'll try it with a newer version after this.
I see. The overflow protection kicks in but once it tries to print out a nice message, stating that something went wrong, it dies because there's no more stack space.
The solution is simple yet convoluted, using sigaltstack
during the startup phase (and for each thread we spawn).
The obvious downside is the need for more memory, a quick test showed we need something like 32kb of alternate stack for each N+1 active threads.
proof of concept for posix https://gist.github.com/nektro/c7a3a3232e6dcb409664ed784be73529
This stack segmentation fault is also happening when attempting to parse large json strings using std.json.parseFromSlice
Example code causing a segfault. level.Level
is a large struct.
const string = try std.fs.cwd().readFileAlloc(a, path, 100000);
if (!try std.json.validate(a, string)) {
return error.invalid_json;
}
const parsed = try std.json.parseFromSlice(level.Level, a, string, .{});
Process 13483 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7ff7bf6ff500)
frame #0: 0x0000000100164c54 dev`__zig_probe_stack at stack_probe.zig:53:13 [opt]
50 switch (arch) {
51 .x86_64 => {
52 // %rax = probe length, %rsp = stack pointer
-> 53 asm volatile (
54 \\ push %%rcx
55 \\ mov %%rax, %%rcx
56 \\ cmp $0x1000,%%rcx
warning: dev was compiled with optimization - stepping may behave oddly; variables may not be available.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7ff7bf6ff500)
* frame #0: 0x0000000100164c54 dev`__zig_probe_stack at stack_probe.zig:53:13 [opt]
frame #1: 0x00000001000a0f89 dev`json.static.innerParse__anon_16225(allocator=mem.Allocator @ 0x00007ff7bfc75588, source=0x00007ff7bfd02868, options=json.static.ParseOptions @ 0x00007ff7bfbe8260) at static.zig:361:63
frame #2: 0x0000000100088e4e dev`json.static.innerParse__anon_15817(allocator=mem.Allocator @ 0x00007ff7bfc75588, source=0x00007ff7bfd02868, options=json.static.ParseOptions @ 0x00007ff7bfbe8260) at static.zig:361:63
frame #3: 0x000000010006fbf0 dev`json.static.parseFromTokenSourceLeaky__anon_14537(allocator=mem.Allocator @ 0x00007ff7bfc75588, scanner_or_reader=0x00007ff7bfd02868, options=json.static.ParseOptions @ 0x00000001001d3980) at static.zig:140:33
frame #4: 0x00000001000409c4 dev`json.static.parseFromTokenSource__anon_11798(allocator=mem.Allocator @ 0x00007ff7bfeff338, scanner_or_reader=0x00007ff7bfd02868, options=json.static.ParseOptions @ 0x00000001001d3980) at static.zig:107:49
frame #5: 0x000000010002c19f dev`json.static.parseFromSlice__anon_10958(allocator=mem.Allocator @ 0x00007ff7bfeff338,```
I'm not sure whether this is a bug report or a proposal because this seems like a fairly basic feature. Currently it seems like we are doing nothing about segfaults/stack overflows. This is alright if you are running the compiled program from a terminal, as all terminals I've used will tell you if a program segfaults, but
zig run
gives no indication other than a nonzero exit code. This makes it very difficult to figure out what's going on if you get infinite recursion andzig run
exits with no output.I don't know if it's feasible to distinguish a stack overflow from other segfaults or to provide a stack trace, but I do know that it's possible to at least install a signal handler, or to make
zig run
print "Segmentation fault".