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 {...@@ -185,12 +185,17 @@ const ElfStackTrace = struct {
185 }185 }
186};186};
187187
188const PcRange = struct {
189 start: u64,
190 end: u64,
191};
192
188const CompileUnit = struct {193const CompileUnit = struct {
194 version: u16,
189 is_64: bool,195 is_64: bool,
190 die: &Die,196 die: &Die,
191 pc_start: u64,
192 pc_end: u64,
193 index: usize,197 index: usize,
198 pc_range: ?PcRange,
194};199};
195200
196const AbbrevTable = List(AbbrevTableEntry);201const AbbrevTable = List(AbbrevTableEntry);
...@@ -259,7 +264,7 @@ const Die = struct {...@@ -259,7 +264,7 @@ const Die = struct {
259 }264 }
260265
261 fn getAttrAddr(self: &const Die, id: u64) -> %u64 {266 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;
263 return switch (*form_value) {268 return switch (*form_value) {
264 FormValue.Address => |value| value,269 FormValue.Address => |value| value,
265 else => error.InvalidDebugInfo,270 else => error.InvalidDebugInfo,
...@@ -267,7 +272,7 @@ const Die = struct {...@@ -267,7 +272,7 @@ const Die = struct {
267 }272 }
268273
269 fn getAttrUnsignedLe(self: &const Die, id: u64) -> %u64 {274 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;
271 return switch (*form_value) {276 return switch (*form_value) {
272 FormValue.Const => |value| value.asUnsignedLe(),277 FormValue.Const => |value| value.asUnsignedLe(),
273 else => error.InvalidDebugInfo,278 else => error.InvalidDebugInfo,
...@@ -275,7 +280,7 @@ const Die = struct {...@@ -275,7 +280,7 @@ const Die = struct {
275 }280 }
276281
277 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) -> %[]u8 {282 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;
279 return switch (*form_value) {284 return switch (*form_value) {
280 FormValue.String => |value| value,285 FormValue.String => |value| value,
281 FormValue.StrPtr => |offset| getString(st, offset),286 FormValue.StrPtr => |offset| getString(st, offset),
...@@ -794,7 +799,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {...@@ -794,7 +799,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
794 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));799 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
795800
796 const version = %return st.self_exe_stream.readInt(st.elf.is_big_endian, u16);801 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
799 const debug_abbrev_offset = if (is_64) {804 const debug_abbrev_offset = if (is_64) {
800 %return st.self_exe_stream.readInt(st.elf.is_big_endian, u64)805 %return st.self_exe_stream.readInt(st.elf.is_big_endian, u64)
...@@ -815,22 +820,36 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {...@@ -815,22 +820,36 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
815820
816 if (compile_unit_die.tag_id != DW.TAG_compile_unit)821 if (compile_unit_die.tag_id != DW.TAG_compile_unit)
817 return error.InvalidDebugInfo;822 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;824 const pc_range = {
821 const pc_end = switch (*high_pc_value) {825 try (compile_unit_die.getAttrAddr(DW.AT_low_pc)) |low_pc| {
822 FormValue.Address => |value| value,826 test (compile_unit_die.getAttr(DW.AT_high_pc)) |high_pc_value| {
823 FormValue.Const => |value| {827 const pc_end = switch (*high_pc_value) {
824 const offset = %return value.asUnsignedLe();828 FormValue.Address => |value| value,
825 low_pc + offset829 FormValue.Const => |value| {
826 },830 const offset = %return value.asUnsignedLe();
827 else => return error.InvalidDebugInfo,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 }
828 };847 };
829848
830 %return st.compile_unit_list.append(CompileUnit {849 %return st.compile_unit_list.append(CompileUnit {
850 .version = version,
831 .is_64 = is_64,851 .is_64 = is_64,
832 .pc_start = low_pc,852 .pc_range = pc_range,
833 .pc_end = pc_end,
834 .die = compile_unit_die,853 .die = compile_unit_die,
835 .index = cu_index,854 .index = cu_index,
836 });855 });
...@@ -842,8 +861,10 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {...@@ -842,8 +861,10 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
842861
843fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> ?&const CompileUnit {862fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> ?&const CompileUnit {
844 for (st.compile_unit_list.toSlice()) |*compile_unit| {863 for (st.compile_unit_list.toSlice()) |*compile_unit| {
845 if (target_address >= compile_unit.pc_start and target_address < compile_unit.pc_end)864 test (compile_unit.pc_range) |range| {
846 return compile_unit;865 if (target_address >= range.start and target_address < range.end)
866 return compile_unit;
867 }
847 }868 }
848 return null;869 return null;
849}870}