Skip to content

std.debug.dumpStackTrace shows ???:?:?: for error return traces when CWD differs from source location #25433

@ityonemo

Description

@ityonemo

Zig Version

0.15.1

Steps to Reproduce and Observed Behavior

Summary

In Zig 0.15.1, std.debug.dumpStackTrace() (on any attempt to resolve stack traces) cannot resolve source file locations for error return traces when the current working directory is different from where the source files are located. This worked correctly in Zig 0.14.1, as well as in 0.15.1 Linux builds.

Environment

  • Zig Version: 0.15.1
  • OS: macOS 14.6.0 (Darwin 24.6.0)
  • Architecture: aarch64 (Apple Silicon)
  • Previous Working Version: 0.14.1

Reproduction

Directory structure:

testylib/
├── lib.zig
├── build.zig
├── run.zig
└── different-cwd/
    └── test_loader.zig

lib.zig:

const std = @import("std");

fn bar() !void {
    var x: u8 = 42;
    if (x == 42) {
        return error.bad;
    }
    x = 10;
}

export fn foo() void {
    bar() catch {
        std.debug.dumpStackTrace(@errorReturnTrace().?.*);
    };
}

build.zig:

const std = @import("std");

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

    const lib_module = b.createModule(.{
        .root_source_file = b.path("lib.zig"),
        .target = target,
        .optimize = optimize,
        .error_tracing = true,
        .strip = false,
        .omit_frame_pointer = false,
    });

    const lib = b.addLibrary(.{
        .name = "lib",
        .root_module = lib_module,
        .linkage = .dynamic,
    });

    b.installArtifact(lib);
}

run.zig:

const std = @import("std");

pub fn main() !void {
    var lib = try std.DynLib.open("zig-out/lib/liblib.dylib");
    const foo = lib.lookup(*const fn () callconv(.c) void, "foo") orelse unreachable;
    foo();
}

different-cwd/test_loader.zig:

const std = @import("std");

pub fn main() !void {
    var lib = try std.DynLib.open("../zig-out/lib/liblib.dylib");
    defer lib.close();

    const foo = lib.lookup(*const fn () callconv(.c) void, "foo") orelse unreachable;

    foo();
}

Steps to reproduce:

Test from source directory (works):

cd testylib
zig build
zig run run.zig

Expected and actual output:

testylib/lib.zig:6:9: 0x10442c7a7 in foo (lib)
        return error.bad;
        ^

Test from different directory (broken):

cd testylib/different-cwd
zig run test_loader.zig

Expected output:

testylib/lib.zig:6:9: 0x10442c7a7 in foo (lib)
        return error.bad;
        ^

Actual output:

???:?:?: 0x1011947a7 in _foo (???)

Analysis

  1. The error return trace addresses are captured correctly
  2. Debug info is present in the dylib (can be verified with atos)
  3. std.debug.getSelfDebugInfo() appears to find the debug info
  4. The issue is that source file paths cannot be resolved when CWD differs from source location

Verification that debug info exists:

cd testylib
atos -o zig-out/lib/liblib.dylib -l 0x100000000 0x10442c7a7
# Output shows: _foo (in liblib.dylib) (lib.zig:12)

This proves the debug info is present and atos can resolve it, but std.debug.dumpStackTrace() cannot when run from a different directory.

Actual Behavior

Source locations show as ???:?:?: when the current working directory is different from where the source files are located.

Impact

This breaks error return trace debugging for:

  • Dynamically loaded libraries (NIFs, plugins, etc.)
  • Applications that change working directory
  • Any scenario where the dylib is loaded from a different CWD than the build directory

Additional Notes

  • This is a regression from Zig 0.14.1 where it worked correctly on macOS
  • The issue affects both Debug and ReleaseSafe optimization modes
  • Setting .error_tracing = true, .strip = false, .omit_frame_pointer = false does not resolve the issue

Expected Behavior

std.debug.dumpStackTrace() should be able to resolve source locations regardless of the current working directory, as it did in Zig 0.14.1.

Metadata

Metadata

Assignees

Labels

bugObserved behavior contradicts documented or intended behaviordebug-infoDebug information of binary generated by Zig is not as expected.os-macosregressionIt worked in a previous version of Zig, but stopped working.

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions