master
  1pub fn addCases(cases: *@import("tests.zig").StackTracesContext) void {
  2    cases.addCase(.{
  3        .name = "simple panic",
  4        .source =
  5        \\pub fn main() void {
  6        \\    foo();
  7        \\}
  8        \\fn foo() void {
  9        \\    @panic("oh no");
 10        \\}
 11        \\
 12        ,
 13        .unwind = .any,
 14        .expect_panic = true,
 15        .expect =
 16        \\panic: oh no
 17        \\source.zig:5:5: [address] in foo
 18        \\    @panic("oh no");
 19        \\    ^
 20        \\source.zig:2:8: [address] in main
 21        \\    foo();
 22        \\       ^
 23        \\
 24        ,
 25        .expect_strip =
 26        \\panic: oh no
 27        \\???:?:?: [address] in source.foo
 28        \\???:?:?: [address] in source.main
 29        \\
 30        ,
 31    });
 32
 33    cases.addCase(.{
 34        .name = "simple panic with no unwind strategy",
 35        .source =
 36        \\pub fn main() void {
 37        \\    foo();
 38        \\}
 39        \\fn foo() void {
 40        \\    @panic("oh no");
 41        \\}
 42        \\
 43        ,
 44        .unwind = .none,
 45        .expect_panic = true,
 46        .expect = "panic: oh no",
 47        .expect_strip = "panic: oh no",
 48    });
 49
 50    cases.addCase(.{
 51        .name = "dump current trace",
 52        .source =
 53        \\pub fn main() void {
 54        \\    foo(bar());
 55        \\}
 56        \\fn bar() void {
 57        \\    qux(123);
 58        \\}
 59        \\fn foo(_: void) void {}
 60        \\fn qux(x: u32) void {
 61        \\    std.debug.dumpCurrentStackTrace(.{});
 62        \\    _ = x;
 63        \\}
 64        \\const std = @import("std");
 65        \\
 66        ,
 67        .unwind = .safe,
 68        .expect_panic = false,
 69        .expect =
 70        \\source.zig:9:36: [address] in qux
 71        \\    std.debug.dumpCurrentStackTrace(.{});
 72        \\                                   ^
 73        \\source.zig:5:8: [address] in bar
 74        \\    qux(123);
 75        \\       ^
 76        \\source.zig:2:12: [address] in main
 77        \\    foo(bar());
 78        \\           ^
 79        \\
 80        ,
 81        .expect_strip =
 82        \\???:?:?: [address] in source.qux
 83        \\???:?:?: [address] in source.bar
 84        \\???:?:?: [address] in source.main
 85        \\
 86        ,
 87    });
 88
 89    cases.addCase(.{
 90        .name = "dump current trace with no unwind strategy",
 91        .source =
 92        \\pub fn main() void {
 93        \\    foo(bar());
 94        \\}
 95        \\fn bar() void {
 96        \\    qux(123);
 97        \\}
 98        \\fn foo(_: void) void {}
 99        \\fn qux(x: u32) void {
100        \\    std.debug.print("pre\n", .{});
101        \\    std.debug.dumpCurrentStackTrace(.{});
102        \\    std.debug.print("post\n", .{});
103        \\    _ = x;
104        \\}
105        \\const std = @import("std");
106        \\
107        ,
108        .unwind = .no_safe,
109        .expect_panic = false,
110        .expect = "pre\npost\n",
111        .expect_strip = "pre\npost\n",
112    });
113
114    cases.addCase(.{
115        .name = "dump captured trace",
116        .source =
117        \\pub fn main() void {
118        \\    var stack_trace_buf: [8]usize = undefined;
119        \\    dumpIt(&captureIt(&stack_trace_buf));
120        \\}
121        \\fn captureIt(buf: []usize) std.builtin.StackTrace {
122        \\    return captureItInner(buf);
123        \\}
124        \\fn dumpIt(st: *const std.builtin.StackTrace) void {
125        \\    std.debug.dumpStackTrace(st);
126        \\}
127        \\fn captureItInner(buf: []usize) std.builtin.StackTrace {
128        \\    return std.debug.captureCurrentStackTrace(.{}, buf);
129        \\}
130        \\const std = @import("std");
131        \\
132        ,
133        .unwind = .safe,
134        .expect_panic = false,
135        .expect =
136        \\source.zig:12:46: [address] in captureItInner
137        \\    return std.debug.captureCurrentStackTrace(.{}, buf);
138        \\                                             ^
139        \\source.zig:6:26: [address] in captureIt
140        \\    return captureItInner(buf);
141        \\                         ^
142        \\source.zig:3:22: [address] in main
143        \\    dumpIt(&captureIt(&stack_trace_buf));
144        \\                     ^
145        \\
146        ,
147        .expect_strip =
148        \\???:?:?: [address] in source.captureItInner
149        \\???:?:?: [address] in source.captureIt
150        \\???:?:?: [address] in source.main
151        \\
152        ,
153    });
154
155    cases.addCase(.{
156        .name = "dump captured trace with no unwind strategy",
157        .source =
158        \\pub fn main() void {
159        \\    var stack_trace_buf: [8]usize = undefined;
160        \\    dumpIt(&captureIt(&stack_trace_buf));
161        \\}
162        \\fn captureIt(buf: []usize) std.builtin.StackTrace {
163        \\    return captureItInner(buf);
164        \\}
165        \\fn dumpIt(st: *const std.builtin.StackTrace) void {
166        \\    std.debug.dumpStackTrace(st);
167        \\}
168        \\fn captureItInner(buf: []usize) std.builtin.StackTrace {
169        \\    return std.debug.captureCurrentStackTrace(.{}, buf);
170        \\}
171        \\const std = @import("std");
172        \\
173        ,
174        .unwind = .no_safe,
175        .expect_panic = false,
176        .expect = "(empty stack trace)\n",
177        .expect_strip = "(empty stack trace)\n",
178    });
179
180    cases.addCase(.{
181        .name = "dump captured trace on thread",
182        .source =
183        \\pub fn main() !void {
184        \\    var stack_trace_buf: [8]usize = undefined;
185        \\    const t = try std.Thread.spawn(.{}, threadMain, .{&stack_trace_buf});
186        \\    t.join();
187        \\}
188        \\fn threadMain(stack_trace_buf: []usize) void {
189        \\    dumpIt(&captureIt(stack_trace_buf));
190        \\}
191        \\fn captureIt(buf: []usize) std.builtin.StackTrace {
192        \\    return captureItInner(buf);
193        \\}
194        \\fn dumpIt(st: *const std.builtin.StackTrace) void {
195        \\    std.debug.dumpStackTrace(st);
196        \\}
197        \\fn captureItInner(buf: []usize) std.builtin.StackTrace {
198        \\    return std.debug.captureCurrentStackTrace(.{}, buf);
199        \\}
200        \\const std = @import("std");
201        \\
202        ,
203        .unwind = .safe,
204        .expect_panic = false,
205        .expect =
206        \\source.zig:16:46: [address] in captureItInner
207        \\    return std.debug.captureCurrentStackTrace(.{}, buf);
208        \\                                             ^
209        \\source.zig:10:26: [address] in captureIt
210        \\    return captureItInner(buf);
211        \\                         ^
212        \\source.zig:7:22: [address] in threadMain
213        \\    dumpIt(&captureIt(stack_trace_buf));
214        \\                     ^
215        \\
216        ,
217        .expect_strip =
218        \\???:?:?: [address] in source.captureItInner
219        \\???:?:?: [address] in source.captureIt
220        \\???:?:?: [address] in source.threadMain
221        \\
222        ,
223    });
224}