mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 02:44:43 +01:00
Dwarf: fix cross-module inline function line info
This commit is contained in:
parent
ef11bc9899
commit
7a0acc8be6
2 changed files with 153 additions and 53 deletions
|
|
@ -4,9 +4,7 @@ format: DW.Format,
|
|||
endian: std.builtin.Endian,
|
||||
address_size: AddressSize,
|
||||
|
||||
mods: std.AutoArrayHashMapUnmanaged(*Module, struct {
|
||||
files: Files,
|
||||
}),
|
||||
mods: std.AutoArrayHashMapUnmanaged(*Module, ModInfo),
|
||||
types: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),
|
||||
navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, Entry.Index),
|
||||
|
||||
|
|
@ -39,7 +37,19 @@ pub const AddressSize = enum(u8) {
|
|||
_,
|
||||
};
|
||||
|
||||
const Files = std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void);
|
||||
const ModInfo = struct {
|
||||
root_dir_path: Entry.Index,
|
||||
dirs: std.AutoArrayHashMapUnmanaged(Unit.Index, void),
|
||||
files: Files,
|
||||
|
||||
const Files = std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void);
|
||||
|
||||
fn deinit(mod_info: *ModInfo, gpa: std.mem.Allocator) void {
|
||||
mod_info.dirs.deinit(gpa);
|
||||
mod_info.files.deinit(gpa);
|
||||
mod_info.* = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const DebugAbbrev = struct {
|
||||
section: Section,
|
||||
|
|
@ -92,10 +102,20 @@ const DebugLine = struct {
|
|||
opcode_base: u8,
|
||||
};
|
||||
|
||||
fn headerBytes(dwarf: *Dwarf, file_count: u32) u32 {
|
||||
fn dirIndexInfo(dir_count: u32) struct { bytes: u8, form: DeclValEnum(DW.FORM) } {
|
||||
return if (dir_count <= 1 << 8)
|
||||
.{ .bytes = 1, .form = .data1 }
|
||||
else if (dir_count <= 1 << 16)
|
||||
.{ .bytes = 2, .form = .data2 }
|
||||
else
|
||||
unreachable;
|
||||
}
|
||||
|
||||
fn headerBytes(dwarf: *Dwarf, dir_count: u32, file_count: u32) u32 {
|
||||
const dir_index_info = dirIndexInfo(dir_count);
|
||||
return dwarf.unitLengthBytes() + 2 + 1 + 1 + dwarf.sectionOffsetBytes() + 1 + 1 + 1 + 1 + 1 + 1 + 1 * (dwarf.debug_line.header.opcode_base - 1) +
|
||||
1 + uleb128Bytes(DW.LNCT.path) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(1) + (dwarf.sectionOffsetBytes()) * 1 +
|
||||
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;
|
||||
1 + uleb128Bytes(DW.LNCT.path) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(dir_count) + (dwarf.sectionOffsetBytes()) * dir_count +
|
||||
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;
|
||||
}
|
||||
|
||||
const trailer_bytes = 1 + uleb128Bytes(0) +
|
||||
|
|
@ -1066,6 +1086,7 @@ pub const WipNav = struct {
|
|||
const new_func_info = zcu.funcInfo(func);
|
||||
const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav);
|
||||
const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod);
|
||||
|
||||
const dlw = wip_nav.debug_line.writer(dwarf.gpa);
|
||||
if (dwarf.incremental()) {
|
||||
const new_nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, new_func_info.owner_nav);
|
||||
|
|
@ -1089,9 +1110,14 @@ pub const WipNav = struct {
|
|||
const old_func_info = zcu.funcInfo(wip_nav.func);
|
||||
const old_file = zcu.navFileScopeIndex(old_func_info.owner_nav);
|
||||
if (old_file != new_file) {
|
||||
const new_file_gop = try dwarf.getUnitFiles(new_unit).getOrPut(dwarf.gpa, new_file);
|
||||
const mod_info = dwarf.getModInfo(wip_nav.unit);
|
||||
const mod_gop = try mod_info.dirs.getOrPut(dwarf.gpa, new_unit);
|
||||
errdefer _ = if (!mod_gop.found_existing) mod_info.dirs.pop();
|
||||
const file_gop = try mod_info.files.getOrPut(dwarf.gpa, new_file);
|
||||
errdefer _ = if (!file_gop.found_existing) mod_info.files.pop();
|
||||
|
||||
try dlw.writeByte(DW.LNS.set_file);
|
||||
try uleb128(dlw, new_file_gop.index);
|
||||
try uleb128(dlw, file_gop.index);
|
||||
}
|
||||
|
||||
const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav);
|
||||
|
|
@ -1437,7 +1463,7 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
|
|||
|
||||
pub fn deinit(dwarf: *Dwarf) void {
|
||||
const gpa = dwarf.gpa;
|
||||
for (dwarf.mods.values()) |*mod_info| mod_info.files.deinit(gpa);
|
||||
for (dwarf.mods.values()) |*mod_info| mod_info.deinit(gpa);
|
||||
dwarf.mods.deinit(gpa);
|
||||
dwarf.types.deinit(gpa);
|
||||
dwarf.navs.deinit(gpa);
|
||||
|
|
@ -1458,8 +1484,12 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
|
|||
if (!mod_gop.found_existing) {
|
||||
errdefer _ = dwarf.mods.pop();
|
||||
mod_gop.value_ptr.* = .{
|
||||
.root_dir_path = undefined,
|
||||
.dirs = .{},
|
||||
.files = .{},
|
||||
};
|
||||
errdefer mod_gop.value_ptr.dirs.deinit(dwarf.gpa);
|
||||
try mod_gop.value_ptr.dirs.putNoClobber(dwarf.gpa, unit, {});
|
||||
assert(try dwarf.debug_aranges.section.addUnit(
|
||||
DebugAranges.headerBytes(dwarf),
|
||||
DebugAranges.trailerBytes(dwarf),
|
||||
|
|
@ -1473,7 +1503,7 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
|
|||
) == unit);
|
||||
errdefer dwarf.debug_info.section.popUnit();
|
||||
assert(try dwarf.debug_line.section.addUnit(
|
||||
DebugLine.headerBytes(dwarf, 25),
|
||||
DebugLine.headerBytes(dwarf, 5, 25),
|
||||
DebugLine.trailer_bytes,
|
||||
dwarf,
|
||||
) == unit);
|
||||
|
|
@ -1494,8 +1524,12 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
|
|||
return unit;
|
||||
}
|
||||
|
||||
fn getUnitFiles(dwarf: *Dwarf, unit: Unit.Index) *Files {
|
||||
return &dwarf.mods.values()[@intFromEnum(unit)].files;
|
||||
fn getUnitIfExists(dwarf: *const Dwarf, mod: *Module) ?Unit.Index {
|
||||
return @enumFromInt(dwarf.mods.getIndex(mod) orelse return null);
|
||||
}
|
||||
|
||||
fn getModInfo(dwarf: *Dwarf, unit: Unit.Index) *ModInfo {
|
||||
return &dwarf.mods.values()[@intFromEnum(unit)];
|
||||
}
|
||||
|
||||
pub 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
|
|||
});
|
||||
try dlw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
|
||||
|
||||
const file_gop = try dwarf.getUnitFiles(unit).getOrPut(dwarf.gpa, inst_info.file);
|
||||
const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
|
||||
try dlw.writeByte(DW.LNS.set_file);
|
||||
try uleb128(dlw, file_gop.index);
|
||||
|
||||
|
|
@ -2698,7 +2732,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
|||
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0) .namespace_file else .file)));
|
||||
const file_gop = try dwarf.getUnitFiles(unit).getOrPut(dwarf.gpa, inst_info.file);
|
||||
const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
|
||||
try uleb128(diw, file_gop.index);
|
||||
try wip_nav.strp(loaded_struct.name.toSlice(ip));
|
||||
if (loaded_struct.field_types.len > 0) {
|
||||
|
|
@ -2945,8 +2979,19 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
|||
try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
|
||||
}
|
||||
|
||||
const cwd = try std.process.getCwdAlloc(dwarf.gpa);
|
||||
defer dwarf.gpa.free(cwd);
|
||||
{
|
||||
const cwd = try std.process.getCwdAlloc(dwarf.gpa);
|
||||
defer dwarf.gpa.free(cwd);
|
||||
for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| {
|
||||
const root_dir_path = try std.fs.path.resolve(dwarf.gpa, &.{
|
||||
cwd,
|
||||
mod.root.root_dir.path orelse "",
|
||||
mod.root.sub_path,
|
||||
});
|
||||
defer dwarf.gpa.free(root_dir_path);
|
||||
mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path);
|
||||
}
|
||||
}
|
||||
|
||||
var header = std.ArrayList(u8).init(dwarf.gpa);
|
||||
defer header.deinit();
|
||||
|
|
@ -2997,7 +3042,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
|||
dwarf.debug_aranges.section.dirty = false;
|
||||
}
|
||||
if (dwarf.debug_info.section.dirty) {
|
||||
for (dwarf.mods.keys(), dwarf.debug_info.section.units.items, 0..) |mod, *unit_ptr, unit_index| {
|
||||
for (dwarf.mods.keys(), dwarf.mods.values(), dwarf.debug_info.section.units.items, 0..) |mod, mod_info, *unit_ptr, unit_index| {
|
||||
const unit: Unit.Index = @enumFromInt(unit_index);
|
||||
try unit_ptr.cross_unit_relocs.ensureUnusedCapacity(dwarf.gpa, 1);
|
||||
try unit_ptr.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 7);
|
||||
|
|
@ -3032,22 +3077,14 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
|||
.target_unit = StringSection.unit,
|
||||
.target_entry = (try dwarf.debug_line_str.addString(dwarf, "zig " ++ @import("build_options").version)).toOptional(),
|
||||
});
|
||||
{
|
||||
const mod_root_path = try std.fs.path.resolve(dwarf.gpa, &.{
|
||||
cwd,
|
||||
mod.root.root_dir.path orelse "",
|
||||
mod.root.sub_path,
|
||||
});
|
||||
defer dwarf.gpa.free(mod_root_path);
|
||||
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
|
||||
unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
|
||||
.source_off = @intCast(header.items.len),
|
||||
.target_sec = .debug_line_str,
|
||||
.target_unit = StringSection.unit,
|
||||
.target_entry = (try dwarf.debug_line_str.addString(dwarf, mod_root_path)).toOptional(),
|
||||
});
|
||||
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
|
||||
}
|
||||
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
|
||||
unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
|
||||
.source_off = @intCast(header.items.len),
|
||||
.target_sec = .debug_line_str,
|
||||
.target_unit = StringSection.unit,
|
||||
.target_entry = mod_info.root_dir_path.toOptional(),
|
||||
});
|
||||
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
|
||||
unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
|
||||
.source_off = @intCast(header.items.len),
|
||||
.target_sec = .debug_line_str,
|
||||
|
|
@ -3097,8 +3134,8 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
|||
}
|
||||
if (dwarf.debug_line.section.dirty) {
|
||||
for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit|
|
||||
try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.files.count())));
|
||||
for (dwarf.mods.keys(), dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod, mod_info, *unit| {
|
||||
try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count())));
|
||||
for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| {
|
||||
try unit.cross_section_relocs.ensureUnusedCapacity(dwarf.gpa, 2 * (1 + mod_info.files.count()));
|
||||
header.clearRetainingCapacity();
|
||||
try header.ensureTotalCapacity(unit.header_len);
|
||||
|
|
@ -3150,25 +3187,22 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
|||
header.appendAssumeCapacity(1);
|
||||
uleb128(header.fixedWriter(), DW.LNCT.path) catch unreachable;
|
||||
uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
|
||||
uleb128(header.fixedWriter(), 1) catch unreachable;
|
||||
{
|
||||
const mod_root_path = try std.fs.path.resolve(dwarf.gpa, &.{
|
||||
cwd,
|
||||
mod.root.root_dir.path orelse "",
|
||||
mod.root.sub_path,
|
||||
});
|
||||
defer dwarf.gpa.free(mod_root_path);
|
||||
uleb128(header.fixedWriter(), mod_info.dirs.count()) catch unreachable;
|
||||
for (mod_info.dirs.keys()) |dir_unit| {
|
||||
unit.cross_section_relocs.appendAssumeCapacity(.{
|
||||
.source_off = @intCast(header.items.len),
|
||||
.target_sec = .debug_line_str,
|
||||
.target_unit = StringSection.unit,
|
||||
.target_entry = (try dwarf.debug_line_str.addString(dwarf, mod_root_path)).toOptional(),
|
||||
.target_entry = dwarf.getModInfo(dir_unit).root_dir_path.toOptional(),
|
||||
});
|
||||
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
|
||||
}
|
||||
header.appendAssumeCapacity(2);
|
||||
const dir_index_info = DebugLine.dirIndexInfo(@intCast(mod_info.dirs.count()));
|
||||
header.appendAssumeCapacity(3);
|
||||
uleb128(header.fixedWriter(), DW.LNCT.path) catch unreachable;
|
||||
uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
|
||||
uleb128(header.fixedWriter(), DW.LNCT.directory_index) catch unreachable;
|
||||
uleb128(header.fixedWriter(), @intFromEnum(dir_index_info.form)) catch unreachable;
|
||||
uleb128(header.fixedWriter(), DW.LNCT.LLVM_source) catch unreachable;
|
||||
uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
|
||||
uleb128(header.fixedWriter(), mod_info.files.count()) catch unreachable;
|
||||
|
|
@ -3181,6 +3215,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
|||
.target_entry = (try dwarf.debug_line_str.addString(dwarf, file.sub_file_path)).toOptional(),
|
||||
});
|
||||
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
|
||||
dwarf.writeInt(
|
||||
header.addManyAsSliceAssumeCapacity(dir_index_info.bytes),
|
||||
mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod).?).?,
|
||||
);
|
||||
unit.cross_section_relocs.appendAssumeCapacity(.{
|
||||
.source_off = @intCast(header.items.len),
|
||||
.target_sec = .debug_line_str,
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
|
|||
\\breakpoint set --file basic.zig --source-pattern-regexp '_ = basic;'
|
||||
\\process launch
|
||||
\\frame variable --show-types basic
|
||||
\\breakpoint delete --force
|
||||
\\breakpoint delete --force 1
|
||||
,
|
||||
&.{
|
||||
\\(lldb) frame variable --show-types basic
|
||||
|
|
@ -178,6 +178,8 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
|
|||
\\ (f80) f80_-91625968981.3330078125 = -91625968981.3330078125
|
||||
\\ (f128) f128_384307168202282325.333332061767578125 = 384307168202282325.333332061767578125
|
||||
\\}
|
||||
\\(lldb) breakpoint delete --force 1
|
||||
\\1 breakpoints deleted; 0 breakpoint locations disabled.
|
||||
},
|
||||
);
|
||||
db.addLldbTest(
|
||||
|
|
@ -228,7 +230,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
|
|||
\\process launch
|
||||
\\target variable --show-types --format hex global_const global_var global_threadlocal1 global_threadlocal2
|
||||
\\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
|
||||
\\breakpoint delete --force
|
||||
\\breakpoint delete --force 1
|
||||
,
|
||||
&.{
|
||||
\\(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 {
|
|||
\\(u64) local_comptime_ptr.0 = 0x82e834dae74767a1
|
||||
\\(u64) local_const = 0xdffceb8b2f41e205
|
||||
\\(u64) local_var = 0x5d14df51c80685a4
|
||||
\\(lldb) breakpoint delete --force 1
|
||||
\\1 breakpoints deleted; 0 breakpoint locations disabled.
|
||||
},
|
||||
);
|
||||
db.addLldbTest(
|
||||
|
|
@ -272,7 +276,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
|
|||
\\breakpoint set --file slices.zig --source-pattern-regexp '_ = slice;'
|
||||
\\process launch
|
||||
\\frame variable --show-types array slice
|
||||
\\breakpoint delete --force
|
||||
\\breakpoint delete --force 1
|
||||
,
|
||||
&.{
|
||||
\\(lldb) frame variable --show-types array slice
|
||||
|
|
@ -288,6 +292,8 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
|
|||
\\ (u32) [2] = 4
|
||||
\\ (u32) [3] = 8
|
||||
\\}
|
||||
\\(lldb) breakpoint delete --force 1
|
||||
\\1 breakpoints deleted; 0 breakpoint locations disabled.
|
||||
},
|
||||
);
|
||||
db.addLldbTest(
|
||||
|
|
@ -313,18 +319,20 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
|
|||
\\breakpoint set --file optionals.zig --source-pattern-regexp 'maybe_u32 = 123;'
|
||||
\\process launch
|
||||
\\frame variable null_u32 maybe_u32 nonnull_u32
|
||||
\\breakpoint delete --force
|
||||
\\breakpoint delete --force 1
|
||||
\\
|
||||
\\breakpoint set --file optionals.zig --source-pattern-regexp '_ = .{ &null_u32, &nonnull_u32 };'
|
||||
\\process continue
|
||||
\\frame variable --show-types null_u32 maybe_u32 nonnull_u32
|
||||
\\breakpoint delete --force
|
||||
\\breakpoint delete --force 2
|
||||
,
|
||||
&.{
|
||||
\\(lldb) frame variable null_u32 maybe_u32 nonnull_u32
|
||||
\\(?u32) null_u32 = null
|
||||
\\(?u32) maybe_u32 = null
|
||||
\\(?u32) nonnull_u32 = (nonnull_u32.? = 456)
|
||||
\\(lldb) breakpoint delete --force 1
|
||||
\\1 breakpoints deleted; 0 breakpoint locations disabled.
|
||||
,
|
||||
\\(lldb) frame variable --show-types null_u32 maybe_u32 nonnull_u32
|
||||
\\(?u32) null_u32 = null
|
||||
|
|
@ -334,11 +342,60 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
|
|||
\\(?u32) nonnull_u32 = {
|
||||
\\ (u32) nonnull_u32.? = 456
|
||||
\\}
|
||||
\\(lldb) breakpoint delete --force 2
|
||||
\\1 breakpoints deleted; 0 breakpoint locations disabled.
|
||||
},
|
||||
);
|
||||
db.addLldbTest(
|
||||
"cross_module_call",
|
||||
target,
|
||||
&.{
|
||||
.{
|
||||
.path = "main.zig",
|
||||
.source =
|
||||
\\const module = @import("module");
|
||||
\\pub fn main() void {
|
||||
\\ module.foo(123);
|
||||
\\ module.bar(456);
|
||||
\\}
|
||||
,
|
||||
},
|
||||
.{
|
||||
.import = "module",
|
||||
.path = "module.zig",
|
||||
.source =
|
||||
\\pub fn foo(x: u32) void {
|
||||
\\ _ = x;
|
||||
\\}
|
||||
\\pub inline fn bar(y: u32) void {
|
||||
\\ _ = y;
|
||||
\\}
|
||||
,
|
||||
},
|
||||
},
|
||||
\\breakpoint set --file module.zig --source-pattern-regexp '_ = x;'
|
||||
\\process launch
|
||||
\\source info
|
||||
\\breakpoint delete --force 1
|
||||
\\
|
||||
\\breakpoint set --file module.zig --line 5
|
||||
\\process continue
|
||||
\\source info
|
||||
\\breakpoint delete --force 2
|
||||
,
|
||||
&.{
|
||||
\\/module.zig:2:5
|
||||
\\(lldb) breakpoint delete --force 1
|
||||
\\1 breakpoints deleted; 0 breakpoint locations disabled.
|
||||
,
|
||||
\\/module.zig:5:5
|
||||
\\(lldb) breakpoint delete --force 2
|
||||
\\1 breakpoints deleted; 0 breakpoint locations disabled.
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const File = struct { path: []const u8, source: []const u8 };
|
||||
const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 };
|
||||
|
||||
fn addGdbTest(
|
||||
db: *Debugger,
|
||||
|
|
@ -421,7 +478,12 @@ fn addTest(
|
|||
.use_llvm = false,
|
||||
.use_lld = false,
|
||||
});
|
||||
for (files[1..]) |file| _ = files_wf.add(file.path, file.source);
|
||||
for (files[1..]) |file| {
|
||||
const path = files_wf.add(file.path, file.source);
|
||||
if (file.import) |import| exe.root_module.addImport(import, db.b.createModule(.{
|
||||
.root_source_file = path,
|
||||
}));
|
||||
}
|
||||
const commands_wf = db.b.addWriteFiles();
|
||||
const run = std.Build.Step.Run.create(db.b, db.b.fmt("run {s} {s}", .{ name, target.test_name_suffix }));
|
||||
run.addArgs(db_argv1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue