authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-01 18:31:06-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 13:00:54-04:00
log980bf80036a896ff01e7395c3887858ebae3e7f7
treeae95303599411dcc30422098104be9eec2c72fc9
parentbac57b3d15b84b1e4d5365acde3a78d98f439de3

Dwarf2: add testing and enable passing tests

- fix some bit-rotted documentation - fix some non-determinism that was causing these tests to be flaky - also update padding on moved/resized events - make `unit_padding` a header node - refactor out `ifPos`

9 files changed, 312 insertions(+), 201 deletions(-)

README.md+13-6
...@@ -781,12 +781,20 @@ If you will be debugging the Zig compiler itself, or if you will be debugging...@@ -781,12 +781,20 @@ If you will be debugging the Zig compiler itself, or if you will be debugging
781any project compiled with Zig's LLVM backend (not recommended with the LLDB781any project compiled with Zig's LLVM backend (not recommended with the LLDB
782fork, prefer vanilla LLDB with a version that matches the version of LLVM that782fork, prefer vanilla LLDB with a version that matches the version of LLVM that
783Zig is using), you can get a better debugging experience by using783Zig is using), you can get a better debugging experience by using
784[`lldb_pretty_printers.py`](https://codeberg.org/ziglang/zig/src/branch/master/tools/lldb_pretty_printers.py).784[`lldb/pretty_printers.py`](https://codeberg.org/ziglang/zig/src/branch/master/lib/lldb/pretty_printers.py)
785which is included in Zig's installed lib dir.
785786
786Put this line in `~/.lldbinit`:787Put this line in `~/.lldbinit`:
787788
788```789```
789command script import /path/to/zig/tools/lldb_pretty_printers.py790command script import /path/to/zig/lib/lldb/pretty_printers.py
791```
792
793If you will be debugging a Zig compiler built using Zig's self-hosted backends,
794you will also want this line:
795
796```
797type category enable zig.compiler
790```798```
791799
792If you will be using Zig's LLVM backend (again, not recommended with the LLDB800If you will be using Zig's LLVM backend (again, not recommended with the LLDB
...@@ -797,10 +805,9 @@ type category enable zig.lang...@@ -797,10 +805,9 @@ type category enable zig.lang
797type category enable zig.std805type category enable zig.std
798```806```
799807
800If you will be debugging a Zig compiler built using Zig's LLVM backend (again,808If you will be debugging a Zig compiler built using Zig's LLVM backend without
801not recommended with the LLDB fork), you will also want this line:809using the LLDB fork, you will also want this line:
802810
803```811```
804type category enable zig.stage2812type category enable zig
805```813```
806
ci/x86_64-linux-debug-llvm.sh+1-1
...@@ -53,7 +53,7 @@ stage3-debug/bin/zig build \...@@ -53,7 +53,7 @@ stage3-debug/bin/zig build \
5353
54stage3-debug/bin/zig build test docs \54stage3-debug/bin/zig build test docs \
55 --maxrss ${ZSF_MAX_RSS:-0} \55 --maxrss ${ZSF_MAX_RSS:-0} \
56 -Dlldb=$HOME/deps/lldb-zig/Debug-7c1090fd46/bin/lldb \56 -Dlldb=$HOME/deps/lldb-zig/Debug-aad646607a/bin/lldb \
57 -Dlibc-test-path=$HOME/deps/libc-test-b95fe84 \57 -Dlibc-test-path=$HOME/deps/libc-test-b95fe84 \
58 -fqemu \58 -fqemu \
59 --libc-runtimes $HOME/deps/glibc-2.43-musl-1.2.5 \59 --libc-runtimes $HOME/deps/glibc-2.43-musl-1.2.5 \
ci/x86_64-linux-debug.sh+1-1
...@@ -53,7 +53,7 @@ stage3-debug/bin/zig build \...@@ -53,7 +53,7 @@ stage3-debug/bin/zig build \
5353
54stage3-debug/bin/zig build test docs \54stage3-debug/bin/zig build test docs \
55 --maxrss ${ZSF_MAX_RSS:-0} \55 --maxrss ${ZSF_MAX_RSS:-0} \
56 -Dlldb=$HOME/deps/lldb-zig/Debug-7c1090fd46/bin/lldb \56 -Dlldb=$HOME/deps/lldb-zig/Debug-aad646607a/bin/lldb \
57 -fqemu \57 -fqemu \
58 --libc-runtimes $HOME/deps/glibc-2.43-musl-1.2.5 \58 --libc-runtimes $HOME/deps/glibc-2.43-musl-1.2.5 \
59 -fwasmtime \59 -fwasmtime \
ci/x86_64-linux-release.sh+1-1
...@@ -61,7 +61,7 @@ stage3-release/bin/zig build \...@@ -61,7 +61,7 @@ stage3-release/bin/zig build \
6161
62stage3-release/bin/zig build test docs \62stage3-release/bin/zig build test docs \
63 --maxrss ${ZSF_MAX_RSS:-0} \63 --maxrss ${ZSF_MAX_RSS:-0} \
64 -Dlldb=$HOME/deps/lldb-zig/Release-7c1090fd46/bin/lldb \64 -Dlldb=$HOME/deps/lldb-zig/Release-aad646607a/bin/lldb \
65 -Dlibc-test-path=$HOME/deps/libc-test-b95fe84 \65 -Dlibc-test-path=$HOME/deps/libc-test-b95fe84 \
66 -fqemu \66 -fqemu \
67 --libc-runtimes $HOME/deps/glibc-2.43-musl-1.2.5 \67 --libc-runtimes $HOME/deps/glibc-2.43-musl-1.2.5 \
src/link/Coff.zig+2-1
...@@ -7736,12 +7736,13 @@ pub fn printNode(...@@ -7736,12 +7736,13 @@ pub fn printNode(
7736 {7736 {
7737 const mf_node = &coff.mf.nodes.items[@backingInt(ni)];7737 const mf_node = &coff.mf.nodes.items[@backingInt(ni)];
7738 const off, const size = mf_node.location().resolve(&coff.mf);7738 const off, const size = mf_node.location().resolve(&coff.mf);
7739 try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x} {t}{s}{s}{s}\n", .{7739 try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x} {t}{s}{s}{s}{s}\n", .{
7740 @backingInt(ni),7740 @backingInt(ni),
7741 off,7741 off,
7742 size,7742 size,
7743 mf_node.flags.alignment.toByteUnits(),7743 mf_node.flags.alignment.toByteUnits(),
7744 mf_node.flags.position,7744 mf_node.flags.position,
7745 if (mf_node.flags.bubbles_moved) " bubbles_moved" else "",
7745 if (mf_node.flags.moved) " moved" else "",7746 if (mf_node.flags.moved) " moved" else "",
7746 if (mf_node.flags.resized) " resized" else "",7747 if (mf_node.flags.resized) " resized" else "",
7747 if (mf_node.flags.has_content) " has_content" else "",7748 if (mf_node.flags.has_content) " has_content" else "",
src/link/Elf2.zig+150-94
...@@ -7241,7 +7241,16 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7241,7 +7241,16 @@ fn prelinkInner(elf: *Elf) Error!void {
7241 const debug_ni = debug_shndx.get(elf).ni;7241 const debug_ni = debug_shndx.get(elf).ni;
7242 const frame_format = debug_shndx.debugFrameFormat(elf);7242 const frame_format = debug_shndx.debugFrameFormat(elf);
7243 const unit_padding_ni = elf.addNodeAssumeCapacity(7243 const unit_padding_ni = elf.addNodeAssumeCapacity(
7244 try debug_ni.addFloatingChild(gpa, &elf.mf, .{7244 try debug_ni.addHeaderChildAfter(gpa, &elf.mf, last_header_oni: {
7245 var last_header_oni = debug_ni.last(&elf.mf);
7246 while (last_header_oni.unwrap()) |last_header_ni|
7247 switch (last_header_ni.position(&elf.mf)) {
7248 .header => break,
7249 .footer => last_header_oni = last_header_ni.prev(&elf.mf),
7250 .floating => unreachable,
7251 };
7252 break :last_header_oni last_header_oni;
7253 }, .{
7245 .alignment = if (frame_format) |_| switch (elf.identClass()) {7254 .alignment = if (frame_format) |_| switch (elf.identClass()) {
7246 .NONE, _ => unreachable,7255 .NONE, _ => unreachable,
7247 .@"32" => .@"4",7256 .@"32" => .@"4",
...@@ -9311,7 +9320,7 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {...@@ -9311,7 +9320,7 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {
9311 defer sub_prog_node.end();9320 defer sub_prog_node.end();
9312 if (clean_moved) try elf.flushMoved(ni);9321 if (clean_moved) try elf.flushMoved(ni);
9313 if (clean_resized) try elf.flushResized(ni);9322 if (clean_resized) try elf.flushResized(ni);
9314 if (clean_next_moved) try elf.flushNextMoved(ni);9323 if (clean_moved or clean_resized or clean_next_moved) try elf.flushPadding(ni);
9315 break :task;9324 break :task;
9316 }9325 }
9317 }9326 }
...@@ -10248,12 +10257,12 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo...@@ -10248,12 +10257,12 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo
10248 }10257 }
10249}10258}
1025010259
10251fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void {10260fn flushPadding(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void {
10252 const trace = tracy.trace(@src());10261 const trace = tracy.trace(@src());
10253 defer trace.end();10262 defer trace.end();
1025410263
10255 switch (elf.getNode(ni)) {10264 switch (elf.getNode(ni)) {
10256 .deleted,10265 .deleted => unreachable,
10257 .archive,10266 .archive,
10258 .archive_input_member,10267 .archive_input_member,
10259 .archive_elf_member_header,10268 .archive_elf_member_header,
...@@ -10272,7 +10281,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -10272,7 +10281,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
10272 .debug_shared,10281 .debug_shared,
10273 .eh_frame_footer,10282 .eh_frame_footer,
10274 .unit_debug_info_footer,10283 .unit_debug_info_footer,
10275 => unreachable,10284 => {},
1027610285
10277 .archive_header => {10286 .archive_header => {
10278 const archive = &elf.archive.?;10287 const archive = &elf.archive.?;
...@@ -10314,94 +10323,139 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -10314,94 +10323,139 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
10314 => |_, tag| {10323 => |_, tag| {
10315 const offset, const size = ni.location(&elf.mf).resolve(&elf.mf);10324 const offset, const size = ni.location(&elf.mf).resolve(&elf.mf);
10316 const parent_ni = ni.parent(&elf.mf).unwrap().?;10325 const parent_ni = ni.parent(&elf.mf).unwrap().?;
10317 const slice = if (ni.next(&elf.mf).ifPos(&elf.mf, .floating).unwrap()) |next_ni| slice: {10326 const slice = slice: {
10318 const parent_slice = parent_ni.slicePadding(&elf.mf);10327 if (ni.next(&elf.mf).unwrap()) |next_ni| switch (next_ni.position(&elf.mf)) {
10319 const next_offset, _ = next_ni.location(&elf.mf).resolve(&elf.mf);10328 .header => unreachable,
10320 break :slice parent_slice[@intCast(offset)..@intCast(next_offset)];10329 .footer => {},
10321 } else slice: switch (tag) {10330 .floating => {
10322 else => unreachable,10331 const parent_slice = parent_ni.slicePadding(&elf.mf);
10323 .unit_padding, .unit_debug_rnglists => {10332 const next_offset, _ = next_ni.location(&elf.mf).resolve(&elf.mf);
10324 const parent_slice = parent_ni.slicePadding(&elf.mf);10333 break :slice parent_slice[@intCast(offset)..@intCast(next_offset)];
10325 const frame_shndx = elf.getNodeShndx(parent_ni);10334 },
10326 const frame_format = frame_shndx.debugFrameFormat(elf) orelse10335 };
10327 break :slice parent_slice[@intCast(offset)..];10336 switch (tag) {
10328 const footer_size = elf.debugFrameFooterSize(frame_format);10337 else => unreachable,
10329 @memset(parent_slice[@intCast(offset + size)..][0..footer_size], 0);10338 .unit_padding, .unit_debug_rnglists => {
10330 frame_shndx.setSize(elf, offset + size + footer_size);10339 const parent_slice = parent_ni.slicePadding(&elf.mf);
10331 break :slice parent_slice[@intCast(offset)..][0..@intCast(size)];10340 const frame_shndx = elf.getNodeShndx(parent_ni);
10332 },10341 const frame_format = frame_shndx.debugFrameFormat(elf) orelse
10333 .unit_frame_cie, .func_frame_fde => {10342 break :slice parent_slice[@intCast(offset)..];
10334 const parent_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);10343 const footer_size = elf.debugFrameFooterSize(frame_format);
10335 const frame_ni = parent_ni.parent(&elf.mf).unwrap().?;10344 @memset(parent_slice[@intCast(offset + size)..][0..footer_size], 0);
10336 const frame_slice = frame_ni.slicePadding(&elf.mf);10345 frame_shndx.setSize(elf, offset + size + footer_size);
10337 const frame_shndx = elf.getNode(frame_ni).section_manual_size;10346 break :slice parent_slice[@intCast(offset)..][0..@intCast(size)];
10338 const frame_format = frame_shndx.debugFrameFormat(elf).?;10347 },
10339 if (parent_ni.next(&elf.mf).ifPos(&elf.mf, .floating).unwrap()) |parent_next_ni| {10348 .unit_frame_cie, .func_frame_fde => {
10340 const parent_next_offset, _ = parent_next_ni.location(&elf.mf).resolve(&elf.mf);10349 const parent_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
10341 const slice =10350 const frame_ni = parent_ni.parent(&elf.mf).unwrap().?;
10342 frame_slice[@intCast(parent_offset + offset)..@intCast(parent_next_offset)];10351 const frame_slice = frame_ni.slicePadding(&elf.mf);
10343 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);10352 const frame_shndx = elf.getNode(frame_ni).section_manual_size;
10344 elf.dwarf.genDebugFrameCie(&fw, null, frame_format) catch |err| switch (err) {10353 const frame_format = frame_shndx.debugFrameFormat(elf).?;
10345 error.WriteFailed => break :slice slice,10354 if (parent_ni.next(&elf.mf).unwrap()) |parent_next_ni| {
10346 };10355 switch (parent_next_ni.position(&elf.mf)) {
10347 elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len);10356 .header => unreachable,
10348 break :slice slice[0..@intCast(size)];10357 .footer => {},
10349 }10358 .floating => {
10350 const footer_size = elf.debugFrameFooterSize(frame_format);10359 const parent_next_offset, _ =
10351 @memset(frame_slice[@intCast(parent_offset + offset + size)..][0..footer_size], 0);10360 parent_next_ni.location(&elf.mf).resolve(&elf.mf);
10352 frame_shndx.setSize(elf, parent_offset + offset + size + footer_size);10361 const slice = frame_slice[@intCast(
10353 break :slice frame_slice[@intCast(parent_offset + offset)..][0..@intCast(size)];10362 parent_offset + offset,
10354 },10363 )..@intCast(parent_next_offset)];
10355 .unit_debug_info_header,10364 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);
10356 .unit_debug_line_header,10365 elf.dwarf.genDebugFrameCie(
10357 .const_debug_info,10366 &fw,
10358 .global_debug_info,10367 null,
10359 .func_debug_info,10368 frame_format,
10360 .func_debug_line,10369 ) catch |err| switch (err) {
10361 .decl_debug_info,10370 error.WriteFailed => break :slice slice,
10362 => {10371 };
10363 const parent_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);10372 elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len);
10364 const debug_ni = parent_ni.parent(&elf.mf).unwrap().?;10373 break :slice slice[0..@intCast(size)];
10365 const debug_slice = debug_ni.slicePadding(&elf.mf);
10366 var fw: Io.Writer = .fixed(debug_slice[@intCast(parent_offset)..if (parent_ni
10367 .next(&elf.mf).ifPos(&elf.mf, .floating).unwrap()) |parent_next_ni|
10368 debug_end: {
10369 const parent_next_offset, _ = parent_next_ni.location(&elf.mf).resolve(&elf.mf);
10370 break :debug_end @intCast(parent_next_offset);
10371 } else debug_slice.len]);
10372 fw.end = @intCast(offset + size);
10373 switch (tag) {
10374 else => unreachable,
10375 .unit_debug_info_header,
10376 .const_debug_info,
10377 .global_debug_info,
10378 .func_debug_info,
10379 .decl_debug_info,
10380 => for (0..2) |_| fw.writeUleb128(@backingInt(Dwarf.AbbrevCode.null)) catch unreachable,
10381 .unit_debug_line_header, .func_debug_line => {},
10382 }
10383 const unit_padding_offset = fw.end;
10384 const unit_padding = fw.unusedCapacitySlice();
10385 elf.dwarf.genUnitPadding(&fw) catch |err| switch (err) {
10386 error.WriteFailed => {
10387 fw.end = unit_padding_offset;
10388 elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len);
10389 switch (tag) {
10390 else => unreachable,
10391 .unit_debug_info_header, .const_debug_info, .global_debug_info, .func_debug_info, .decl_debug_info => {
10392 comptime assert(Dwarf.uleb128Size(@backingInt(Dwarf.AbbrevCode.null)) == 1);
10393 @memset(fw.unusedCapacitySlice(), @backingInt(Dwarf.AbbrevCode.null));
10394 },10374 },
10395 .unit_debug_line_header, .func_debug_line => Dwarf.genDebugLinePadding(&fw, fw.unusedCapacityLen()) catch
10396 unreachable,
10397 }10375 }
10398 return;10376 }
10399 },10377 const footer_size = elf.debugFrameFooterSize(frame_format);
10400 };10378 @memset(
10401 elf.dwarf.updateUnitLength(fw.buffer, unit_padding_offset);10379 frame_slice[@intCast(parent_offset + offset + size)..][0..footer_size],
10402 elf.dwarf.updateUnitLength(unit_padding, unit_padding.len);10380 0,
10403 return;10381 );
10404 },10382 frame_shndx.setSize(elf, parent_offset + offset + size + footer_size);
10383 break :slice frame_slice[@intCast(parent_offset + offset)..][0..@intCast(size)];
10384 },
10385 .unit_debug_info_header,
10386 .unit_debug_line_header,
10387 .const_debug_info,
10388 .global_debug_info,
10389 .func_debug_info,
10390 .func_debug_line,
10391 .decl_debug_info,
10392 => {
10393 const parent_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
10394 const debug_ni = parent_ni.parent(&elf.mf).unwrap().?;
10395 const debug_slice = debug_ni.slicePadding(&elf.mf);
10396 var fw: Io.Writer = .fixed(buffer: {
10397 if (parent_ni.next(&elf.mf).unwrap()) |parent_next_ni| {
10398 switch (parent_next_ni.position(&elf.mf)) {
10399 .header => unreachable,
10400 .footer => {},
10401 .floating => {
10402 const parent_next_offset, _ =
10403 parent_next_ni.location(&elf.mf).resolve(&elf.mf);
10404 break :buffer debug_slice[@intCast(
10405 parent_offset,
10406 )..@intCast(parent_next_offset)];
10407 },
10408 }
10409 }
10410 break :buffer debug_slice[@intCast(parent_offset)..];
10411 });
10412 fw.end = @intCast(offset + size);
10413 switch (tag) {
10414 else => unreachable,
10415 .unit_debug_info_header,
10416 .const_debug_info,
10417 .global_debug_info,
10418 .func_debug_info,
10419 .decl_debug_info,
10420 => for (0..2) |_| fw.writeUleb128(@backingInt(Dwarf.AbbrevCode.null)) catch
10421 unreachable,
10422 .unit_debug_line_header, .func_debug_line => {},
10423 }
10424 const unit_padding_offset = fw.end;
10425 const unit_padding = fw.unusedCapacitySlice();
10426 elf.dwarf.genUnitPadding(&fw) catch |err| switch (err) {
10427 error.WriteFailed => {
10428 fw.end = unit_padding_offset;
10429 elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len);
10430 switch (tag) {
10431 else => unreachable,
10432 .unit_debug_info_header,
10433 .const_debug_info,
10434 .global_debug_info,
10435 .func_debug_info,
10436 .decl_debug_info,
10437 => {
10438 comptime assert(
10439 Dwarf.uleb128Size(@backingInt(Dwarf.AbbrevCode.null)) == 1,
10440 );
10441 @memset(
10442 fw.unusedCapacitySlice(),
10443 @backingInt(Dwarf.AbbrevCode.null),
10444 );
10445 },
10446 .unit_debug_line_header,
10447 .func_debug_line,
10448 => Dwarf.genDebugLinePadding(&fw, fw.unusedCapacityLen()) catch
10449 unreachable,
10450 }
10451 return;
10452 },
10453 };
10454 elf.dwarf.updateUnitLength(fw.buffer, unit_padding_offset);
10455 elf.dwarf.updateUnitLength(unit_padding, unit_padding.len);
10456 return;
10457 },
10458 }
10405 };10459 };
10406 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);10460 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);
10407 switch (tag) {10461 switch (tag) {
...@@ -11007,15 +11061,17 @@ pub fn printNode(...@@ -11007,15 +11061,17 @@ pub fn printNode(
11007 {11061 {
11008 const mf_node = &elf.mf.nodes.items[@backingInt(ni)];11062 const mf_node = &elf.mf.nodes.items[@backingInt(ni)];
11009 const off, const size = mf_node.location().resolve(&elf.mf);11063 const off, const size = mf_node.location().resolve(&elf.mf);
11010 try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x} {t}{s}{s}{s}{s}\n", .{11064 try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x} {t}{s}{s}{s}{s}{s}{s}\n", .{
11011 @backingInt(ni),11065 @backingInt(ni),
11012 off,11066 off,
11013 size,11067 size,
11014 mf_node.flags.alignment.toByteUnits(),11068 mf_node.flags.alignment.toByteUnits(),
11015 mf_node.flags.position,11069 mf_node.flags.position,
11016 if (mf_node.flags.moved) " moved" else "",11070 if (mf_node.flags.bubbles_moved) " bubbles_moved" else "",
11017 if (mf_node.flags.next_moved) " next_moved" else "",11071 if (mf_node.flags.resized) " moved" else "",
11018 if (mf_node.flags.resized) " resized" else "",11072 if (mf_node.flags.resized) " resized" else "",
11073 if (mf_node.flags.enable_next_moved) " enable_next_moved" else "",
11074 if (mf_node.flags.next_moved) " next_moved" else "",
11019 if (mf_node.flags.has_content) " has_content" else "",11075 if (mf_node.flags.has_content) " has_content" else "",
11020 });11076 });
11021 }11077 }
src/link/MappedFile.zig+2-8
...@@ -355,10 +355,6 @@ pub const Node = extern struct {...@@ -355,10 +355,6 @@ pub const Node = extern struct {
355 assert(oi != .none);355 assert(oi != .none);
356 return oi;356 return oi;
357 }357 }
358
359 pub fn ifPos(oi: Optional, mf: *const MappedFile, pos: Node.Position) Optional {
360 return if ((oi.unwrap() orelse return .none).position(mf) == pos) oi else .none;
361 }
362 };358 };
363359
364 fn get(ni: Node.Index, mf: *const MappedFile) *Node {360 fn get(ni: Node.Index, mf: *const MappedFile) *Node {
...@@ -518,12 +514,10 @@ pub const Node = extern struct {...@@ -518,12 +514,10 @@ pub const Node = extern struct {
518 return node_moved.*;514 return node_moved.*;
519 }515 }
520 pub fn movedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void {516 pub fn movedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void {
521 if (ni.hasMoved(mf)) return;
522 const node = ni.get(mf);517 const node = ni.get(mf);
518 if (node.prev.unwrap()) |prev_ni| prev_ni.nextMovedAssumeCapacity(mf);
519 if (ni.hasMoved(mf)) return;
523 node.flags.moved = true;520 node.flags.moved = true;
524 if (node.prev.unwrap()) |prev_ni| {
525 prev_ni.nextMovedAssumeCapacity(mf);
526 }
527 if (node.flags.resized or node.flags.next_moved) return;521 if (node.flags.resized or node.flags.next_moved) return;
528 mf.updates.appendAssumeCapacity(ni);522 mf.updates.appendAssumeCapacity(ni);
529 mf.update_prog_node.increaseEstimatedTotalItems(1);523 mf.update_prog_node.increaseEstimatedTotalItems(1);
test/src/Debugger.zig+101-71
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1b: *std.Build,1b: *std.Build,
2options: Options,2options: Options,
3root_step: *std.Build.Step,3root_step: *std.Build.Step,
4test_matrix: []const TestTarget,
45
5pub const Options = struct {6pub const Options = struct {
6 test_filters: []const []const u8,7 test_filters: []const []const u8,
...@@ -12,19 +13,20 @@ pub const Options = struct {...@@ -12,19 +13,20 @@ pub const Options = struct {
12 skip_libc: bool,13 skip_libc: bool,
13};14};
1415
15pub const Target = struct {16pub const TestTarget = struct {
16 resolved: std.Build.ResolvedTarget,17 target: std.Target.Query,
17 optimize_mode: std.builtin.Optimize = .debug,18 optimize_mode: std.builtin.Optimize = .debug,
18 link_libc: ?bool = null,19 link_libc: ?bool = null,
19 single_threaded: ?bool = null,20 single_threaded: ?bool = null,
20 pic: ?bool = null,21 pic: ?bool = null,
21 test_name_suffix: []const u8,22 linker: LinkerImpl,
22};23};
2324
24pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {25pub const LinkerImpl = enum { default, old, new };
26
27pub fn addTests(db: *Debugger) void {
25 db.addLldbTest(28 db.addLldbTest(
26 "basic",29 "basic",
27 target,
28 &.{30 &.{
29 .{31 .{
30 .path = "basic.zig",32 .path = "basic.zig",
...@@ -179,10 +181,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -179,10 +181,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
179 \\(lldb) breakpoint delete --force 1181 \\(lldb) breakpoint delete --force 1
180 \\1 breakpoints deleted; 0 breakpoint locations disabled.182 \\1 breakpoints deleted; 0 breakpoint locations disabled.
181 },183 },
184 .{},
182 );185 );
183 db.addLldbTest(186 db.addLldbTest(
184 "identifiers",187 "identifiers",
185 target,
186 &.{188 &.{
187 .{189 .{
188 .path = "identifiers.zig",190 .path = "identifiers.zig",
...@@ -214,10 +216,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -214,10 +216,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
214 \\(lldb) breakpoint delete --force 1216 \\(lldb) breakpoint delete --force 1
215 \\1 breakpoints deleted; 0 breakpoint locations disabled.217 \\1 breakpoints deleted; 0 breakpoint locations disabled.
216 },218 },
219 .{},
217 );220 );
218 db.addLldbTest(221 db.addLldbTest(
219 "types",222 "types",
220 target,
221 &.{223 &.{
222 .{224 .{
223 .path = "types.zig",225 .path = "types.zig",
...@@ -282,10 +284,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -282,10 +284,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
282 \\(lldb) breakpoint delete --force 1284 \\(lldb) breakpoint delete --force 1
283 \\1 breakpoints deleted; 0 breakpoint locations disabled.285 \\1 breakpoints deleted; 0 breakpoint locations disabled.
284 },286 },
287 .{},
285 );288 );
286 db.addLldbTest(289 db.addLldbTest(
287 "pointers",290 "pointers",
288 target,
289 &.{291 &.{
290 .{292 .{
291 .path = "pointers.zig",293 .path = "pointers.zig",
...@@ -419,10 +421,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -419,10 +421,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
419 \\(lldb) breakpoint delete --force 1421 \\(lldb) breakpoint delete --force 1
420 \\1 breakpoints deleted; 0 breakpoint locations disabled.422 \\1 breakpoints deleted; 0 breakpoint locations disabled.
421 },423 },
424 .{},
422 );425 );
423 db.addLldbTest(426 db.addLldbTest(
424 "strings",427 "strings",
425 target,
426 &.{428 &.{
427 .{429 .{
428 .path = "strings.zig",430 .path = "strings.zig",
...@@ -495,10 +497,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -495,10 +497,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
495 \\(lldb) breakpoint delete --force 1497 \\(lldb) breakpoint delete --force 1
496 \\1 breakpoints deleted; 0 breakpoint locations disabled.498 \\1 breakpoints deleted; 0 breakpoint locations disabled.
497 },499 },
500 .{},
498 );501 );
499 db.addLldbTest(502 db.addLldbTest(
500 "enums",503 "enums",
501 target,
502 &.{504 &.{
503 .{505 .{
504 .path = "enums.zig",506 .path = "enums.zig",
...@@ -557,10 +559,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -557,10 +559,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
557 \\(lldb) breakpoint delete --force 1559 \\(lldb) breakpoint delete --force 1
558 \\1 breakpoints deleted; 0 breakpoint locations disabled.560 \\1 breakpoints deleted; 0 breakpoint locations disabled.
559 },561 },
562 .{ .skip_new_linker = true }, // passes, but prints errors
560 );563 );
561 db.addLldbTest(564 db.addLldbTest(
562 "errors",565 "errors",
563 target,
564 &.{566 &.{
565 .{567 .{
566 .path = "errors.zig",568 .path = "errors.zig",
...@@ -627,10 +629,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -627,10 +629,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
627 \\(lldb) breakpoint delete --force 1629 \\(lldb) breakpoint delete --force 1
628 \\1 breakpoints deleted; 0 breakpoint locations disabled.630 \\1 breakpoints deleted; 0 breakpoint locations disabled.
629 },631 },
632 .{ .skip_new_linker = true },
630 );633 );
631 db.addLldbTest(634 db.addLldbTest(
632 "optionals",635 "optionals",
633 target,
634 &.{636 &.{
635 .{637 .{
636 .path = "optionals.zig",638 .path = "optionals.zig",
...@@ -681,10 +683,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -681,10 +683,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
681 \\(lldb) breakpoint delete --force 2683 \\(lldb) breakpoint delete --force 2
682 \\1 breakpoints deleted; 0 breakpoint locations disabled.684 \\1 breakpoints deleted; 0 breakpoint locations disabled.
683 },685 },
686 .{},
684 );687 );
685 db.addLldbTest(688 db.addLldbTest(
686 "unions",689 "unions",
687 target,
688 &.{690 &.{
689 .{691 .{
690 .path = "unions.zig",692 .path = "unions.zig",
...@@ -766,10 +768,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -766,10 +768,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
766 \\(lldb) breakpoint delete --force 1768 \\(lldb) breakpoint delete --force 1
767 \\1 breakpoints deleted; 0 breakpoint locations disabled.769 \\1 breakpoints deleted; 0 breakpoint locations disabled.
768 },770 },
771 .{ .skip_new_linker = true }, // passes, but prints errors
769 );772 );
770 db.addLldbTest(773 db.addLldbTest(
771 "storage",774 "storage",
772 target,
773 &.{775 &.{
774 .{776 .{
775 .path = "storage.zig",777 .path = "storage.zig",
...@@ -866,10 +868,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -866,10 +868,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
866 \\(lldb) breakpoint delete --force 1868 \\(lldb) breakpoint delete --force 1
867 \\1 breakpoints deleted; 0 breakpoint locations disabled.869 \\1 breakpoints deleted; 0 breakpoint locations disabled.
868 },870 },
871 .{ .skip_new_linker = true },
869 );872 );
870 db.addLldbTest(873 db.addLldbTest(
871 "if_blocks",874 "if_blocks",
872 target,
873 &.{875 &.{
874 .{876 .{
875 .path = "if_blocks.zig",877 .path = "if_blocks.zig",
...@@ -908,10 +910,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -908,10 +910,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
908 \\(lldb) breakpoint delete --force 1910 \\(lldb) breakpoint delete --force 1
909 \\1 breakpoints deleted; 0 breakpoint locations disabled.911 \\1 breakpoints deleted; 0 breakpoint locations disabled.
910 },912 },
913 .{},
911 );914 );
912 db.addLldbTest(915 db.addLldbTest(
913 "switch_blocks",916 "switch_blocks",
914 target,
915 &.{917 &.{
916 .{918 .{
917 .path = "switch_blocks.zig",919 .path = "switch_blocks.zig",
...@@ -953,10 +955,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -953,10 +955,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
953 \\(lldb) breakpoint delete --force 1955 \\(lldb) breakpoint delete --force 1
954 \\1 breakpoints deleted; 0 breakpoint locations disabled.956 \\1 breakpoints deleted; 0 breakpoint locations disabled.
955 },957 },
958 .{},
956 );959 );
957 db.addLldbTest(960 db.addLldbTest(
958 "step_single_stmt_loops",961 "step_single_stmt_loops",
959 target,
960 &.{962 &.{
961 .{963 .{
962 .path = "step_single_stmt_loops.zig",964 .path = "step_single_stmt_loops.zig",
...@@ -1371,10 +1373,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -1371,10 +1373,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
1371 \\(lldb) frame variable --show-all-children x1373 \\(lldb) frame variable --show-all-children x
1372 \\(u32) x = 121374 \\(u32) x = 12
1373 },1375 },
1376 .{},
1374 );1377 );
1375 db.addLldbTest(1378 db.addLldbTest(
1376 "inline_call",1379 "inline_call",
1377 target,
1378 &.{1380 &.{
1379 .{1381 .{
1380 .path = "root0.zig",1382 .path = "root0.zig",
...@@ -1944,10 +1946,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -1944,10 +1946,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
1944 \\ frame #1: inline_call`m1pfi(m1pai=89) at mod1.zig:23:151946 \\ frame #1: inline_call`m1pfi(m1pai=89) at mod1.zig:23:15
1945 \\ frame #2: inline_call`root0.main at root0.zig:41:151947 \\ frame #2: inline_call`root0.main at root0.zig:41:15
1946 },1948 },
1949 .{ .skip_new_linker = true },
1947 );1950 );
1948 db.addLldbTest(1951 db.addLldbTest(
1949 "link_object",1952 "link_object",
1950 target,
1951 &.{1953 &.{
1952 .{1954 .{
1953 .path = "main.zig",1955 .path = "main.zig",
...@@ -1983,10 +1985,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -1983,10 +1985,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
1983 \\(lldb) breakpoint delete --force 21985 \\(lldb) breakpoint delete --force 2
1984 \\1 breakpoints deleted; 0 breakpoint locations disabled.1986 \\1 breakpoints deleted; 0 breakpoint locations disabled.
1985 },1987 },
1988 .{},
1986 );1989 );
1987 db.addLldbTest(1990 db.addLldbTest(
1988 "hash_map",1991 "hash_map",
1989 target,
1990 &.{1992 &.{
1991 .{1993 .{
1992 .path = "main.zig",1994 .path = "main.zig",
...@@ -2052,10 +2054,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -2052,10 +2054,10 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
2052 \\(lldb) breakpoint delete --force 12054 \\(lldb) breakpoint delete --force 1
2053 \\1 breakpoints deleted; 0 breakpoint locations disabled.2055 \\1 breakpoints deleted; 0 breakpoint locations disabled.
2054 },2056 },
2057 .{ .skip_new_linker = true },
2055 );2058 );
2056 db.addLldbTest(2059 db.addLldbTest(
2057 "multi_array_list",2060 "multi_array_list",
2058 target,
2059 &.{2061 &.{
2060 .{2062 .{
2061 .path = "main.zig",2063 .path = "main.zig",
...@@ -2306,22 +2308,26 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {...@@ -2306,22 +2308,26 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
2306 \\(lldb) breakpoint delete --force 12308 \\(lldb) breakpoint delete --force 1
2307 \\1 breakpoints deleted; 0 breakpoint locations disabled.2309 \\1 breakpoints deleted; 0 breakpoint locations disabled.
2308 },2310 },
2311 .{ .skip_new_linker = true },
2309 );2312 );
2310}2313}
23112314
2312const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 };2315const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 };
23132316
2317const TestOptions = struct {
2318 skip_new_linker: bool = false,
2319};
2320
2314fn addGdbTest(2321fn addGdbTest(
2315 db: *Debugger,2322 db: *Debugger,
2316 name: []const u8,2323 name: []const u8,
2317 target: *const Target,
2318 files: []const File,2324 files: []const File,
2319 commands: []const u8,2325 commands: []const u8,
2320 expected_output: []const []const u8,2326 expected_output: []const []const u8,
2327 options: TestOptions,
2321) void {2328) void {
2322 db.addTest(2329 db.addTest(
2323 name,2330 name,
2324 target,
2325 files,2331 files,
2326 &.{},2332 &.{},
2327 &.{2333 &.{
...@@ -2331,24 +2337,22 @@ fn addGdbTest(...@@ -2331,24 +2337,22 @@ fn addGdbTest(
2331 },2337 },
2332 "set remotetimeout 0",2338 "set remotetimeout 0",
2333 commands,2339 commands,
2334 &.{2340 &.{"--args"},
2335 "--args",
2336 },
2337 expected_output,2341 expected_output,
2342 options,
2338 );2343 );
2339}2344}
23402345
2341fn addLldbTest(2346fn addLldbTest(
2342 db: *Debugger,2347 db: *Debugger,
2343 name: []const u8,2348 name: []const u8,
2344 target: *const Target,
2345 files: []const File,2349 files: []const File,
2346 commands: []const u8,2350 commands: []const u8,
2347 expected_output: []const []const u8,2351 expected_output: []const []const u8,
2352 options: TestOptions,
2348) void {2353) void {
2349 db.addTest(2354 db.addTest(
2350 name,2355 name,
2351 target,
2352 files,2356 files,
2353 &.{.{ "LANG", "C.UTF-8" }}, // affects output formatting2357 &.{.{ "LANG", "C.UTF-8" }}, // affects output formatting
2354 &.{2358 &.{
...@@ -2358,10 +2362,9 @@ fn addLldbTest(...@@ -2358,10 +2362,9 @@ fn addLldbTest(
2358 },2362 },
2359 "settings set plugin.process.gdb-remote.packet-timeout 0",2363 "settings set plugin.process.gdb-remote.packet-timeout 0",
2360 commands,2364 commands,
2361 &.{2365 &.{"--"},
2362 "--",
2363 },
2364 expected_output,2366 expected_output,
2367 options,
2365 );2368 );
2366}2369}
23672370
...@@ -2373,7 +2376,6 @@ const success = 99;...@@ -2373,7 +2376,6 @@ const success = 99;
2373fn addTest(2376fn addTest(
2374 db: *Debugger,2377 db: *Debugger,
2375 name: []const u8,2378 name: []const u8,
2376 target: *const Target,
2377 files: []const File,2379 files: []const File,
2378 env: []const struct { []const u8, []const u8 },2380 env: []const struct { []const u8, []const u8 },
2379 db_argv1: []const []const u8,2381 db_argv1: []const []const u8,
...@@ -2381,57 +2383,85 @@ fn addTest(...@@ -2381,57 +2383,85 @@ fn addTest(
2381 commands: []const u8,2383 commands: []const u8,
2382 db_argv2: []const []const u8,2384 db_argv2: []const []const u8,
2383 expected_output: []const []const u8,2385 expected_output: []const []const u8,
2386 options: TestOptions,
2384) void {2387) void {
2385 if (db.options.test_filters.len > 0) {2388 if (db.options.test_filters.len > 0) {
2386 for (db.options.test_filters) |test_filter| {2389 for (db.options.test_filters) |test_filter| {
2387 if (std.mem.find(u8, name, test_filter) != null) break;2390 if (std.mem.find(u8, name, test_filter) != null) break;
2388 } else return;2391 } else return;
2389 }2392 }
2390 if (db.options.test_target_filters.len > 0) {
2391 const triple_txt = target.resolved.query.zigTriple(db.b.allocator) catch @panic("OOM");
2392 for (db.options.test_target_filters) |filter| {
2393 if (std.mem.find(u8, triple_txt, filter) != null) break;
2394 } else return;
2395 }
2396 const files_wf = db.b.addWriteFiles();
23972393
2398 const mod = db.b.createModule(.{2394 const wf = db.b.addWriteFiles();
2399 .target = target.resolved,2395 const root_source_file = wf.add(files[0].path, files[0].source);
2400 .root_source_file = files_wf.add(files[0].path, files[0].source),2396 var imports: std.array_hash_map.String(*std.Build.Module) = .empty;
2401 .optimize = target.optimize_mode,
2402 .link_libc = target.link_libc,
2403 .single_threaded = target.single_threaded,
2404 .pic = target.pic,
2405 .strip = false,
2406 });
2407 for (files[1..]) |file| {2397 for (files[1..]) |file| {
2408 const path = files_wf.add(file.path, file.source);2398 const path = wf.add(file.path, file.source);
2409 if (file.import) |import| mod.addImport(import, db.b.createModule(.{2399 if (file.import) |import| imports.putNoClobber(db.b.allocator, import, db.b.createModule(.{
2410 .root_source_file = path,2400 .root_source_file = path,
2411 }));2401 })) catch @panic("OOM");
2412 }2402 }
24132403 const commands_file = wf.add(
2414 const exe = db.b.addExecutable(.{
2415 .name = name,
2416 .root_module = mod,
2417 .use_llvm = false,
2418 .use_lld = false,
2419 });
2420
2421 const commands_wf = db.b.addWriteFiles();
2422 const run = std.Build.Step.Run.create(db.b, db.b.fmt("run {s} {s}", .{ name, target.test_name_suffix }));
2423 for (env) |env_var| run.setEnvironmentVariable(env_var[0], env_var[1]);
2424 run.addArgs(db_argv1);
2425 run.addFileArg(commands_wf.add(
2426 db.b.fmt("{s}.cmd", .{name}),2404 db.b.fmt("{s}.cmd", .{name}),
2427 db.b.fmt("{s}\n\n{s}\n\nquit {d}\n", .{ db_commands, commands, success }),2405 db.b.fmt("{s}\n\n{s}\n\nquit {d}\n", .{ db_commands, commands, success }),
2428 ));2406 );
2429 run.addArgs(db_argv2);2407
2430 run.addArtifactArg(exe);2408 for (db.test_matrix) |test_target| {
2431 for (expected_output) |expected| run.addCheck(.{ .expect_stdout_match = db.b.fmt("{s}\n", .{expected}) });2409 if (options.skip_new_linker and test_target.linker == .new) continue;
2432 run.addCheck(.{ .expect_term = .{ .exited = success } });2410
2433 run.setStdIn(.{ .bytes = "" });2411 const resolved_target = db.b.resolveTargetQuery(test_target.target);
2434 db.root_step.dependOn(&run.step);2412
2413 const target_str = db.b.fmt("{s}{s}{s}", .{
2414 resolved_target.query.zigTriple(db.b.allocator) catch @panic("OOM"),
2415 switch (test_target.linker) {
2416 .default, .old => "",
2417 .new => "-new-linker",
2418 },
2419 if (test_target.pic == true) "-pic" else "",
2420 });
2421
2422 if (db.options.test_target_filters.len > 0) {
2423 for (db.options.test_target_filters) |filter| {
2424 if (std.mem.find(u8, target_str, filter) != null) break;
2425 } else continue;
2426 }
2427
2428 const mod = db.b.createModule(.{
2429 .target = resolved_target,
2430 .root_source_file = root_source_file,
2431 .optimize = test_target.optimize_mode,
2432 .link_libc = test_target.link_libc,
2433 .single_threaded = test_target.single_threaded,
2434 .pic = test_target.pic,
2435 .strip = false,
2436 });
2437 for (imports.keys(), imports.values()) |import_name, import_mod|
2438 mod.addImport(import_name, import_mod);
2439
2440 const exe = db.b.addExecutable(.{
2441 .name = name,
2442 .root_module = mod,
2443 .use_llvm = false,
2444 .use_lld = false,
2445 });
2446 exe.use_new_linker = switch (test_target.linker) {
2447 .default => null,
2448 .old => false,
2449 .new => true,
2450 };
2451
2452 const run = std.Build.Step.Run.create(db.b, db.b.fmt("run {s} {s}", .{ name, target_str }));
2453 for (env) |env_var| run.setEnvironmentVariable(env_var[0], env_var[1]);
2454 run.addArgs(db_argv1);
2455 run.addFileArg(commands_file);
2456 run.addArgs(db_argv2);
2457 run.addArtifactArg(exe);
2458 for (expected_output) |expected| run.addCheck(.{
2459 .expect_stdout_match = db.b.fmt("{s}\n", .{expected}),
2460 });
2461 run.addCheck(.{ .expect_term = .{ .exited = success } });
2462 run.setStdIn(.{ .bytes = "" });
2463 db.root_step.dependOn(&run.step);
2464 }
2435}2465}
24362466
2437const Debugger = @This();2467const Debugger = @This();
test/tests.zig+41-18
...@@ -2303,6 +2303,45 @@ const incremental_targets = &[_]IncrementalTarget{...@@ -2303,6 +2303,45 @@ const incremental_targets = &[_]IncrementalTarget{
2303 },2303 },
2304};2304};
23052305
2306const debugger_matrix: []const DebuggerContext.TestTarget = &.{
2307 .{
2308 .target = .{
2309 .cpu_arch = .x86_64,
2310 .os_tag = .linux,
2311 .abi = .none,
2312 },
2313 .pic = false,
2314 .linker = .old,
2315 },
2316 .{
2317 .target = .{
2318 .cpu_arch = .x86_64,
2319 .os_tag = .linux,
2320 .abi = .none,
2321 },
2322 .pic = true,
2323 .linker = .old,
2324 },
2325 .{
2326 .target = .{
2327 .cpu_arch = .x86_64,
2328 .os_tag = .linux,
2329 .abi = .none,
2330 },
2331 .pic = false,
2332 .linker = .new,
2333 },
2334 .{
2335 .target = .{
2336 .cpu_arch = .x86_64,
2337 .os_tag = .linux,
2338 .abi = .none,
2339 },
2340 .pic = true,
2341 .linker = .new,
2342 },
2343};
2344
2306fn compatible32bitArch(host: *const std.Target) ?std.Target.Cpu.Arch {2345fn compatible32bitArch(host: *const std.Target) ?std.Target.Cpu.Arch {
2307 return switch (host.os.tag) {2346 return switch (host.os.tag) {
2308 .freebsd => switch (host.cpu.arch) {2347 .freebsd => switch (host.cpu.arch) {
...@@ -3323,25 +3362,9 @@ pub fn addDebuggerTests(b: *std.Build, options: DebuggerContext.Options) ?*Step...@@ -3323,25 +3362,9 @@ pub fn addDebuggerTests(b: *std.Build, options: DebuggerContext.Options) ?*Step
3323 .b = b,3362 .b = b,
3324 .options = options,3363 .options = options,
3325 .root_step = step,3364 .root_step = step,
3365 .test_matrix = debugger_matrix,
3326 };3366 };
3327 context.addTestsForTarget(&.{3367 context.addTests();
3328 .resolved = b.resolveTargetQuery(.{
3329 .cpu_arch = .x86_64,
3330 .os_tag = .linux,
3331 .abi = .none,
3332 }),
3333 .pic = false,
3334 .test_name_suffix = "x86_64-linux",
3335 });
3336 context.addTestsForTarget(&.{
3337 .resolved = b.resolveTargetQuery(.{
3338 .cpu_arch = .x86_64,
3339 .os_tag = .linux,
3340 .abi = .none,
3341 }),
3342 .pic = true,
3343 .test_name_suffix = "x86_64-linux-pic",
3344 });
3345 return step;3368 return step;
3346}3369}
33473370