Skip to content
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

SIGSEGV 11 on ReleaseFast but not Debug #22455

Open
thuiop opened this issue Jan 9, 2025 · 3 comments
Open

SIGSEGV 11 on ReleaseFast but not Debug #22455

thuiop opened this issue Jan 9, 2025 · 3 comments
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@thuiop
Copy link

thuiop commented Jan 9, 2025

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

Compile the following code with -OReleaseFast to see it crashing

const std = @import("std");

fn next_secret(secret: usize) usize {
    var temp: usize = ((secret * 64) ^ secret) % 16777216;
    temp = ((temp / 32) ^ temp) % 16777216;
    temp = ((temp * 2048) ^ temp) % 16777216;
    return temp;
}

fn run(input: [:0]const u8) usize {
    var it = std.mem.splitScalar(u8, input, "\n"[0]);

    var results: [1048576]usize = [_]usize{0} ** 1048576;
    var is_done: [1048576]bool = [_]bool{false} ** 1048576;
    while (it.next()) |row| {
        @memset(&is_done, false);
        var secret: usize = std.fmt.parseInt(usize, row, 10) catch unreachable;
        var prev_price: i5 = @intCast(secret % 10);
        var last_4: u20 = 0;
        var i: usize = 0;
        for (0..2000) |_| {
            secret = next_secret(secret);
            const price: i5 = @intCast(secret % 10);
            const diff: i5 = price - prev_price;
            last_4 = (last_4 << 5) + @as(u5, @bitCast(diff));
            if (i >= 4) {
                if (!is_done[last_4]) {
                    results[last_4] += secret % 10;
                    is_done[last_4] = true;
                }
            } else {
                i += 1;
            }
            prev_price = price;
        }
    }
    return std.mem.max(usize, &results);
}

pub fn main() !void {
    _ = run("1");
}

However, it does not crash when in Debug.

System: Nixos 24.05
Kernel: 6.6.41
Architecture: x86_64

Expected Behavior

I am really unsure of why it crashes; I stumbled upon it during the Advent of Code. What I investigated:

  • Originally I allocated results and is_done dynamically, and it worked fine. It also works fine when only is_done is a literal.
  • Removing the results[last_4] += secret % 10; line removes the crash. However, debug printing showed that last_4 stays within the bounds of results as I expected.
  • The program seems to crash instantly; even a print at the very beginning does not appear.
  • I dared not remove more code when submitting the issue just in case, but the crash still happens even when changing next_secret to a dummy function.
  • For some reason, replacing all the usize with u32 also removed the crash.

Maybe there is a good reason for this, but I am not seeing it. I thought it might be something related to the size of the allocated array but this does not explain why it only happens in ReleaseFast mode.

Thanks in advance.

@thuiop thuiop added the bug Observed behavior contradicts documented or intended behavior label Jan 9, 2025
@alexrp
Copy link
Member

alexrp commented Jan 9, 2025

Without having looked at the code in detail: That's... a lot of data to put on the stack. Could well be a stack overflow. I suggest you try to move it to global variables and see if the issue still reproduces.

@nektro
Copy link
Contributor

nektro commented Jan 9, 2025

yeah just the two arrays are using 9,437,184 bytes of stack

@thuiop
Copy link
Author

thuiop commented Jan 9, 2025

Without having looked at the code in detail: That's... a lot of data to put on the stack. Could well be a stack overflow. I suggest you try to move it to global variables and see if the issue still reproduces.

Indeed, moving them to global variables seems to solve the issue, so I guess it is indeed the size of the array. However, why does it work in Debug mode?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

3 participants