authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-23 04:48:01+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-23 23:22:13+00:00
log7774287fdca1b56e12a420c446e83191c05fb468
tree43f98e437925d644bfa61938ea2d1a1687381ea6
parentd916954bee0f477bcada0693d4aa952197cf1eef
signaturelock-open Commit is signed but in an unrecognized format.

tests: enable stack trace tests for x86_64-selfhosted

Allows the stack trace tests to be additionally compiled and run with `.use_llvm = false, .use_lld = false` depending on the host target. This is currently enabled for x86_64 targets emitting ELF. Self-hosted backends emit slightly different DWARF info to the LLVM backend, so the checking logic (and the tests themselves) had to be tweaked slightly to support both backends at once.

3 files changed, 70 insertions(+), 42 deletions(-)

test/src/StackTrace.zig+25-6
...@@ -21,17 +21,34 @@ const Config = struct {...@@ -21,17 +21,34 @@ const Config = struct {
21};21};
2222
23pub fn addCase(self: *StackTrace, config: Config) void {23pub fn addCase(self: *StackTrace, config: Config) void {
24 self.addCaseInner(config, true);
25 if (shouldTestNonLlvm(self.b.graph.host.result)) {
26 self.addCaseInner(config, false);
27 }
28}
29
30fn addCaseInner(self: *StackTrace, config: Config, use_llvm: bool) void {
24 if (config.Debug) |per_mode|31 if (config.Debug) |per_mode|
25 self.addExpect(config.name, config.source, .Debug, per_mode);32 self.addExpect(config.name, config.source, .Debug, use_llvm, per_mode);
2633
27 if (config.ReleaseSmall) |per_mode|34 if (config.ReleaseSmall) |per_mode|
28 self.addExpect(config.name, config.source, .ReleaseSmall, per_mode);35 self.addExpect(config.name, config.source, .ReleaseSmall, use_llvm, per_mode);
2936
30 if (config.ReleaseFast) |per_mode|37 if (config.ReleaseFast) |per_mode|
31 self.addExpect(config.name, config.source, .ReleaseFast, per_mode);38 self.addExpect(config.name, config.source, .ReleaseFast, use_llvm, per_mode);
3239
33 if (config.ReleaseSafe) |per_mode|40 if (config.ReleaseSafe) |per_mode|
34 self.addExpect(config.name, config.source, .ReleaseSafe, per_mode);41 self.addExpect(config.name, config.source, .ReleaseSafe, use_llvm, per_mode);
42}
43
44fn shouldTestNonLlvm(target: std.Target) bool {
45 return switch (target.cpu.arch) {
46 .x86_64 => switch (target.ofmt) {
47 .elf => true,
48 else => false,
49 },
50 else => false,
51 };
35}52}
3653
37fn addExpect(54fn addExpect(
...@@ -39,13 +56,14 @@ fn addExpect(...@@ -39,13 +56,14 @@ fn addExpect(
39 name: []const u8,56 name: []const u8,
40 source: []const u8,57 source: []const u8,
41 optimize_mode: OptimizeMode,58 optimize_mode: OptimizeMode,
59 use_llvm: bool,
42 mode_config: Config.PerMode,60 mode_config: Config.PerMode,
43) void {61) void {
44 for (mode_config.exclude_os) |tag| if (tag == builtin.os.tag) return;62 for (mode_config.exclude_os) |tag| if (tag == builtin.os.tag) return;
4563
46 const b = self.b;64 const b = self.b;
47 const annotated_case_name = b.fmt("check {s} ({s})", .{65 const annotated_case_name = b.fmt("check {s} ({s} {s})", .{
48 name, @tagName(optimize_mode),66 name, @tagName(optimize_mode), if (use_llvm) "llvm" else "selfhosted",
49 });67 });
50 for (self.test_filters) |test_filter| {68 for (self.test_filters) |test_filter| {
51 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;69 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
...@@ -61,6 +79,7 @@ fn addExpect(...@@ -61,6 +79,7 @@ fn addExpect(
61 .target = b.graph.host,79 .target = b.graph.host,
62 .error_tracing = mode_config.error_tracing,80 .error_tracing = mode_config.error_tracing,
63 }),81 }),
82 .use_llvm = use_llvm,
64 });83 });
6584
66 const run = b.addRunArtifact(exe);85 const run = b.addRunArtifact(exe);
test/src/check-stack-trace.zig+15-6
...@@ -58,14 +58,23 @@ pub fn main() !void {...@@ -58,14 +58,23 @@ pub fn main() !void {
58 try buf.appendSlice(line[pos + 1 .. marks[2] + delims[2].len]);58 try buf.appendSlice(line[pos + 1 .. marks[2] + delims[2].len]);
59 try buf.appendSlice(" [address]");59 try buf.appendSlice(" [address]");
60 if (optimize_mode == .Debug) {60 if (optimize_mode == .Debug) {
61 // On certain platforms (windows) or possibly depending on how we choose to link main61 try buf.appendSlice(line[marks[3] .. marks[4] + delims[4].len]);
62 // the object file extension may be present so we simply strip any extension.62
63 if (mem.indexOfScalar(u8, line[marks[4]..marks[5]], '.')) |idot| {63 const file_name = line[marks[4] + delims[4].len .. marks[5]];
64 try buf.appendSlice(line[marks[3] .. marks[4] + idot]);64 // The LLVM backend currently uses the object file name in the debug info here.
65 try buf.appendSlice(line[marks[5]..]);65 // This actually violates the DWARF specification (DWARF5 § 3.1.1, lines 24-27).
66 // The self-hosted backend uses the root Zig source file of the module (in compilance with the spec).
67 if (std.mem.eql(u8, file_name, "test") or
68 std.mem.eql(u8, file_name, "test.exe.obj") or
69 std.mem.endsWith(u8, file_name, ".zig"))
70 {
71 try buf.appendSlice("[main_file]");
66 } else {72 } else {
67 try buf.appendSlice(line[marks[3]..]);73 // Something unexpected; include it verbatim.
74 try buf.appendSlice(file_name);
68 }75 }
76
77 try buf.appendSlice(line[marks[5]..]);
69 } else {78 } else {
70 try buf.appendSlice(line[marks[3] .. marks[3] + delims[3].len]);79 try buf.appendSlice(line[marks[3] .. marks[3] + delims[3].len]);
71 try buf.appendSlice("[function]");80 try buf.appendSlice("[function]");
test/stack_traces.zig+30-30
...@@ -13,7 +13,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -13,7 +13,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
13 .Debug = .{13 .Debug = .{
14 .expect =14 .expect =
15 \\error: TheSkyIsFalling15 \\error: TheSkyIsFalling
16 \\source.zig:2:5: [address] in main (test)16 \\source.zig:2:5: [address] in main ([main_file])
17 \\ return error.TheSkyIsFalling;17 \\ return error.TheSkyIsFalling;
18 \\ ^18 \\ ^
19 \\19 \\
...@@ -61,10 +61,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -61,10 +61,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
61 .Debug = .{61 .Debug = .{
62 .expect =62 .expect =
63 \\error: TheSkyIsFalling63 \\error: TheSkyIsFalling
64 \\source.zig:2:5: [address] in foo (test)64 \\source.zig:2:5: [address] in foo ([main_file])
65 \\ return error.TheSkyIsFalling;65 \\ return error.TheSkyIsFalling;
66 \\ ^66 \\ ^
67 \\source.zig:6:5: [address] in main (test)67 \\source.zig:6:5: [address] in main ([main_file])
68 \\ try foo();68 \\ try foo();
69 \\ ^69 \\ ^
70 \\70 \\
...@@ -120,7 +120,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -120,7 +120,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
120 .Debug = .{120 .Debug = .{
121 .expect =121 .expect =
122 \\error: UnrelatedError122 \\error: UnrelatedError
123 \\source.zig:13:5: [address] in main (test)123 \\source.zig:13:5: [address] in main ([main_file])
124 \\ return error.UnrelatedError;124 \\ return error.UnrelatedError;
125 \\ ^125 \\ ^
126 \\126 \\
...@@ -172,7 +172,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -172,7 +172,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
172 .Debug = .{172 .Debug = .{
173 .expect =173 .expect =
174 \\error: UnrelatedError174 \\error: UnrelatedError
175 \\source.zig:10:5: [address] in main (test)175 \\source.zig:10:5: [address] in main ([main_file])
176 \\ return error.UnrelatedError;176 \\ return error.UnrelatedError;
177 \\ ^177 \\ ^
178 \\178 \\
...@@ -224,10 +224,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -224,10 +224,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
224 .Debug = .{224 .Debug = .{
225 .expect =225 .expect =
226 \\error: TheSkyIsFalling226 \\error: TheSkyIsFalling
227 \\source.zig:2:5: [address] in foo (test)227 \\source.zig:2:5: [address] in foo ([main_file])
228 \\ return error.TheSkyIsFalling;228 \\ return error.TheSkyIsFalling;
229 \\ ^229 \\ ^
230 \\source.zig:10:5: [address] in main (test)230 \\source.zig:10:5: [address] in main ([main_file])
231 \\ try foo();231 \\ try foo();
232 \\ ^232 \\ ^
233 \\233 \\
...@@ -284,7 +284,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -284,7 +284,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
284 .Debug = .{284 .Debug = .{
285 .expect =285 .expect =
286 \\error: BadTime286 \\error: BadTime
287 \\source.zig:12:5: [address] in main (test)287 \\source.zig:12:5: [address] in main ([main_file])
288 \\ return error.BadTime;288 \\ return error.BadTime;
289 \\ ^289 \\ ^
290 \\290 \\
...@@ -332,10 +332,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -332,10 +332,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
332 .Debug = .{332 .Debug = .{
333 .expect =333 .expect =
334 \\error: AndMyCarIsOutOfGas334 \\error: AndMyCarIsOutOfGas
335 \\source.zig:2:5: [address] in foo (test)335 \\source.zig:2:5: [address] in foo ([main_file])
336 \\ return error.TheSkyIsFalling;336 \\ return error.TheSkyIsFalling;
337 \\ ^337 \\ ^
338 \\source.zig:6:5: [address] in main (test)338 \\source.zig:6:5: [address] in main ([main_file])
339 \\ return foo() catch error.AndMyCarIsOutOfGas;339 \\ return foo() catch error.AndMyCarIsOutOfGas;
340 \\ ^340 \\ ^
341 \\341 \\
...@@ -391,7 +391,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -391,7 +391,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
391 .Debug = .{391 .Debug = .{
392 .expect =392 .expect =
393 \\error: SomethingUnrelatedWentWrong393 \\error: SomethingUnrelatedWentWrong
394 \\source.zig:11:5: [address] in main (test)394 \\source.zig:11:5: [address] in main ([main_file])
395 \\ return error.SomethingUnrelatedWentWrong;395 \\ return error.SomethingUnrelatedWentWrong;
396 \\ ^396 \\ ^
397 \\397 \\
...@@ -456,13 +456,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -456,13 +456,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
456 .Debug = .{456 .Debug = .{
457 .expect =457 .expect =
458 \\error: StillUnresolved458 \\error: StillUnresolved
459 \\source.zig:1:18: [address] in foo (test)459 \\source.zig:1:18: [address] in foo ([main_file])
460 \\fn foo() !void { return error.TheSkyIsFalling; }460 \\fn foo() !void { return error.TheSkyIsFalling; }
461 \\ ^461 \\ ^
462 \\source.zig:2:18: [address] in bar (test)462 \\source.zig:2:18: [address] in bar ([main_file])
463 \\fn bar() !void { return error.InternalError; }463 \\fn bar() !void { return error.InternalError; }
464 \\ ^464 \\ ^
465 \\source.zig:23:5: [address] in main (test)465 \\source.zig:23:5: [address] in main ([main_file])
466 \\ return error.StillUnresolved;466 \\ return error.StillUnresolved;
467 \\ ^467 \\ ^
468 \\468 \\
...@@ -527,13 +527,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -527,13 +527,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
527 .Debug = .{527 .Debug = .{
528 .expect =528 .expect =
529 \\error: TestExpectedError529 \\error: TestExpectedError
530 \\source.zig:9:18: [address] in foo (test)530 \\source.zig:9:18: [address] in foo ([main_file])
531 \\fn foo() !void { return error.Foo; }531 \\fn foo() !void { return error.Foo; }
532 \\ ^532 \\ ^
533 \\source.zig:5:5: [address] in expectError (test)533 \\source.zig:5:5: [address] in expectError ([main_file])
534 \\ return error.TestExpectedError;534 \\ return error.TestExpectedError;
535 \\ ^535 \\ ^
536 \\source.zig:17:5: [address] in main (test)536 \\source.zig:17:5: [address] in main ([main_file])
537 \\ try expectError(error.Bar, foo());537 \\ try expectError(error.Bar, foo());
538 \\ ^538 \\ ^
539 \\539 \\
...@@ -592,13 +592,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -592,13 +592,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
592 .Debug = .{592 .Debug = .{
593 .expect =593 .expect =
594 \\error: AndMyCarIsOutOfGas594 \\error: AndMyCarIsOutOfGas
595 \\source.zig:2:5: [address] in foo (test)595 \\source.zig:2:5: [address] in foo ([main_file])
596 \\ return error.TheSkyIsFalling;596 \\ return error.TheSkyIsFalling;
597 \\ ^597 \\ ^
598 \\source.zig:6:5: [address] in bar (test)598 \\source.zig:6:5: [address] in bar ([main_file])
599 \\ return error.AndMyCarIsOutOfGas;599 \\ return error.AndMyCarIsOutOfGas;
600 \\ ^600 \\ ^
601 \\source.zig:11:9: [address] in main (test)601 \\source.zig:11:9: [address] in main ([main_file])
602 \\ try bar();602 \\ try bar();
603 \\ ^603 \\ ^
604 \\604 \\
...@@ -657,13 +657,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -657,13 +657,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
657 .Debug = .{657 .Debug = .{
658 .expect =658 .expect =
659 \\error: AndMyCarIsOutOfGas659 \\error: AndMyCarIsOutOfGas
660 \\source.zig:2:5: [address] in foo (test)660 \\source.zig:2:5: [address] in foo ([main_file])
661 \\ return error.TheSkyIsFalling;661 \\ return error.TheSkyIsFalling;
662 \\ ^662 \\ ^
663 \\source.zig:6:5: [address] in bar (test)663 \\source.zig:6:5: [address] in bar ([main_file])
664 \\ return error.AndMyCarIsOutOfGas;664 \\ return error.AndMyCarIsOutOfGas;
665 \\ ^665 \\ ^
666 \\source.zig:11:9: [address] in main (test)666 \\source.zig:11:9: [address] in main ([main_file])
667 \\ try bar();667 \\ try bar();
668 \\ ^668 \\ ^
669 \\669 \\
...@@ -724,16 +724,16 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -724,16 +724,16 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
724 .Debug = .{724 .Debug = .{
725 .expect =725 .expect =
726 \\error: TheSkyIsFalling726 \\error: TheSkyIsFalling
727 \\source.zig:10:5: [address] in make_error (test)727 \\source.zig:10:5: [address] in make_error ([main_file])
728 \\ return error.TheSkyIsFalling;728 \\ return error.TheSkyIsFalling;
729 \\ ^729 \\ ^
730 \\source.zig:6:5: [address] in bar (test)730 \\source.zig:6:5: [address] in bar ([main_file])
731 \\ return make_error();731 \\ return make_error();
732 \\ ^732 \\ ^
733 \\source.zig:2:5: [address] in foo (test)733 \\source.zig:2:5: [address] in foo ([main_file])
734 \\ try bar();734 \\ try bar();
735 \\ ^735 \\ ^
736 \\source.zig:14:5: [address] in main (test)736 \\source.zig:14:5: [address] in main ([main_file])
737 \\ try foo();737 \\ try foo();
738 \\ ^738 \\ ^
739 \\739 \\
...@@ -797,10 +797,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -797,10 +797,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
797 .windows, // TODO intermittent failures797 .windows, // TODO intermittent failures
798 },798 },
799 .expect =799 .expect =
800 \\source.zig:7:8: [address] in foo (test)800 \\source.zig:7:8: [address] in foo ([main_file])
801 \\ bar();801 \\ bar();
802 \\ ^802 \\ ^
803 \\source.zig:10:8: [address] in main (test)803 \\source.zig:10:8: [address] in main ([main_file])
804 \\ foo();804 \\ foo();
805 \\ ^805 \\ ^
806 \\806 \\
...@@ -829,7 +829,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -829,7 +829,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
829 .Debug = .{829 .Debug = .{
830 .expect =830 .expect =
831 \\error: TheSkyIsFalling831 \\error: TheSkyIsFalling
832 \\source.zig:3:5: [address] in main (test)832 \\source.zig:3:5: [address] in main ([main_file])
833 \\ return error.TheSkyIsFalling;833 \\ return error.TheSkyIsFalling;
834 \\ ^834 \\ ^
835 \\835 \\