zig icon indicating copy to clipboard operation
zig copied to clipboard

std.DynLib: Lookup points to zero'ed bytes when libc is not linked.

Open gcoakes opened this issue 1 year ago • 3 comments

Zig Version

0.14.0-dev.1166+bb7050106

Steps to Reproduce and Observed Behavior

repro.tar.gz

Using the above archive, run the following commands:

$ tar xvf repro.tar.gz
zig-dynlib-lookup-bug/
zig-dynlib-lookup-bug/.gitignore
zig-dynlib-lookup-bug/LICENSE
zig-dynlib-lookup-bug/README.md
zig-dynlib-lookup-bug/build.zig
zig-dynlib-lookup-bug/lib.zig
zig-dynlib-lookup-bug/main.zig
zig-dynlib-lookup-bug/workaround.diff
$ cd zig-dynlib-lookup-bug
$ zig build
$ ./zig-out/bin/repro zig-out/lib/librepro.so
Segmentation fault at address 0x0
???:?:?: 0x0 in ??? (???)
fish: Job 1, './zig-out/bin/repro zig-out/lib…' terminated by signal SIGABRT (Abort)

Expected Behavior

$ ./zig-out/bin/repro zig-out/lib/librepro.so
Hello, world!

Linking libc works around the issue.

gcoakes avatar Aug 25 '24 00:08 gcoakes

Environment:

$ cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.20.2
PRETTY_NAME="Alpine Linux v3.20"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
$ uname -a
Linux gcoakes 6.6.45-0-lts #1-Alpine SMP PREEMPT_DYNAMIC 2024-08-13 08:10:32 x86_64 GNU/Linux

gcoakes avatar Aug 25 '24 00:08 gcoakes

Related to #20980 This is caused by missing relocation logic in the zig implementation of ElfDynLib. Linking wtih libc causes dlopen to be used instead, which makes it work. Though this case is probably more complicated, because std is involved

fardragon avatar Aug 25 '24 11:08 fardragon

Somewhat reduced repro steps updated for 0.15.0-dev.552+bc2f7c754

mkdir repro
cd repro
zig init

root.zig

const std = @import("std");

pub export fn foo() callconv(.c) void {
    std.debug.print("aa", .{});
}

main.zig

const std = @import("std");

pub fn main() !void {
    var lib = try std.DynLib.open("zig-out/lib/librepro.so");
    const foo = lib.lookup(*const fn () callconv(.c) void, "foo") orelse return error.LookupFailed;
    foo();
}

build.zig diff

51c51
<         .linkage = .static,
---
>         .linkage = .dynamic,
zig build run

eshom avatar May 17 '25 12:05 eshom