DOOM-fire-zig icon indicating copy to clipboard operation
DOOM-fire-zig copied to clipboard

'zig build run' starts, then fails with index out of bounds

Open hencomb opened this issue 10 months ago • 5 comments

zig version 0.13.0

MacOS 15.3

Tested on iTerm2 and Ghostty.

Build succeeds, opens the splash screen, then on Enter it crashes as below.

Error:

thread 9473501 panic: index out of bounds: index 316659348809645, len 10406
/Users/h/DOOM-fire-zig/src/main.zig:690:39: 0x10159e0cd in showDoomFire (DOOM-fire)
                            screen_buf[spread_dst - FIRE_W] = spread_px - (spread_rnd_idx & 1);
                                      ^
/Users/h/DOOM-fire-zig/src/main.zig:748:21: 0x101594d83 in main (DOOM-fire)
    try showDoomFire();
                    ^
/usr/local/Cellar/zig/0.13.0/lib/zig/std/start.zig:524:37: 0x1015949db in main (DOOM-fire)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x7ff80ae162cc in ??? (???)
Unwind information for `???:0x7ff80ae162cc` was not available, trace may be incomplete

???:?:?: 0x0 in ??? (???)
run
└─ run DOOM-fire failure
error: the following command terminated unexpectedly:
/Users/h/DOOM-fire-zig/zig-out/bin/DOOM-fire
Build Summary: 3/5 steps succeeded; 1 failed (disable with --summary none)
run transitive failure
└─ run DOOM-fire failure
error: the following build command failed with exit code 1:
/Users/h/DOOM-fire-zig/.zig-cache/o/4266a87667ea93b0206d11aa6def2c86/build /usr/local/Cellar/zig/0.13.0/bin/zig /Users/h/DOOM-fire-zig /Users/h/DOOM-fire-zig/.zig-cache /Users/h/.cache/zig --seed 0xac79a0d1 -Z889d2205159e4c50 run

hencomb avatar Feb 06 '25 08:02 hencomb

Do you have the most recent commit? Could you check real quick?

DOOM-fire-zig % git rev-parse HEAD
7fe99f28c33c27a6a726ed8a18d9afcb45d5a5f4

I am not seeing this issue - MacOS 15.3; zig 0.13; alacritty.

thread 9473501 panic: index out of bounds: index 316659348809645, len 10406

I have seen this when emulating Ubuntu via Multipass on MacOS, in debug mode; and it's a tough one to pin down as pulling DOOM-Fire-zig into lldb...the issue doesn't happen. Nor does it happen in release.

const-void avatar Feb 08 '25 14:02 const-void

Mac ~/DOOM-fire-zig% git rev-parse HEAD 7fe99f28c33c27a6a726ed8a18d9afcb45d5a5f4

Yup.

Let me know if there's something I can try to narrow this down for you.

Cheers

On Sat, 8 Feb 2025 at 16:43, const-void @.***> wrote:

Do you have the most recent commit? Could you check real quick?

DOOM-fire-zig % git rev-parse HEAD 7fe99f28c33c27a6a726ed8a18d9afcb45d5a5f4

I am not seeing this issue - MacOS 15.3; zig 0.13; alacritty.

thread 9473501 panic: index out of bounds: index 316659348809645, len 10406

I have seen this when emulating Ubuntu via Multipass on MacOS, in debug mode; and it's a tough one to pin down as pulling DOOM-Fire-zig into lldb...the issue doesn't happen. Nor does it happen in release.

— Reply to this email directly, view it on GitHub https://github.com/const-void/DOOM-fire-zig/issues/26#issuecomment-2645747584, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKVLMFFUMNFBV2EHRI3FHT32OYJXNAVCNFSM6AAAAABWS6IR22VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMNBVG42DONJYGQ . You are receiving this because you authored the thread.Message ID: @.***>

hencomb avatar Feb 10 '25 07:02 hencomb

Yup.

Thank you for confirming.

It appears to be an overflow puzzler. If you try compiling in release mode (are you?), it may go away; if you run via a debugger/lldb, it may also not occur.

Overflow issues in one build mode vs another are usually signs of the issue being a memory boundary problem; given DOOM-fire-zig is a straight forward single threaded process...that blows my mind.

