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 {
2121};
2222
2323pub 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 {
2431 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
2734 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
3037 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
3340 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 };
3552}
3653
3754fn addExpect(
......@@ -39,13 +56,14 @@ fn addExpect(
3956 name: []const u8,
4057 source: []const u8,
4158 optimize_mode: OptimizeMode,
59 use_llvm: bool,
4260 mode_config: Config.PerMode,
4361) void {
4462 for (mode_config.exclude_os) |tag| if (tag == builtin.os.tag) return;
4563
4664 const b = self.b;
47 const annotated_case_name = b.fmt("check {s} ({s})", .{
48 name, @tagName(optimize_mode),
65 const annotated_case_name = b.fmt("check {s} ({s} {s})", .{
66 name, @tagName(optimize_mode), if (use_llvm) "llvm" else "selfhosted",
4967 });
5068 for (self.test_filters) |test_filter| {
5169 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
......@@ -61,6 +79,7 @@ fn addExpect(
6179 .target = b.graph.host,
6280 .error_tracing = mode_config.error_tracing,
6381 }),
82 .use_llvm = use_llvm,
6483 });
6584
6685 const run = b.addRunArtifact(exe);
test/src/check-stack-trace.zig+15-6
......@@ -58,14 +58,23 @@ pub fn main() !void {
5858 try buf.appendSlice(line[pos + 1 .. marks[2] + delims[2].len]);
5959 try buf.appendSlice(" [address]");
6060 if (optimize_mode == .Debug) {
61 // On certain platforms (windows) or possibly depending on how we choose to link main
62 // the object file extension may be present so we simply strip any extension.
63 if (mem.indexOfScalar(u8, line[marks[4]..marks[5]], '.')) |idot| {
64 try buf.appendSlice(line[marks[3] .. marks[4] + idot]);
65 try buf.appendSlice(line[marks[5]..]);
61 try buf.appendSlice(line[marks[3] .. marks[4] + delims[4].len]);
62
63 const file_name = line[marks[4] + delims[4].len .. marks[5]];
64 // The LLVM backend currently uses the object file name in the debug info here.
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]");
6672 } else {
67 try buf.appendSlice(line[marks[3]..]);
73 // Something unexpected; include it verbatim.
74 try buf.appendSlice(file_name);
6875 }
76
77 try buf.appendSlice(line[marks[5]..]);
6978 } else {
7079 try buf.appendSlice(line[marks[3] .. marks[3] + delims[3].len]);
7180 try buf.appendSlice("[function]");
test/stack_traces.zig+30-30
......@@ -13,7 +13,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
1313 .Debug = .{
1414 .expect =
1515 \\error: TheSkyIsFalling
16 \\source.zig:2:5: [address] in main (test)
16 \\source.zig:2:5: [address] in main ([main_file])
1717 \\ return error.TheSkyIsFalling;
1818 \\ ^
1919 \\
......@@ -61,10 +61,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
6161 .Debug = .{
6262 .expect =
6363 \\error: TheSkyIsFalling
64 \\source.zig:2:5: [address] in foo (test)
64 \\source.zig:2:5: [address] in foo ([main_file])
6565 \\ return error.TheSkyIsFalling;
6666 \\ ^
67 \\source.zig:6:5: [address] in main (test)
67 \\source.zig:6:5: [address] in main ([main_file])
6868 \\ try foo();
6969 \\ ^
7070 \\
......@@ -120,7 +120,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
120120 .Debug = .{
121121 .expect =
122122 \\error: UnrelatedError
123 \\source.zig:13:5: [address] in main (test)
123 \\source.zig:13:5: [address] in main ([main_file])
124124 \\ return error.UnrelatedError;
125125 \\ ^
126126 \\
......@@ -172,7 +172,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
172172 .Debug = .{
173173 .expect =
174174 \\error: UnrelatedError
175 \\source.zig:10:5: [address] in main (test)
175 \\source.zig:10:5: [address] in main ([main_file])
176176 \\ return error.UnrelatedError;
177177 \\ ^
178178 \\
......@@ -224,10 +224,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
224224 .Debug = .{
225225 .expect =
226226 \\error: TheSkyIsFalling
227 \\source.zig:2:5: [address] in foo (test)
227 \\source.zig:2:5: [address] in foo ([main_file])
228228 \\ return error.TheSkyIsFalling;
229229 \\ ^
230 \\source.zig:10:5: [address] in main (test)
230 \\source.zig:10:5: [address] in main ([main_file])
231231 \\ try foo();
232232 \\ ^
233233 \\
......@@ -284,7 +284,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
284284 .Debug = .{
285285 .expect =
286286 \\error: BadTime
287 \\source.zig:12:5: [address] in main (test)
287 \\source.zig:12:5: [address] in main ([main_file])
288288 \\ return error.BadTime;
289289 \\ ^
290290 \\
......@@ -332,10 +332,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
332332 .Debug = .{
333333 .expect =
334334 \\error: AndMyCarIsOutOfGas
335 \\source.zig:2:5: [address] in foo (test)
335 \\source.zig:2:5: [address] in foo ([main_file])
336336 \\ return error.TheSkyIsFalling;
337337 \\ ^
338 \\source.zig:6:5: [address] in main (test)
338 \\source.zig:6:5: [address] in main ([main_file])
339339 \\ return foo() catch error.AndMyCarIsOutOfGas;
340340 \\ ^
341341 \\
......@@ -391,7 +391,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
391391 .Debug = .{
392392 .expect =
393393 \\error: SomethingUnrelatedWentWrong
394 \\source.zig:11:5: [address] in main (test)
394 \\source.zig:11:5: [address] in main ([main_file])
395395 \\ return error.SomethingUnrelatedWentWrong;
396396 \\ ^
397397 \\
......@@ -456,13 +456,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
456456 .Debug = .{
457457 .expect =
458458 \\error: StillUnresolved
459 \\source.zig:1:18: [address] in foo (test)
459 \\source.zig:1:18: [address] in foo ([main_file])
460460 \\fn foo() !void { return error.TheSkyIsFalling; }
461461 \\ ^
462 \\source.zig:2:18: [address] in bar (test)
462 \\source.zig:2:18: [address] in bar ([main_file])
463463 \\fn bar() !void { return error.InternalError; }
464464 \\ ^
465 \\source.zig:23:5: [address] in main (test)
465 \\source.zig:23:5: [address] in main ([main_file])
466466 \\ return error.StillUnresolved;
467467 \\ ^
468468 \\
......@@ -527,13 +527,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
527527 .Debug = .{
528528 .expect =
529529 \\error: TestExpectedError
530 \\source.zig:9:18: [address] in foo (test)
530 \\source.zig:9:18: [address] in foo ([main_file])
531531 \\fn foo() !void { return error.Foo; }
532532 \\ ^
533 \\source.zig:5:5: [address] in expectError (test)
533 \\source.zig:5:5: [address] in expectError ([main_file])
534534 \\ return error.TestExpectedError;
535535 \\ ^
536 \\source.zig:17:5: [address] in main (test)
536 \\source.zig:17:5: [address] in main ([main_file])
537537 \\ try expectError(error.Bar, foo());
538538 \\ ^
539539 \\
......@@ -592,13 +592,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
592592 .Debug = .{
593593 .expect =
594594 \\error: AndMyCarIsOutOfGas
595 \\source.zig:2:5: [address] in foo (test)
595 \\source.zig:2:5: [address] in foo ([main_file])
596596 \\ return error.TheSkyIsFalling;
597597 \\ ^
598 \\source.zig:6:5: [address] in bar (test)
598 \\source.zig:6:5: [address] in bar ([main_file])
599599 \\ return error.AndMyCarIsOutOfGas;
600600 \\ ^
601 \\source.zig:11:9: [address] in main (test)
601 \\source.zig:11:9: [address] in main ([main_file])
602602 \\ try bar();
603603 \\ ^
604604 \\
......@@ -657,13 +657,13 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
657657 .Debug = .{
658658 .expect =
659659 \\error: AndMyCarIsOutOfGas
660 \\source.zig:2:5: [address] in foo (test)
660 \\source.zig:2:5: [address] in foo ([main_file])
661661 \\ return error.TheSkyIsFalling;
662662 \\ ^
663 \\source.zig:6:5: [address] in bar (test)
663 \\source.zig:6:5: [address] in bar ([main_file])
664664 \\ return error.AndMyCarIsOutOfGas;
665665 \\ ^
666 \\source.zig:11:9: [address] in main (test)
666 \\source.zig:11:9: [address] in main ([main_file])
667667 \\ try bar();
668668 \\ ^
669669 \\
......@@ -724,16 +724,16 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
724724 .Debug = .{
725725 .expect =
726726 \\error: TheSkyIsFalling
727 \\source.zig:10:5: [address] in make_error (test)
727 \\source.zig:10:5: [address] in make_error ([main_file])
728728 \\ return error.TheSkyIsFalling;
729729 \\ ^
730 \\source.zig:6:5: [address] in bar (test)
730 \\source.zig:6:5: [address] in bar ([main_file])
731731 \\ return make_error();
732732 \\ ^
733 \\source.zig:2:5: [address] in foo (test)
733 \\source.zig:2:5: [address] in foo ([main_file])
734734 \\ try bar();
735735 \\ ^
736 \\source.zig:14:5: [address] in main (test)
736 \\source.zig:14:5: [address] in main ([main_file])
737737 \\ try foo();
738738 \\ ^
739739 \\
......@@ -797,10 +797,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
797797 .windows, // TODO intermittent failures
798798 },
799799 .expect =
800 \\source.zig:7:8: [address] in foo (test)
800 \\source.zig:7:8: [address] in foo ([main_file])
801801 \\ bar();
802802 \\ ^
803 \\source.zig:10:8: [address] in main (test)
803 \\source.zig:10:8: [address] in main ([main_file])
804804 \\ foo();
805805 \\ ^
806806 \\
......@@ -829,7 +829,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
829829 .Debug = .{
830830 .expect =
831831 \\error: TheSkyIsFalling
832 \\source.zig:3:5: [address] in main (test)
832 \\source.zig:3:5: [address] in main ([main_file])
833833 \\ return error.TheSkyIsFalling;
834834 \\ ^
835835 \\