authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-16 12:36:43-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-16 15:22:56-04:00
log7a0acc8be6792c188649f490f8ee8b03af134a75
tree45c6b158ef5de04ba9d29aad20d55ce47b3fd800
parentef11bc9899002620d67cfce9c79b6c0dc0f5ea61

Dwarf: fix cross-module inline function line info


2 files changed, 153 insertions(+), 53 deletions(-)

src/link/Dwarf.zig+84-46
......@@ -4,9 +4,7 @@ format: DW.Format,
44endian: std.builtin.Endian,
55address_size: AddressSize,
66
7mods: std.AutoArrayHashMapUnmanaged(*Module, struct {
8 files: Files,
9}),
7mods: std.AutoArrayHashMapUnmanaged(*Module, ModInfo),
108types: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),
119navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, Entry.Index),
1210
......@@ -39,7 +37,19 @@ pub const AddressSize = enum(u8) {
3937 _,
4038};
4139
42const Files = std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void);
40const ModInfo = struct {
41 root_dir_path: Entry.Index,
42 dirs: std.AutoArrayHashMapUnmanaged(Unit.Index, void),
43 files: Files,
44
45 const Files = std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void);
46
47 fn deinit(mod_info: *ModInfo, gpa: std.mem.Allocator) void {
48 mod_info.dirs.deinit(gpa);
49 mod_info.files.deinit(gpa);
50 mod_info.* = undefined;
51 }
52};
4353
4454const DebugAbbrev = struct {
4555 section: Section,
......@@ -92,10 +102,20 @@ const DebugLine = struct {
92102 opcode_base: u8,
93103 };
94104
95 fn headerBytes(dwarf: *Dwarf, file_count: u32) u32 {
105 fn dirIndexInfo(dir_count: u32) struct { bytes: u8, form: DeclValEnum(DW.FORM) } {
106 return if (dir_count <= 1 << 8)
107 .{ .bytes = 1, .form = .data1 }
108 else if (dir_count <= 1 << 16)
109 .{ .bytes = 2, .form = .data2 }
110 else
111 unreachable;
112 }
113
114 fn headerBytes(dwarf: *Dwarf, dir_count: u32, file_count: u32) u32 {
115 const dir_index_info = dirIndexInfo(dir_count);
96116 return dwarf.unitLengthBytes() + 2 + 1 + 1 + dwarf.sectionOffsetBytes() + 1 + 1 + 1 + 1 + 1 + 1 + 1 * (dwarf.debug_line.header.opcode_base - 1) +
97 1 + uleb128Bytes(DW.LNCT.path) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(1) + (dwarf.sectionOffsetBytes()) * 1 +
98 1 + uleb128Bytes(DW.LNCT.path) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(DW.LNCT.LLVM_source) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(file_count) + (dwarf.sectionOffsetBytes() + dwarf.sectionOffsetBytes()) * file_count;
117 1 + uleb128Bytes(DW.LNCT.path) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(dir_count) + (dwarf.sectionOffsetBytes()) * dir_count +
118 1 + uleb128Bytes(DW.LNCT.path) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(DW.LNCT.directory_index) + uleb128Bytes(@intFromEnum(dir_index_info.form)) + uleb128Bytes(DW.LNCT.LLVM_source) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(file_count) + (dwarf.sectionOffsetBytes() + dir_index_info.bytes + dwarf.sectionOffsetBytes()) * file_count;
99119 }
100120
101121 const trailer_bytes = 1 + uleb128Bytes(0) +
......@@ -1066,6 +1086,7 @@ pub const WipNav = struct {
10661086 const new_func_info = zcu.funcInfo(func);
10671087 const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav);
10681088 const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod);
1089
10691090 const dlw = wip_nav.debug_line.writer(dwarf.gpa);
10701091 if (dwarf.incremental()) {
10711092 const new_nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, new_func_info.owner_nav);
......@@ -1089,9 +1110,14 @@ pub const WipNav = struct {
10891110 const old_func_info = zcu.funcInfo(wip_nav.func);
10901111 const old_file = zcu.navFileScopeIndex(old_func_info.owner_nav);
10911112 if (old_file != new_file) {
1092 const new_file_gop = try dwarf.getUnitFiles(new_unit).getOrPut(dwarf.gpa, new_file);
1113 const mod_info = dwarf.getModInfo(wip_nav.unit);
1114 const mod_gop = try mod_info.dirs.getOrPut(dwarf.gpa, new_unit);
1115 errdefer _ = if (!mod_gop.found_existing) mod_info.dirs.pop();
1116 const file_gop = try mod_info.files.getOrPut(dwarf.gpa, new_file);
1117 errdefer _ = if (!file_gop.found_existing) mod_info.files.pop();
1118
10931119 try dlw.writeByte(DW.LNS.set_file);
1094 try uleb128(dlw, new_file_gop.index);
1120 try uleb128(dlw, file_gop.index);
10951121 }
10961122
10971123 const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav);
......@@ -1437,7 +1463,7 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
14371463
14381464pub fn deinit(dwarf: *Dwarf) void {
14391465 const gpa = dwarf.gpa;
1440 for (dwarf.mods.values()) |*mod_info| mod_info.files.deinit(gpa);
1466 for (dwarf.mods.values()) |*mod_info| mod_info.deinit(gpa);
14411467 dwarf.mods.deinit(gpa);
14421468 dwarf.types.deinit(gpa);
14431469 dwarf.navs.deinit(gpa);
......@@ -1458,8 +1484,12 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
14581484 if (!mod_gop.found_existing) {
14591485 errdefer _ = dwarf.mods.pop();
14601486 mod_gop.value_ptr.* = .{
1487 .root_dir_path = undefined,
1488 .dirs = .{},
14611489 .files = .{},
14621490 };
1491 errdefer mod_gop.value_ptr.dirs.deinit(dwarf.gpa);
1492 try mod_gop.value_ptr.dirs.putNoClobber(dwarf.gpa, unit, {});
14631493 assert(try dwarf.debug_aranges.section.addUnit(
14641494 DebugAranges.headerBytes(dwarf),
14651495 DebugAranges.trailerBytes(dwarf),
......@@ -1473,7 +1503,7 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
14731503 ) == unit);
14741504 errdefer dwarf.debug_info.section.popUnit();
14751505 assert(try dwarf.debug_line.section.addUnit(
1476 DebugLine.headerBytes(dwarf, 25),
1506 DebugLine.headerBytes(dwarf, 5, 25),
14771507 DebugLine.trailer_bytes,
14781508 dwarf,
14791509 ) == unit);
......@@ -1494,8 +1524,12 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
14941524 return unit;
14951525}
14961526
1497fn getUnitFiles(dwarf: *Dwarf, unit: Unit.Index) *Files {
1498 return &dwarf.mods.values()[@intFromEnum(unit)].files;
1527fn getUnitIfExists(dwarf: *const Dwarf, mod: *Module) ?Unit.Index {
1528 return @enumFromInt(dwarf.mods.getIndex(mod) orelse return null);
1529}
1530
1531fn getModInfo(dwarf: *Dwarf, unit: Unit.Index) *ModInfo {
1532 return &dwarf.mods.values()[@intFromEnum(unit)];
14991533}
15001534
15011535pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, sym_index: u32) UpdateError!?WipNav {
......@@ -1745,7 +1779,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
17451779 });
17461780 try dlw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
17471781
1748 const file_gop = try dwarf.getUnitFiles(unit).getOrPut(dwarf.gpa, inst_info.file);
1782 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
17491783 try dlw.writeByte(DW.LNS.set_file);
17501784 try uleb128(dlw, file_gop.index);
17511785
......@@ -2698,7 +2732,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
26982732
26992733 const diw = wip_nav.debug_info.writer(dwarf.gpa);
27002734 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0) .namespace_file else .file)));
2701 const file_gop = try dwarf.getUnitFiles(unit).getOrPut(dwarf.gpa, inst_info.file);
2735 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
27022736 try uleb128(diw, file_gop.index);
27032737 try wip_nav.strp(loaded_struct.name.toSlice(ip));
27042738 if (loaded_struct.field_types.len > 0) {
......@@ -2945,8 +2979,19 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
29452979 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
29462980 }
29472981
2948 const cwd = try std.process.getCwdAlloc(dwarf.gpa);
2949 defer dwarf.gpa.free(cwd);
2982 {
2983 const cwd = try std.process.getCwdAlloc(dwarf.gpa);
2984 defer dwarf.gpa.free(cwd);
2985 for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| {
2986 const root_dir_path = try std.fs.path.resolve(dwarf.gpa, &.{
2987 cwd,
2988 mod.root.root_dir.path orelse "",
2989 mod.root.sub_path,
2990 });
2991 defer dwarf.gpa.free(root_dir_path);
2992 mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path);
2993 }
2994 }
29502995
29512996 var header = std.ArrayList(u8).init(dwarf.gpa);
29522997 defer header.deinit();
......@@ -2997,7 +3042,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
29973042 dwarf.debug_aranges.section.dirty = false;
29983043 }
29993044 if (dwarf.debug_info.section.dirty) {
3000 for (dwarf.mods.keys(), dwarf.debug_info.section.units.items, 0..) |mod, *unit_ptr, unit_index| {
3045 for (dwarf.mods.keys(), dwarf.mods.values(), dwarf.debug_info.section.units.items, 0..) |mod, mod_info, *unit_ptr, unit_index| {
30013046 const unit: Unit.Index = @enumFromInt(unit_index);
30023047 try unit_ptr.cross_unit_relocs.ensureUnusedCapacity(dwarf.gpa, 1);
30033048 try unit_ptr.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 7);
......@@ -3032,22 +3077,14 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
30323077 .target_unit = StringSection.unit,
30333078 .target_entry = (try dwarf.debug_line_str.addString(dwarf, "zig " ++ @import("build_options").version)).toOptional(),
30343079 });
3035 {
3036 const mod_root_path = try std.fs.path.resolve(dwarf.gpa, &.{
3037 cwd,
3038 mod.root.root_dir.path orelse "",
3039 mod.root.sub_path,
3040 });
3041 defer dwarf.gpa.free(mod_root_path);
3042 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
3043 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
3044 .source_off = @intCast(header.items.len),
3045 .target_sec = .debug_line_str,
3046 .target_unit = StringSection.unit,
3047 .target_entry = (try dwarf.debug_line_str.addString(dwarf, mod_root_path)).toOptional(),
3048 });
3049 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
3050 }
3080 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
3081 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
3082 .source_off = @intCast(header.items.len),
3083 .target_sec = .debug_line_str,
3084 .target_unit = StringSection.unit,
3085 .target_entry = mod_info.root_dir_path.toOptional(),
3086 });
3087 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
30513088 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
30523089 .source_off = @intCast(header.items.len),
30533090 .target_sec = .debug_line_str,
......@@ -3097,8 +3134,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
30973134 }
30983135 if (dwarf.debug_line.section.dirty) {
30993136 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit|
3100 try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.files.count())));
3101 for (dwarf.mods.keys(), dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod, mod_info, *unit| {
3137 try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count())));
3138 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| {
31023139 try unit.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 2 * (1 + mod_info.files.count()));
31033140 header.clearRetainingCapacity();
31043141 try header.ensureTotalCapacity(unit.header_len);
......@@ -3150,25 +3187,22 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
31503187 header.appendAssumeCapacity(1);
31513188 uleb128(header.fixedWriter(), DW.LNCT.path) catch unreachable;
31523189 uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
3153 uleb128(header.fixedWriter(), 1) catch unreachable;
3154 {
3155 const mod_root_path = try std.fs.path.resolve(dwarf.gpa, &.{
3156 cwd,
3157 mod.root.root_dir.path orelse "",
3158 mod.root.sub_path,
3159 });
3160 defer dwarf.gpa.free(mod_root_path);
3190 uleb128(header.fixedWriter(), mod_info.dirs.count()) catch unreachable;
3191 for (mod_info.dirs.keys()) |dir_unit| {
31613192 unit.cross_section_relocs.appendAssumeCapacity(.{
31623193 .source_off = @intCast(header.items.len),
31633194 .target_sec = .debug_line_str,
31643195 .target_unit = StringSection.unit,
3165 .target_entry = (try dwarf.debug_line_str.addString(dwarf, mod_root_path)).toOptional(),
3196 .target_entry = dwarf.getModInfo(dir_unit).root_dir_path.toOptional(),
31663197 });
31673198 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
31683199 }
3169 header.appendAssumeCapacity(2);
3200 const dir_index_info = DebugLine.dirIndexInfo(@intCast(mod_info.dirs.count()));
3201 header.appendAssumeCapacity(3);
31703202 uleb128(header.fixedWriter(), DW.LNCT.path) catch unreachable;
31713203 uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
3204 uleb128(header.fixedWriter(), DW.LNCT.directory_index) catch unreachable;
3205 uleb128(header.fixedWriter(), @intFromEnum(dir_index_info.form)) catch unreachable;
31723206 uleb128(header.fixedWriter(), DW.LNCT.LLVM_source) catch unreachable;
31733207 uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
31743208 uleb128(header.fixedWriter(), mod_info.files.count()) catch unreachable;
......@@ -3181,6 +3215,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
31813215 .target_entry = (try dwarf.debug_line_str.addString(dwarf, file.sub_file_path)).toOptional(),
31823216 });
31833217 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
3218 dwarf.writeInt(
3219 header.addManyAsSliceAssumeCapacity(dir_index_info.bytes),
3220 mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod).?).?,
3221 );
31843222 unit.cross_section_relocs.appendAssumeCapacity(.{
31853223 .source_off = @intCast(header.items.len),
31863224 .target_sec = .debug_line_str,
test/src/Debugger.zig+69-7
......@@ -108,7 +108,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
108108 \\breakpoint set --file basic.zig --source-pattern-regexp '_ = basic;'
109109 \\process launch
110110 \\frame variable --show-types basic
111 \\breakpoint delete --force
111 \\breakpoint delete --force 1
112112 ,
113113 &.{
114114 \\(lldb) frame variable --show-types basic
......@@ -178,6 +178,8 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
178178 \\ (f80) f80_-91625968981.3330078125 = -91625968981.3330078125
179179 \\ (f128) f128_384307168202282325.333332061767578125 = 384307168202282325.333332061767578125
180180 \\}
181 \\(lldb) breakpoint delete --force 1
182 \\1 breakpoints deleted; 0 breakpoint locations disabled.
181183 },
182184 );
183185 db.addLldbTest(
......@@ -228,7 +230,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
228230 \\process launch
229231 \\target variable --show-types --format hex global_const global_var global_threadlocal1 global_threadlocal2
230232 \\frame variable --show-types --format hex param1 param2 param3 param4 param5 param6 param7 param8 local_comptime_val local_comptime_ptr.0 local_const local_var
231 \\breakpoint delete --force
233 \\breakpoint delete --force 1
232234 ,
233235 &.{
234236 \\(lldb) target variable --show-types --format hex global_const global_var global_threadlocal1 global_threadlocal2
......@@ -249,6 +251,8 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
249251 \\(u64) local_comptime_ptr.0 = 0x82e834dae74767a1
250252 \\(u64) local_const = 0xdffceb8b2f41e205
251253 \\(u64) local_var = 0x5d14df51c80685a4
254 \\(lldb) breakpoint delete --force 1
255 \\1 breakpoints deleted; 0 breakpoint locations disabled.
252256 },
253257 );
254258 db.addLldbTest(
......@@ -272,7 +276,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
272276 \\breakpoint set --file slices.zig --source-pattern-regexp '_ = slice;'
273277 \\process launch
274278 \\frame variable --show-types array slice
275 \\breakpoint delete --force
279 \\breakpoint delete --force 1
276280 ,
277281 &.{
278282 \\(lldb) frame variable --show-types array slice
......@@ -288,6 +292,8 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
288292 \\ (u32) [2] = 4
289293 \\ (u32) [3] = 8
290294 \\}
295 \\(lldb) breakpoint delete --force 1
296 \\1 breakpoints deleted; 0 breakpoint locations disabled.
291297 },
292298 );
293299 db.addLldbTest(
......@@ -313,18 +319,20 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
313319 \\breakpoint set --file optionals.zig --source-pattern-regexp 'maybe_u32 = 123;'
314320 \\process launch
315321 \\frame variable null_u32 maybe_u32 nonnull_u32
316 \\breakpoint delete --force
322 \\breakpoint delete --force 1
317323 \\
318324 \\breakpoint set --file optionals.zig --source-pattern-regexp '_ = .{ &null_u32, &nonnull_u32 };'
319325 \\process continue
320326 \\frame variable --show-types null_u32 maybe_u32 nonnull_u32
321 \\breakpoint delete --force
327 \\breakpoint delete --force 2
322328 ,
323329 &.{
324330 \\(lldb) frame variable null_u32 maybe_u32 nonnull_u32
325331 \\(?u32) null_u32 = null
326332 \\(?u32) maybe_u32 = null
327333 \\(?u32) nonnull_u32 = (nonnull_u32.? = 456)
334 \\(lldb) breakpoint delete --force 1
335 \\1 breakpoints deleted; 0 breakpoint locations disabled.
328336 ,
329337 \\(lldb) frame variable --show-types null_u32 maybe_u32 nonnull_u32
330338 \\(?u32) null_u32 = null
......@@ -334,11 +342,60 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
334342 \\(?u32) nonnull_u32 = {
335343 \\ (u32) nonnull_u32.? = 456
336344 \\}
345 \\(lldb) breakpoint delete --force 2
346 \\1 breakpoints deleted; 0 breakpoint locations disabled.
347 },
348 );
349 db.addLldbTest(
350 "cross_module_call",
351 target,
352 &.{
353 .{
354 .path = "main.zig",
355 .source =
356 \\const module = @import("module");
357 \\pub fn main() void {
358 \\ module.foo(123);
359 \\ module.bar(456);
360 \\}
361 ,
362 },
363 .{
364 .import = "module",
365 .path = "module.zig",
366 .source =
367 \\pub fn foo(x: u32) void {
368 \\ _ = x;
369 \\}
370 \\pub inline fn bar(y: u32) void {
371 \\ _ = y;
372 \\}
373 ,
374 },
375 },
376 \\breakpoint set --file module.zig --source-pattern-regexp '_ = x;'
377 \\process launch
378 \\source info
379 \\breakpoint delete --force 1
380 \\
381 \\breakpoint set --file module.zig --line 5
382 \\process continue
383 \\source info
384 \\breakpoint delete --force 2
385 ,
386 &.{
387 \\/module.zig:2:5
388 \\(lldb) breakpoint delete --force 1
389 \\1 breakpoints deleted; 0 breakpoint locations disabled.
390 ,
391 \\/module.zig:5:5
392 \\(lldb) breakpoint delete --force 2
393 \\1 breakpoints deleted; 0 breakpoint locations disabled.
337394 },
338395 );
339396}
340397
341const File = struct { path: []const u8, source: []const u8 };
398const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 };
342399
343400fn addGdbTest(
344401 db: *Debugger,
......@@ -421,7 +478,12 @@ fn addTest(
421478 .use_llvm = false,
422479 .use_lld = false,
423480 });
424 for (files[1..]) |file| _ = files_wf.add(file.path, file.source);
481 for (files[1..]) |file| {
482 const path = files_wf.add(file.path, file.source);
483 if (file.import) |import| exe.root_module.addImport(import, db.b.createModule(.{
484 .root_source_file = path,
485 }));
486 }
425487 const commands_wf = db.b.addWriteFiles();
426488 const run = std.Build.Step.Run.create(db.b, db.b.fmt("run {s} {s}", .{ name, target.test_name_suffix }));
427489 run.addArgs(db_argv1);