Update 3:
But if I try to do anything inside the function if will segfault, this for example result in a Segmentation fault at address 0x0
pub export fn gameInit() void {
std.debug.print("Init done", .{});
}
Update 2:
Looks to have to do with the return of gameInit, if I make it return void it works, however I would need it to not be void.
var gameInit: *const fn () void = undefined;
Update:
Code is now avaliable at Stuck with error · favetelinguis/ztuig@f5ba3fa · GitHub
I am currently playing around with Zig and hot code where I get an error I do not understand at all. Given the following code.
main.zig
const std = @import("std");
const debug = std.debug;
const game_lib = @import("game.zig");
const gameInit_t = @TypeOf(game_lib.gameInit);
var gameInit: *gameInit_t = undefined;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
loadGameDll() catch @panic("Failed to load game.so");
_ = gameInit();
var count: u32 = 1;
while (true) {
if (count % 5 == 0) { // reload every 5 seconds
unloadGameDll() catch unreachable;
recompileGameDll(allocator) catch {
std.debug.print("Failed to recompile game.dll\n", .{});
};
loadGameDll() catch @panic("Failed to load game.dll");
}
std.time.sleep(1_000_000_000);
count += 1;
}
}
var game_dyn_lib: ?std.DynLib = null;
fn loadGameDll() !void {
if (game_dyn_lib != null) return error.AlreadyLoaded;
var dyn_lib = std.DynLib.open("zig-out/lib/libgame.so") catch {
return error.OpenFail;
};
game_dyn_lib = dyn_lib;
gameInit = dyn_lib.lookup(*gameInit_t, "gameInit") orelse return error.LookupFail;
std.debug.print("Loaded libgame.so\n", .{});
}
fn unloadGameDll() !void {
if (game_dyn_lib) |*dyn_lib| {
dyn_lib.close();
game_dyn_lib = null;
} else {
return error.AlreadyUnloaded;
}
}
fn recompileGameDll(allocator: std.mem.Allocator) !void {
const process_args = [_][]const u8{
"zig",
"build",
"-Dgame_only=true",
};
var build_process = std.process.Child.init(&process_args, allocator);
try build_process.spawn();
const term = try build_process.wait();
switch (term) {
.Exited => |exited| {
if (exited == 2) return error.RecompileFail;
},
else => return,
}
}
game.zig
const std = @import("std");
pub const GameState = struct {};
pub export fn gameInit() *GameState {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
return allocator.create(GameState) catch @panic("out of memory");
}
I get the following error when trying to run it. It looks like it loads the dynamic lib ok but then fail to run gameInit()
. Any ideas on how to make progress on fixing the issue and understanding the root of the error.
$ zig build run2 -Dgame_only=false
Loaded libgame.so
General protection exception (no address available)
???:?:?: 0x7f7e21bddd90 in ??? (???)
Unwind information for `???:0x7f7e21bddd90` was not available, trace may be incomplete
/home/h/repos/zigs/ztuig/src/main2.zig:23:17: 0x103c0f1 in main (hotr)
_ = gameInit();
^
/nix/store/j9sp79vdhz4l6lfnvzhvcprhar803zr3-zig-0.13.0/lib/zig/std/start.zig:524:37: 0x103ae14 in posixCallMainAndExit (hotr)
const result = root.main() catch |err| {
^
/nix/store/j9sp79vdhz4l6lfnvzhvcprhar803zr3-zig-0.13.0/lib/zig/std/start.zig:266:5: 0x103a951 in _start (hotr)
asm volatile (switch (native_arch) {
^
run2
└─ run hotr failure
error: the following command terminated unexpectedly:
/home/h/repos/zigs/ztuig/zig-out/bin/hotr
Build Summary: 7/9 steps succeeded; 1 failed (disable with --summary none)
run2 transitive failure
└─ run hotr failure
error: the following build command failed with exit code 1:
/home/h/repos/zigs/ztuig/.zig-cache/o/b99ecefa070148799c71cbf52f917711/build /nix/store/j9sp79vdhz4l6lfnvzhvcprhar803zr3-zig-0.13.0/bin/zig /home/h/repos/zigs/ztuig /home/h/repos/zigs/ztuig/.zig-cache /home/h/.cache/zig --seed 0x7f4b92cb -Z4de9b50e3d3bb79a run2 -Dgame_only=false
error: Recipe `rerun` failed on line 2 with exit code 1
The code is very much taken from hotreload/src/main.zig at master · samhattangady/hotreload · GitHub
and
Hot-reloading with Raylib - Zig NEWS