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

Unable to run on macOS #10

Closed
Chriscbr opened this issue Jul 4, 2024 · 3 comments
Closed

Unable to run on macOS #10

Chriscbr opened this issue Jul 4, 2024 · 3 comments

Comments

@Chriscbr
Copy link

Chriscbr commented Jul 4, 2024

Zig verison: 0.13.0
macOS version: 14.5 (64-bit)

When trying to run the project I initially got some build errors, so I applied a few patches:

diff --git a/build.zig b/build.zig
index 175bc4f..0efeb5a 100644
--- a/build.zig
+++ b/build.zig
@@ -9,11 +9,11 @@ pub fn build(b: *std.Build) void {
 
     // Standard release options allow the person running `zig build` to select
     // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
-    const optimize = b.standardOptimizeOption(.{});
+    const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = std.builtin.OptimizeMode.Debug });
 
     const exe = b.addExecutable(.{
         .name = "DOOM-fire",
-        .root_source_file = .{ .path = "src/main.zig" },
+        .root_source_file = .{ .cwd_relative = "src/main.zig" },
         .target = target,
         .optimize = optimize,
     });
@@ -32,7 +32,7 @@ pub fn build(b: *std.Build) void {
 
     const exe_tests = b.addTest(.{
         .name = "exe_tests",
-        .root_source_file = .{ .path = "src/main.zig" },
+        .root_source_file = .{ .cwd_relative = "src/main.zig" },
         .target = target,
         .optimize = optimize,
     });
diff --git a/src/main.zig b/src/main.zig
index 1d8379c..482b286 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -60,7 +60,7 @@ pub fn initRNG() !void {
     //rnd setup -- https://ziglearn.org/chapter-2/#random-numbers
     var prng = std.rand.DefaultPrng.init(blk: {
         var seed: u64 = undefined;
-        try std.os.getrandom(std.mem.asBytes(&seed));
+        try std.posix.getrandom(std.mem.asBytes(&seed));
         break :blk seed;
     });
     rand = prng.random();
@@ -151,12 +151,10 @@ pub fn initColor() void {
 // defer freeColor(); just too lazy right now.
 
 //get terminal size given a tty
-pub fn getTermSz(tty: std.os.fd_t) !TermSz {
+pub fn getTermSz(tty: std.posix.fd_t) !TermSz {
     if (builtin.os.tag == .windows) {
         var info: win32.CONSOLE_SCREEN_BUFFER_INFO = undefined;
-        if (0 == win32.GetConsoleScreenBufferInfo(tty, &info)) switch (
-            std.os.windows.kernel32.GetLastError()
-        ) {
+        if (0 == win32.GetConsoleScreenBufferInfo(tty, &info)) switch (std.os.windows.kernel32.GetLastError()) {
             else => |e| return std.os.windows.unexpectedError(e),
         };
         return TermSz{
@@ -165,12 +163,12 @@ pub fn getTermSz(tty: std.os.fd_t) !TermSz {
         };
     }
     var winsz = c.winsize{ .ws_col = 0, .ws_row = 0, .ws_xpixel = 0, .ws_ypixel = 0 };
-    const rv = std.os.system.ioctl(tty, TIOCGWINSZ, @intFromPtr(&winsz));
-    const err = std.os.errno(rv);
+    const rv = std.os.linux.ioctl(tty, TIOCGWINSZ, @intFromPtr(&winsz));
+    const err = std.posix.errno(rv);
     if (rv == 0) {
         return TermSz{ .height = winsz.ws_row, .width = winsz.ws_col };
     } else {
-        return std.os.unexpectedErrno(err);
+        return std.posix.unexpectedErrno(err);
     }
 }
 
@@ -207,7 +205,7 @@ pub fn pause() void {
     if (b == 'q') {
         //exit cleanly
         complete();
-        std.os.exit(0);
+        std.process.exit(0);
     }
 }

But even after this, when I ran zig build run I got an error running the binary:

run
└─ run DOOM-fire failure
error: the following command terminated unexpectedly:
/Users/rybickic/Developer/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/rybickic/Developer/DOOM-fire-zig/.zig-cache/o/958b330d13b776b6cc06266e9f71aa07/build /usr/local/Cellar/zig/0.13.0/bin/zig /Users/rybickic/Developer/DOOM-fire-zig /Users/rybickic/Developer/DOOM-fire-zig/.zig-cache /Users/rybickic/.cache/zig --seed 0x670b8b27 -Z3905a3c7f0b2f588 run

If I run lldb /Users/rybickic/Developer/DOOM-fire-zig/zig-out/bin/DOOM-fire and execute run to step through the debug build, I get an error suggesting the syscall is invalid:

Process 19813 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_SYSCALL (code=16, subcode=0x1)
    frame #0: 0x000000010002b48b DOOM-fire`os.linux.x86_64.syscall3(number=ioctl, arg1=1, arg2=1074295912, arg3=140702053821520) at x86_64.zig:46:5
   43    }
   44
   45    pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
-> 46        return asm volatile ("syscall"
   47            : [ret] "={rax}" (-> usize),
   48            : [number] "{rax}" (@intFromEnum(number)),
   49              [arg1] "{rdi}" (arg1),
Target 0: (DOOM-fire) stopped.
@Chriscbr
Copy link
Author

Chriscbr commented Jul 4, 2024

Update: I changed the code a bit to rely on the std.c APIs and this seemed to fix the immediate issue:

var winsz: std.c.winsize = undefined;
const rv = std.c.ioctl(tty, std.c.T.IOCGWINSZ, @intFromPtr(&winsz));

Unfortunately, I get a different runtime error now when rendering the fire animation:

thread 18916636 panic: index out of bounds: index 15449, len 13536
/Users/rybickic/Developer/DOOM-fire-zig/src/main.zig:621:39: 0x1089fb4d8 in showDoomFire (DOOM-fire)
                            screen_buf[spread_dst - FIRE_W] = spread_px - (spread_rnd_idx & 1);
                                      ^
/Users/rybickic/Developer/DOOM-fire-zig/src/main.zig:679:17: 0x1089f8cfb in main (DOOM-fire)
    showDoomFire();
                ^
/usr/local/Cellar/zig/0.13.0/lib/zig/std/start.zig:524:37: 0x1089f89db in main (DOOM-fire)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x7ff811808365 in ??? (???)
Unwind information for `???:0x7ff811808365` was not available, trace may be incomplete

???:?:?: 0x0 in ??? (???)
run
└─ run DOOM-fire failure
error: the following command terminated unexpectedly:
/Users/rybickic/Developer/DOOM-fire-zig/zig-out/bin/DOOM-fire

@const-void
Copy link
Owner

Thank you, I am incorporating your patches into the latest zig 13 compatible build!!! I really appreciate your hard work & thorough investigation!

@const-void
Copy link
Owner

const-void commented Aug 4, 2024

You are 100% correct - the secret is to use std.c across the board. There are a few bugs that have been fixed ...

Bug #1 - rv==0 vs rv>=0

the ioctl function returns success on >=0, so my check for a strict rv==0 is a bug. When >0 was getting returned, for whatever reason, unexpectedErrno would freak out. TODO - This should be updated to return a better error that is not so reliant on the C-lib, something for the future!

Swapping from rv==0 to rv>=0 fixes that behavior.

Bug #2 - rv>0 is still a problem

However, it exposes another problem, where the ioctl invocation worked, but didn't actually retrieve a terminal size...this results in a positive return value, with a 0x0 size terminal window.

The terminal size (width and height) is used to allocate various memory buffers, so a zero value will cause the math, somewhere, to under-allocate buffers, including...0 bytes...which, simply will not work. The DOOM-fire rendering pipeline will fail spectacularly somewhere along the line.

So I added a check to make that easier to catch for a person running the program to say ... hey, we got here, but it looks like we have a 0x0 window; another future TODO would be to trigger an error if we fail some basic memory sanity checks.

Very Close!*

You were very very close with your patch...converting to std.c absolutely did the trick, and you saved me days of research as I am not really sure why. The only thing was--we still need the terminal window structure as the ioctl function won't actually allocate memory for us...we have to do that in advance...in effect, giving it what it needs, for it to do what we want.

It's a bit counter-intuitive compared to the modern age, where we ask a question and it does it all for us, but that is the nature of these system level calls which are over 40+ years old at this point, and still trucking! Kind of neat.

Thank you again for your help! I really appreciate it, very cool that you spent some time researching.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants