I'm upgrading a library I'm working on to use the stage2 compiler and I've encountered a crash that seems to be related to the @extern builtin function. In my library I construct library and function names using comptime string interpolation, and then load a dynamic library and call a C function using those names. This appears to compile correctly, but crashes at runtime. I constructed a basic example to see if I could replicate the behavior:
test2.zig
const std = @import("std");
pub fn main() void {
const func = @extern(*const fn (i32, i32) i32, .{
.name = "plus",
.library_name = "add",
.linkage = .Strong,
.is_thread_local = false,
});
const three = func(1, 2);
std.debug.assert(three == 3);
}
with the C shared library add.c
int plus(int a, int b) {
return a + b;
}
I compile the shared library with zig cc -c add.c and zig cc -shared -o libadd.so add.o and then compile the zig program with zig build-exe test.zig -L. -ladd. This appears to build correctly, but crashes at runtime with a seg fault.
Segmentation fault at address 0x0
???:?:?: 0x0 in ??? (???)
/home/adam/zig-linux-x86_64-0.10.0/lib/std/start.zig:596:22: 0x20de34 in posixCallMainAndExit (test2)
root.main();
^
/home/adam/zig-linux-x86_64-0.10.0/lib/std/start.zig:368:5: 0x20d920 in _start (test2)
@call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
^
Aborted (core dumped)
My original, more complicated, code worked fine in stage1, and I'm not 100% sure this simple example is reproducing the exact same issue, but it certainly doesn't work. Am I missing something in this example, is there a difference in the usage of @extern between stage1 and self-hosted, or is this a self-hosted bug?