diff options
Diffstat (limited to 'src/main.zig')
| -rw-r--r-- | src/main.zig | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/main.zig b/src/main.zig index 004d59cb..1fcc2770 100644 --- a/src/main.zig +++ b/src/main.zig @@ -160,6 +160,26 @@ fn webMain() !void { } fn nativeMain(init: std.process.Init) !void { + // FIRST, before anything can log or panic. std's start code hands the + // debug/log stderr writer the process environ exactly as the kernel laid + // it out beside argv, and `std.debug.lockStderr` scans that block once, + // lazily, for NO_COLOR and CLICOLOR_FORCE. Lazily is the problem: libc + // may have rewritten the block by then. SDL_CreateWindow does, every + // time — `Wayland_ShowWindow` unsets XDG_ACTIVATION_TOKEN, and glibc's + // unsetenv compacts `environ` in place and leaves a null in the slot the + // captured length still counts. `Environ.scan` unwraps that null, so the + // FIRST log line or panic in the gui shell panicked inside the scan, and + // then the panic handler took the same path and deadlocked on the stderr + // lock it was already holding: "attempt to use null value" and a hang, + // with no trace and no message of its own. Every SDL_GetError report in + // gui.zig was that, which is to say unreachable. + // + // Locking and immediately unlocking here does the scan while the block is + // still the one std was given, and memoizes it. Nothing is written. + var stderr_probe: [64]u8 = undefined; + _ = std.debug.lockStderr(&stderr_probe); + std.debug.unlockStderr(); + var opts: pardes.Options = .{}; const arena = init.arena.allocator(); const args = try init.minimal.args.toSlice(arena); |
