@@ -113,6 +113,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
113
113
.debug_abbrev = undefined ,
114
114
.debug_str = undefined ,
115
115
.debug_line = undefined ,
116
+ .debug_ranges = null ,
116
117
.abbrev_table_list = ArrayList (AbbrevTableHeader ).init (allocator ),
117
118
.compile_unit_list = ArrayList (CompileUnit ).init (allocator ),
118
119
};
@@ -127,6 +128,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
127
128
st .debug_abbrev = (% return st .elf .findSection (".debug_abbrev" )) ?? return error .MissingDebugInfo ;
128
129
st .debug_str = (% return st .elf .findSection (".debug_str" )) ?? return error .MissingDebugInfo ;
129
130
st .debug_line = (% return st .elf .findSection (".debug_line" )) ?? return error .MissingDebugInfo ;
131
+ st .debug_ranges = (% return st .elf .findSection (".debug_ranges" ));
130
132
% return scanAllCompileUnits (st );
131
133
132
134
var ignored_count : usize = 0 ;
@@ -144,7 +146,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
144
146
// at compile time. I'll call it issue #313
145
147
const ptr_hex = if (@sizeOf (usize ) == 4 ) "0x{x8}" else "0x{x16}" ;
146
148
147
- const compile_unit = findCompileUnit (st , return_address ) ?? {
149
+ const compile_unit = findCompileUnit (st , return_address ) %% {
148
150
% return out_stream .print ("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n " ,
149
151
return_address );
150
152
continue ;
@@ -233,6 +235,7 @@ const ElfStackTrace = struct {
233
235
debug_abbrev : & elf.SectionHeader ,
234
236
debug_str : & elf.SectionHeader ,
235
237
debug_line : & elf.SectionHeader ,
238
+ debug_ranges : ? & elf.SectionHeader ,
236
239
abbrev_table_list : ArrayList (AbbrevTableHeader ),
237
240
compile_unit_list : ArrayList (CompileUnit ),
238
241
@@ -333,6 +336,15 @@ const Die = struct {
333
336
};
334
337
}
335
338
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
+
336
348
fn getAttrUnsignedLe (self : & const Die , id : u64 ) - > % u64 {
337
349
const form_value = self .getAttr (id ) ?? return error .MissingDebugInfo ;
338
350
return switch (* form_value ) {
@@ -900,14 +912,40 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
900
912
}
901
913
}
902
914
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 ;
904
918
for (st .compile_unit_list .toSlice ()) | * compile_unit | {
905
919
if (compile_unit .pc_range ) | range | {
906
920
if (target_address >= range .start and target_address < range .end )
907
921
return compile_unit ;
908
922
}
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
+ }
909
947
}
910
- return null ;
948
+ return error . MissingDebugInfo ;
911
949
}
912
950
913
951
fn readInitialLength (in_stream : & io.InStream , is_64 : & bool ) - > % u64 {
0 commit comments