diff --git a/test/standalone.zig b/test/standalone.zig index f52705f05f..b7dfc9dc94 100644 --- a/test/standalone.zig +++ b/test/standalone.zig @@ -234,6 +234,10 @@ pub const build_cases = [_]BuildCase{ .build_root = "test/standalone/stack_iterator", .import = @import("standalone/stack_iterator/build.zig"), }, + .{ + .build_root = "test/standalone/coff_dwarf", + .import = @import("standalone/coff_dwarf/build.zig"), + }, }; const std = @import("std"); diff --git a/test/standalone/coff_dwarf/build.zig b/test/standalone/coff_dwarf/build.zig new file mode 100644 index 0000000000..ffd7800a5b --- /dev/null +++ b/test/standalone/coff_dwarf/build.zig @@ -0,0 +1,35 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +/// This tests the path where DWARF information is embedded in a COFF binary +pub fn build(b: *std.Build) void { + const test_step = b.step("test", "Test it"); + b.default_step = test_step; + + const optimize: std.builtin.OptimizeMode = .Debug; + const target = b.standardTargetOptions(.{}); + + if (builtin.os.tag != .windows) return; + + const exe = b.addExecutable(.{ + .name = "main", + .root_source_file = .{ .path = "main.zig" }, + .optimize = optimize, + .target = target, + }); + + const lib = b.addSharedLibrary(.{ + .name = "shared_lib", + .optimize = optimize, + .target = target, + }); + lib.addCSourceFile("shared_lib.c", &.{"-gdwarf"}); + lib.linkLibC(); + exe.linkLibrary(lib); + + const run = b.addRunArtifact(exe); + run.expectExitCode(0); + run.skip_foreign_checks = true; + + test_step.dependOn(&run.step); +} diff --git a/test/standalone/coff_dwarf/main.zig b/test/standalone/coff_dwarf/main.zig new file mode 100644 index 0000000000..236aa1c5fa --- /dev/null +++ b/test/standalone/coff_dwarf/main.zig @@ -0,0 +1,27 @@ +const std = @import("std"); +const assert = std.debug.assert; +const testing = std.testing; + +extern fn add(a: u32, b: u32, addr: *usize) u32; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer assert(gpa.deinit() == .ok); + const allocator = gpa.allocator(); + + var debug_info = try std.debug.openSelfDebugInfo(allocator); + defer debug_info.deinit(); + + var add_addr: usize = undefined; + _ = add(1, 2, &add_addr); + + const module = try debug_info.getModuleForAddress(add_addr); + const symbol = try module.getSymbolAtAddress(allocator, add_addr); + defer symbol.deinit(allocator); + + try testing.expectEqualStrings("add", symbol.symbol_name); + try testing.expect(symbol.line_info != null); + try testing.expectEqualStrings("shared_lib.c", std.fs.path.basename(symbol.line_info.?.file_name)); + try testing.expectEqual(@as(u64, 3), symbol.line_info.?.line); + try testing.expectEqual(@as(u64, 0), symbol.line_info.?.column); +} diff --git a/test/standalone/coff_dwarf/shared_lib.c b/test/standalone/coff_dwarf/shared_lib.c new file mode 100644 index 0000000000..0455a6a0ad --- /dev/null +++ b/test/standalone/coff_dwarf/shared_lib.c @@ -0,0 +1,6 @@ +#include + +__declspec(dllexport) uint32_t add(uint32_t a, uint32_t b, uintptr_t* addr) { + *addr = (uintptr_t)&add; + return a + b; +}