Fault

ERROR: thread** 9473501 panic: index out of bounds: index 316659348809645, len 10406

The index value reads like an integer overflow error, as if a decrement 'wrapped' the value around to the maximum value. But how?

Code Analysis

Below is where the fault occurs: screen_buf[spread_dst - FIRE_W] = spread_px - (spread_rnd_idx & 1);

The context of the error, with my comments below.

...
// x = column, starting with the first column
// y = row, starting with the top row

// We iterate through each column of the width of our terminal, a row at a time. 
doFire_idx = doFire_y * FIRE_W + doFire_x; // convert 2d Point (x,y) to  1D array index

...
spread_rnd_idx = rand.intRangeAtMost(u8, 0, 3);  // roll 1d4: 0-3.
if (doFire_idx >= (spread_rnd_idx + 1)) { //bound check...make sure our x,y > 1d4+1
  // we are going to move the fire to a new spot
  spread_dst = doFire_idx - spread_rnd_idx + 1;   //new destination = current destination - (1d4+1)
} else {
  spread_dst = doFire_idx; //the first four characters of the fire never move.
 }

if (spread_dst >= FIRE_W) { //are we moving fire after the second row, call this check "A"
   if (spread_px > (spread_rnd_idx & 1)) { //boundary check  "B"
    //
    //-----
    //
    screen_buf[spread_dst - FIRE_W] = spread_px - (spread_rnd_idx & 1); // <---- BOOM
    // ^^^ BUT we specifically checked spread_dst - FIRE_W in A...how can this be overflow???
    //
    // FIRE_W = u64
    // spread_dst = u64
    // 
    // we specifically check to make sure that spread_dst >= FIRE_W, thus 
    // on paper, spread_dst should never be ... less than zero?  So how does it overflow?
    //
    // ----
    ///
  } else {
    screen_buf[spread_dst - FIRE_W] = 0;
  }
}

Similar but different

In the past, in a different but similar issue, when we printed out values, the values didn't indicate that there could be a problem. And yet, even when all the values were aligned, KABOOM...just like what you experienced!

https://github.com/const-void/DOOM-fire-zig/issues/14#issuecomment-2575433958

What is good is that you have found the issue with a "bare metal" Mac. In contrast, I experienced a massive emulation tier.

I am at a loss at this point, and I am hopeful it will be magically fixed with the new zig 0.14 release (sometime in 2025, now March). But I am not super confident.

const-void avatar Feb 15 '25 14:02 const-void

Thanks for taking time to look at this.

I wish I had more time to learn zig and help out... this kind of issue would drive me nuts. Reminds me of a SunOS C compiler bug in the mid-90s, where in frustration I compiled an early version of GCC (2.7 or thereabouts) bootstrapped with an even earlier gcc binary, and the problem went away.

/Edit: not saying it's definitely a bug in the zig compiler, but hey.

hencomb avatar Feb 17 '25 07:02 hencomb

Overflow issues can be tricky - a boundary shatters ... here .... which percolates over ... there ... which is manifested randomly in a loop when a specific cell of memory the compiler presumes to be in one condition is actually in a very different condition. In the days of C, a shared object gets updated with a memory boundary fault, that is then manifested several layers away in a totally unrelated executable code-wise.

Could it be LibC on Mac OS? Could it be a problem with defer? Debugging is another tell, when I simulated Ubuntu on Mac OS, in lldb, the kaboom went away entirely. When I printed to std err and logged the std error to file, the kaboom went away.

Could it be the compiler? The std lib? It could be those as well. Is there an async element I am not tracking?

The only sure way I know to debug, is to brute force and dump memory to file at regular intervals, perhaps even line after line of code, then on explosion...examine that location in memory inside each dump until the kaboom can be traced to a compiler activity...reverse engineer that assembler to a line of code and there may be enough clue to determine the root cause.

I doubt myself first; zig is not clear to me, to be honest. So it is highly likely I am misunderstanding how zig manages memory, and doing something, somewhere, that is zapping a value inadvertently, which later manifests in a loop that really has very little to do with memory management.

const-void avatar Feb 21 '25 12:02 const-void