Skip to content

Missing stacktrace on Windows 11 x86_64 for Dynamic Libraries linked at runtime (DynSym) #20255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
katamari64 opened this issue Jun 10, 2024 · 4 comments
Labels
bug Observed behavior contradicts documented or intended behavior regression It worked in a previous version of Zig, but stopped working.
Milestone

Comments

@katamari64
Copy link

katamari64 commented Jun 10, 2024

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

When linking at runtime with std.DynLib, stacktrace can't find symbols from the .dll.
This used to work fine in 0.11.0, but stopped working on 0.12.0 and 0.13.0.

Here is a repro case (0.13.0) with 3 files [main.zig, my_lib.zig, build.zig]:

// src/main.zig
const std = @import("std");
const do_something = @import("my_lib").do_something;

pub fn main() !void {
    // > Uncomment the following to see the correct expected stacktrace
    // do_something();

    var lib = try std.DynLib.open("./zig-out/bin/my_lib.dll");
    const dynsym__do_something = lib.lookup(*const fn () void, "do_something") orelse return error.SymbolNotFound;
    dynsym__do_something();
}
// src/my_lib.zig
pub fn do_something() callconv(.C) void {
    panic_function();
}

fn panic_function() void {
    @panic("Time to dump the stacktrace");
}

comptime {
    if (@import("root") == @This()) {
        @export(do_something, .{ .name = "do_something", .linkage = .weak });
    }
}
// build.zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});

    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "missing-stacktrace-repro",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    const my_lib: *std.Build.Step.Compile = b.addSharedLibrary(.{
        .name = "my_lib",
        .root_source_file = b.path("src/my_lib.zig"),
        .target = target,
        .optimize = optimize,
    });
    b.installArtifact(my_lib);

    const my_lib_mod = b.addModule("my_lib", .{
        .root_source_file = b.path("src/my_lib.zig"),
        .imports = &.{},
    });
    exe.root_module.addImport("my_lib", my_lib_mod);

    b.installArtifact(exe);

    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());

    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}

Expected Behavior

(A) Stacktrace when linked at runtime:

>zig build run
thread 40576 panic: Time to dump the stacktrace
???:?:?: 0x76791066 in ??? (my_lib.dll)
???:?:?: 0x7679102e in ??? (my_lib.dll)
E:\Work\Code\zig\stacktrace-comparison\stacktrace012\src\main.zig:11:25: 0xc4107c in main (stacktrace012.exe.obj)
    dynsym__do_something();
                        ^
C:\Users\karll\Software\Zig\lib\std\start.zig:363:53: 0xc412bc in WinStartup (stacktrace012.exe.obj)
    std.os.windows.ntdll.RtlExitUserProcess(callMain());
                                                    ^
???:?:?: 0x7ffbb106257c in ??? (KERNEL32.DLL)
???:?:?: 0x7ffbb2e2aa47 in ??? (ntdll.dll)
run
└─ run stacktrace012 failure

(B) Stacktrace when linked at startup (expected):

>zig build run
thread 59264 panic: Time to dump the stacktrace
E:\Work\Code\zig\stacktrace-comparison\stacktrace012\src\my_lib.zig:6:5: 0x882d26 in panic_function (stacktrace012.exe.obj)
    @panic("Time to dump the stacktrace");
    ^
E:\Work\Code\zig\stacktrace-comparison\stacktrace012\src\my_lib.zig:2:19: 0x85199e in do_something (stacktrace012.exe.obj)
    panic_function();
                  ^
E:\Work\Code\zig\stacktrace-comparison\stacktrace012\src\main.zig:15:24: 0x8510be in foo (stacktrace012.exe.obj)
    build__do_something();
                       ^
E:\Work\Code\zig\stacktrace-comparison\stacktrace012\src\main.zig:7:8: 0x851012 in main (stacktrace012.exe.obj)
    foo();
       ^
C:\Users\karll\Software\Zig\lib\std\start.zig:363:53: 0x8512dc in WinStartup (stacktrace012.exe.obj)
    std.os.windows.ntdll.RtlExitUserProcess(callMain());
                                                    ^
???:?:?: 0x7ffbb106257c in ??? (KERNEL32.DLL)
???:?:?: 0x7ffbb2e2aa47 in ??? (ntdll.dll)
run
└─ run stacktrace012 failure

Sorry if I'm missing something fundamental here, I'm not familiar with how stacktraces are generated in Zig, but I would expect the stacktrace to be present even when linking at runtime. Also it sounds like a regression to me as it used to work on Zig 0.11.0, but after updating to 0.12.0 it stopped working.

If the build.zig file is adapted, it's possible run the program and do the runtime linking in Zig 0.11.0 to confirm this used to work.

@katamari64 katamari64 added the bug Observed behavior contradicts documented or intended behavior label Jun 10, 2024
@Vexu Vexu added this to the 0.14.0 milestone Jun 10, 2024
@Vexu Vexu added the regression It worked in a previous version of Zig, but stopped working. label Jun 10, 2024
@xdBronch
Copy link
Contributor

i cant test if this is related since i cant reproduce this on linux but your call to lib.lookup is wrong, the function needs to be callconv(.C). see #19841

@katamari64
Copy link
Author

You are right, and as soon as I added callconv(.C) the stacktrace came back. Thanks!

Per the issue you mentioned, I guess the plan is to assert for callconv(.C) and that would have avoided my issue? Should I close this issue then?

@Pyrolistical
Copy link
Contributor

Should I close this issue then?

Yep, once #19842 is closed, this issue would be detected

@Vexu
Copy link
Member

Vexu commented Jun 16, 2024

Is there some other bug that causes this to not work on Linux without linking libc? Specifying callconv(.C) did nothing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior regression It worked in a previous version of Zig, but stopped working.
Projects
None yet
Development

No branches or pull requests

4 participants