Skip to content

x86 backend: global variables are invalid when building a shared library loaded with dlopen #25026

@LordMZTE

Description

@LordMZTE

Zig Version

0.15.1

Steps to Reproduce and Observed Behavior

  1. Write this to test.zig
const std = @import("std");

export fn testFunc() callconv(.c) void {
    std.debug.print("Hello\n", .{});
}
  1. Write this to test.c
#include <dlfcn.h>

typedef void (*testFunc_t)(void);

int main() {
    void *lib = dlopen("./libtest.so", RTLD_NOW | RTLD_LOCAL);

    testFunc_t func = (testFunc_t)dlsym(lib, "testFunc");
    func();

    dlclose(lib);

    return 0;
}
  1. Compile Zig code with zig build-lib test.zig -dynamic -lc to emit libtest.so
  2. Compile C code with gcc test.c to emit a.out
  3. Run ./a.out and observe a segmentation fault from the Zig code with this backtrace:
#0  0x00007ffff7ebfe68 in Progress.unlockStderrWriter () from ./libtest.so
#1  0x00007ffff7e9467d in debug.unlockStderrWriter () from ./libtest.so
#2  0x00007ffff7f60d51 in debug.print__anon_22256 (fmt=..., args=...) from ./libtest.so
#3  0x00007ffff7f60c52 in testFunc () at test.zig:4
#4  0x000000000040117c in main ()

This happens because Progress.unlockStderrWriter is touching a global variable. Global variables in general seem to have undefined values.

Expected Behavior

If we add -fllvm to the zig build-lib invocation, we get a Hello as expected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    arch-x86_6464-bit x86backend-self-hostedbugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions