Skip to content

Commit caa6433

Browse files
committedDec 12, 2017
stack traces: support DW_AT_ranges
This makes some cases print stack traces where it previously failed.
·
0.15.20.2.0
1 parent 23058d8 commit caa6433

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed
 

‎std/debug.zig‎

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
113113
.debug_abbrev = undefined,
114114
.debug_str = undefined,
115115
.debug_line = undefined,
116+
.debug_ranges = null,
116117
.abbrev_table_list = ArrayList(AbbrevTableHeader).init(allocator),
117118
.compile_unit_list = ArrayList(CompileUnit).init(allocator),
118119
};
@@ -127,6 +128,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
127128
st.debug_abbrev = (%return st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo;
128129
st.debug_str = (%return st.elf.findSection(".debug_str")) ?? return error.MissingDebugInfo;
129130
st.debug_line = (%return st.elf.findSection(".debug_line")) ?? return error.MissingDebugInfo;
131+
st.debug_ranges = (%return st.elf.findSection(".debug_ranges"));
130132
%return scanAllCompileUnits(st);
131133

132134
var ignored_count: usize = 0;
@@ -144,7 +146,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
144146
// at compile time. I'll call it issue #313
145147
const ptr_hex = if (@sizeOf(usize) == 4) "0x{x8}" else "0x{x16}";
146148

147-
const compile_unit = findCompileUnit(st, return_address) ?? {
149+
const compile_unit = findCompileUnit(st, return_address) %% {
148150
%return out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n",
149151
return_address);
150152
continue;
@@ -233,6 +235,7 @@ const ElfStackTrace = struct {
233235
debug_abbrev: &elf.SectionHeader,
234236
debug_str: &elf.SectionHeader,
235237
debug_line: &elf.SectionHeader,
238+
debug_ranges: ?&elf.SectionHeader,
236239
abbrev_table_list: ArrayList(AbbrevTableHeader),
237240
compile_unit_list: ArrayList(CompileUnit),
238241

@@ -333,6 +336,15 @@ const Die = struct {
333336
};
334337
}
335338

339+
fn getAttrSecOffset(self: &const Die, id: u64) -> %u64 {
340+
const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
341+
return switch (*form_value) {
342+
FormValue.Const => |value| value.asUnsignedLe(),
343+
FormValue.SecOffset => |value| value,
344+
else => error.InvalidDebugInfo,
345+
};
346+
}
347+
336348
fn getAttrUnsignedLe(self: &const Die, id: u64) -> %u64 {
337349
const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
338350
return switch (*form_value) {
@@ -900,14 +912,40 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
900912
}
901913
}
902914

903-
fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> ?&const CompileUnit {
915+
fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUnit {
916+
var in_file_stream = io.FileInStream.init(&st.self_exe_file);
917+
const in_stream = &in_file_stream.stream;
904918
for (st.compile_unit_list.toSlice()) |*compile_unit| {
905919
if (compile_unit.pc_range) |range| {
906920
if (target_address >= range.start and target_address < range.end)
907921
return compile_unit;
908922
}
923+
if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {
924+
var base_address: usize = 0;
925+
if (st.debug_ranges) |debug_ranges| {
926+
%return st.self_exe_file.seekTo(debug_ranges.offset + ranges_offset);
927+
while (true) {
928+
const begin_addr = %return in_stream.readIntLe(usize);
929+
const end_addr = %return in_stream.readIntLe(usize);
930+
if (begin_addr == 0 and end_addr == 0) {
931+
break;
932+
}
933+
if (begin_addr == @maxValue(usize)) {
934+
base_address = begin_addr;
935+
continue;
936+
}
937+
if (target_address >= begin_addr and target_address < end_addr) {
938+
return compile_unit;
939+
}
940+
}
941+
}
942+
} else |err| {
943+
if (err != error.MissingDebugInfo)
944+
return err;
945+
continue;
946+
}
909947
}
910-
return null;
948+
return error.MissingDebugInfo;
911949
}
912950

913951
fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {

0 commit comments

Comments
 (0)
Please sign in to comment.