Skip to content

Commit 6cd725c

Browse files
committed
stack traces support compile units with no pc range
1 parent 245eed8 commit 6cd725c

File tree

1 file changed

+40
-19
lines changed

1 file changed

+40
-19
lines changed

std/debug.zig

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,17 @@ const ElfStackTrace = struct {
185185
}
186186
};
187187

188+
const PcRange = struct {
189+
start: u64,
190+
end: u64,
191+
};
192+
188193
const CompileUnit = struct {
194+
version: u16,
189195
is_64: bool,
190196
die: &Die,
191-
pc_start: u64,
192-
pc_end: u64,
193197
index: usize,
198+
pc_range: ?PcRange,
194199
};
195200

196201
const AbbrevTable = List(AbbrevTableEntry);
@@ -259,23 +264,23 @@ const Die = struct {
259264
}
260265

261266
fn getAttrAddr(self: &const Die, id: u64) -> %u64 {
262-
const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo;
267+
const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
263268
return switch (*form_value) {
264269
FormValue.Address => |value| value,
265270
else => error.InvalidDebugInfo,
266271
};
267272
}
268273

269274
fn getAttrUnsignedLe(self: &const Die, id: u64) -> %u64 {
270-
const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo;
275+
const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
271276
return switch (*form_value) {
272277
FormValue.Const => |value| value.asUnsignedLe(),
273278
else => error.InvalidDebugInfo,
274279
};
275280
}
276281

277282
fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) -> %[]u8 {
278-
const form_value = self.getAttr(id) ?? return error.InvalidDebugInfo;
283+
const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
279284
return switch (*form_value) {
280285
FormValue.String => |value| value,
281286
FormValue.StrPtr => |offset| getString(st, offset),
@@ -794,7 +799,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
794799
const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
795800

796801
const version = %return st.self_exe_stream.readInt(st.elf.is_big_endian, u16);
797-
if (version != 4) return error.InvalidDebugInfo;
802+
if (version < 2 or version > 5) return error.InvalidDebugInfo;
798803

799804
const debug_abbrev_offset = if (is_64) {
800805
%return st.self_exe_stream.readInt(st.elf.is_big_endian, u64)
@@ -815,22 +820,36 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
815820

816821
if (compile_unit_die.tag_id != DW.TAG_compile_unit)
817822
return error.InvalidDebugInfo;
818-
const low_pc = %return compile_unit_die.getAttrAddr(DW.AT_low_pc);
819823

820-
const high_pc_value = compile_unit_die.getAttr(DW.AT_high_pc) ?? return error.MissingDebugInfo;
821-
const pc_end = switch (*high_pc_value) {
822-
FormValue.Address => |value| value,
823-
FormValue.Const => |value| {
824-
const offset = %return value.asUnsignedLe();
825-
low_pc + offset
826-
},
827-
else => return error.InvalidDebugInfo,
824+
const pc_range = {
825+
try (compile_unit_die.getAttrAddr(DW.AT_low_pc)) |low_pc| {
826+
test (compile_unit_die.getAttr(DW.AT_high_pc)) |high_pc_value| {
827+
const pc_end = switch (*high_pc_value) {
828+
FormValue.Address => |value| value,
829+
FormValue.Const => |value| {
830+
const offset = %return value.asUnsignedLe();
831+
low_pc + offset
832+
},
833+
else => return error.InvalidDebugInfo,
834+
};
835+
PcRange {
836+
.start = low_pc,
837+
.end = pc_end,
838+
}
839+
} else {
840+
null
841+
}
842+
} else |err| {
843+
if (err != error.MissingDebugInfo)
844+
return err;
845+
null
846+
}
828847
};
829848

830849
%return st.compile_unit_list.append(CompileUnit {
850+
.version = version,
831851
.is_64 = is_64,
832-
.pc_start = low_pc,
833-
.pc_end = pc_end,
852+
.pc_range = pc_range,
834853
.die = compile_unit_die,
835854
.index = cu_index,
836855
});
@@ -842,8 +861,10 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
842861

843862
fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> ?&const CompileUnit {
844863
for (st.compile_unit_list.toSlice()) |*compile_unit| {
845-
if (target_address >= compile_unit.pc_start and target_address < compile_unit.pc_end)
846-
return compile_unit;
864+
test (compile_unit.pc_range) |range| {
865+
if (target_address >= range.start and target_address < range.end)
866+
return compile_unit;
867+
}
847868
}
848869
return null;
849870
}

0 commit comments

Comments
 (0)