authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-24 13:03:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-24 13:03:32-04:00
log6cd725c24b5744d67c36ccb3be9ef9e2fd69c74d
tree15111a04e69ded0905d50ec92d1dee59a7edf6ed
parent245eed8afee899cb0d0a2dac60c8a1edc6be654d

stack traces support compile units with no pc range


1 files changed, 40 insertions(+), 19 deletions(-)

std/debug.zig+40-19
......@@ -185,12 +185,17 @@ const ElfStackTrace = struct {
185185 }
186186};
187187
188const PcRange = struct {
189 start: u64,
190 end: u64,
191};
192
188193const 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
196201const AbbrevTable = List(AbbrevTableEntry);
......@@ -259,7 +264,7 @@ 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,
......@@ -267,7 +272,7 @@ const Die = struct {
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,
......@@ -275,7 +280,7 @@ const Die = struct {
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
843862fn 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}