zig
zig copied to clipboard
std.debug: DWARFv5 debug info sometimes causes a failed stack trace
Zig Version
0.10.0-dev.2993+0248073b9
Steps to Reproduce
// build.zig
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const exe = b.addExecutable("test", "test.zig");
exe.addCSourceFile("test.c", &[_][]const u8{
"-std=c99",
"-gdwarf-5", // Bad stack trace
//"-gdwarf-4", // works
});
exe.install();
const run_cmd = exe.run();
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);
}
// test.zig
extern fn baz(x: c_int) c_int;
pub fn main() void {
_ = baz(15);
}
// test.c
int foo(int x) {
*(int*)0 = 10; // Intentionally trigger SEGFAULT
return x + 2;
}
int bar(int x) {
return foo(x + 16);
}
int baz(int x) {
return 2 * bar(x);
}
Expected Behavior
$ ../zig/build/zig build run
Illegal instruction at address 0x205211
/home/topolarity/repos/test/test.c:2:11: 0x205211 in foo (/home/topolarity/repos/test/test.c)
*(int*)0 = 10; // Intentionally trigger SEGFAULT
^
/home/topolarity/repos/test/test.c:7:9: 0x20526c in bar (/home/topolarity/repos/test/test.c)
return foo(x + 16);
^
/home/topolarity/repos/test/test.c:11:13: 0x205292 in baz (/home/topolarity/repos/test/test.c)
return 2 * bar(x);
^
/home/topolarity/repos/test/test.zig:4:12: 0x227a0d in main (test)
_ = baz(15);
^
/home/topolarity/repos/zig/lib/std/start.zig:570:22: 0x207033 in std.start.posixCallMainAndExit (test)
root.main();
^
/home/topolarity/repos/zig/lib/std/start.zig:338:5: 0x206df2 in std.start._start (test)
@call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
^
The following command terminated unexpectedly:
cd /home/topolarity/repos/test && /home/topolarity/repos/test/zig-out/bin/test
error: the following build command failed with exit code 1:
/home/topolarity/repos/test/zig-cache/o/c6e3ef0111461e363fabeadc1273799f/build /home/topolarity/repos/zig/build/zig /home/topolarity/repos/test/home/topolarity/repos/test/zig-cache /home/topolarity/.cache/zig run
Actual Behavior
$ ../zig/build/zig build run
Illegal instruction at address 0x205211
???:?:?: 0x205211 in ??? (???)
???:?:?: 0x20526c in ??? (???)
???:?:?: 0x205292 in ??? (???)
???:?:?: 0x227a0d in ??? (???)
???:?:?: 0x207033 in ??? (???)
???:?:?: 0x206df2 in ??? (???)
The following command terminated unexpectedly:
cd /home/topolarity/repos/test && /home/topolarity/repos/test/zig-out/bin/test
error: the following build command failed with exit code 1:
/home/topolarity/repos/test/zig-cache/o/2117e822669df035365d51266c2c619d/build /home/topolarity/repos/zig/build/zig /home/topolarity/repos/test/home/topolarity/repos/test/zig-cache /home/topolarity/.cache/zig run
Note that DWARFv5 is the default in clang now on many systems, so it's actually quite easy to hit this with just -g
In this case we hit https://github.com/ziglang/zig/blob/master/lib/std/dwarf.zig#L539 with a form_id
of 0x25
. It seems DW_FORM_strx1 and possibly others form types aren't implemented. https://www.dwarfstd.org/doc/DWARF5.pdf#chap%3ADWFORMstrxone
DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, DW_FORM_strx3, and DW_FORM_strx4 seem to be used to index into a debug_str_offsets
section, which we have to add here: https://github.com/ziglang/zig/blob/master/lib/std/debug.zig#L922
I'm running into this same issue. If no-one else is working on it I can see about implementing support for DW_FORM_strx* based strings.
I believe it's almost all of the new attribute forms for v5 that still need to be added (they are listed in the spec)
The issue is up for grabs, if you'd like to take a whack!
Although #12270 was a step in the right direction, this still reproduces on my machine (Zig 0.10.0-dev.3702+583175dc1).
To summarize the missing DWARFv5 support:
- Several new forms:
strx
,addrx
,addrx1
,addrx2
,addrx3
,addrx4
,data16
,implicit_const
,line_strp
,loclistx
,rnglistx
,ref_sup4
,ref_sup8
,strp_sup
- V5 layout/header for the
.debug_info
section
Ah thanks for reopening, I'm not sure why I closed it without checking the test case in the OP.
The comment at the top of the .zig file helped reveal #12610, so thank you for that. As for DWARFv5, here's 0.9.1 vs the commit I just pushed:
0.9.1
$ ~/Downloads/zig-linux-x86_64-0.9.1/zig build-exe test.zig test.c &
& ./test
Illegal instruction at address 0x204d8c
/home/andy/dev/zig/build-release/test.c:3:14: 0x204d8c in baz (test.c)
*(int*)0 = 10; // Intentionally trigger SEGFAULT
^
/home/andy/dev/zig/build-release/test.zig:4:12: 0x22cced in main (test)
_ = baz(15);
^
/home/andy/Downloads/zig-linux-x86_64-0.9.1/lib/std/start.zig:551:22: 0x2263fc in std.start.callMain (test)
root.main();
^
/home/andy/Downloads/zig-linux-x86_64-0.9.1/lib/std/start.zig:495:12: 0x20701e in std.start.callMainWithArgs (test)
return @call(.{ .modifier = .always_inline }, callMain, .{});
^
/home/andy/Downloads/zig-linux-x86_64-0.9.1/lib/std/start.zig:409:17: 0x2060b6 in std.start.posixCallMainAndExit (test)
std.os.exit(@call(.{ .modifier = .always_inline }, callMainWithArgs, .{ argc, argv, envp }));
^
/home/andy/Downloads/zig-linux-x86_64-0.9.1/lib/std/start.zig:322:5: 0x205ec2 in std.start._start (test)
@call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
^
Aborted (core dumped)
master
$ stage2/bin/zig build-exe test.zig test.c && ./test
Illegal instruction at address 0x20ccd1
/home/andy/dev/zig/build-release/test.c:3:14: 0x20ccd1 in foo (test.c)
*(int*)0 = 10; // Intentionally trigger SEGFAULT
^
/home/andy/dev/zig/build-release/test.c:7:12: 0x20cd2c in bar (test.c)
return foo(x + 16);
^
/home/andy/dev/zig/build-release/test.c:10:16: 0x20cd52 in baz (test.c)
return 2 * bar(x);
^
./test.zig:4:12: 0x20dd4d in main (test)
_ = baz(15);
^
/home/andy/dev/zig/lib/std/start.zig:564:22: 0x20d62d in posixCallMainAndExit (test)
root.main();
^
/home/andy/dev/zig/lib/std/start.zig:336:5: 0x20d032 in _start (test)
@call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
^
Aborted (core dumped)
So you can see that master branch outperforms 0.9.1 because some of the C stack frames that were missing with 0.9.1 are present with master branch.