Skip to content

Panic on stack overflow/segfault in debug mode. #7371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
lolbinarycat opened this issue Dec 9, 2020 · 5 comments
Open

Panic on stack overflow/segfault in debug mode. #7371

lolbinarycat opened this issue Dec 9, 2020 · 5 comments
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. standard library This issue involves writing Zig code for the standard library.
Milestone

Comments

@lolbinarycat
Copy link

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 and zig 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".

@LemonBoy
Copy link
Contributor

LemonBoy commented Dec 9, 2020

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?

@lolbinarycat
Copy link
Author

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.

@LemonBoy
Copy link
Contributor

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.

@Vexu Vexu added standard library This issue involves writing Zig code for the standard library. enhancement Solving this issue will likely involve adding new logic or components to the codebase. labels Dec 11, 2020
@Vexu Vexu added this to the 0.8.0 milestone Dec 11, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 Jun 4, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 0.11.0 Nov 24, 2021
@nektro
Copy link
Contributor

nektro commented Oct 20, 2022

proof of concept for posix https://gist.github.com/nektro/c7a3a3232e6dcb409664ed784be73529

@VisenDev
Copy link

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,```

@andrewrk andrewrk removed the error message This issue points out an error message that is unhelpful and should be improved. label Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. standard library This issue involves writing Zig code for the standard library.
Projects
None yet
Development

No branches or pull requests

6 participants