DW_AT_ranges how to get origin value?
anranziruo opened this issue · comments
i want to get DW_AT_ranges like :
DW_AT_ranges (0x000007c0
[0x0000000100009e44, 0x0000000100009e84)
[0x0000000100009e8c, 0x0000000100009ec8)
[0x0000000100009f00, 0x0000000100009f04))
but ,i just get offset as usize value ,just 0x000007c0
but,i am sorry, let raw_ranges: Vec<> = raw_ranges.collect()? occur error:
note: the following trait bounds were not satisfied:
Result<RawRngListIter<EndianSlice<', RunTimeEndian>>, gimli::Error>: Iteratorwhich is required by
&mut Result<RawRngListIter<EndianSlice<'_, RunTimeEndian>>, gimli::Error>: Iterator
use fallible_iterator::FallibleIterator;
use anyhow::{Result};
use object::{Object, ObjectSection,ObjectSegment};
use std::{fs,borrow,path};
use gimli::{DW_TAG_subprogram,DW_TAG_inlined_subroutine,DW_AT_abstract_origin,
DebugInfoOffset,
DebuggingInformationEntry,
Dwarf, EndianSlice, RunTimeEndian, Endianity, LineRows};
use std::collections::HashMap;
use crate::structs;
main code:
if let Ok(Some(at_ranges)) = entry.attr_value(gimli::DW_AT_ranges) {
if let gimli::AttributeValue::RangeListsRef(offset)= at_ranges{
let offset = dwarf.ranges_offset_from_raw(&debug_info_unit, offset);
let raw_ranges = dwarf.raw_ranges(&debug_info_unit, offset);
let raw_ranges: Vec<_> = raw_ranges.collect()?;
let mut ranges = dwarf.ranges(&debug_info_unit, offset)?;
for (i, raw) in raw_ranges.iter().enumerate() {
match *raw {
gimli::RawRngListEntry::AddressOrOffsetPair { begin, end } => {
let range = ranges.next()?.unwrap();
},
_ => println!("West"),
}
}
}
}
let raw_ranges = dwarf.raw_ranges(&debug_info_unit, offset);
needs to be let raw_ranges = dwarf.raw_ranges(&debug_info_unit, offset)?;
. Note the extra ?
near the end.
ok,compile success ,thank you
0x000065e7: DW_TAG_subprogram
DW_AT_linkage_name ("_Z3funi")
DW_AT_name ("fun")
DW_AT_decl_file ("/Users/chao.zhang02/code/rust/apm_parse_symbol/main.cpp")
DW_AT_decl_line (17)
DW_AT_type (0x0000000000004aca "int")
DW_AT_external (true)
DW_AT_inline (DW_INL_inlined)
0x000065f7: DW_TAG_formal_parameter
DW_AT_name ("x")
DW_AT_decl_file ("/Users/chao.zhang02/code/rust/apm_parse_symbol/main.cpp")
DW_AT_decl_line (17)
DW_AT_type (0x0000000000004aca "int")
0x00006602: NULL
0x00006603: DW_TAG_subprogram
DW_AT_linkage_name ("_Z4fun1i")
DW_AT_name ("fun1")
DW_AT_decl_file ("/Users/chao.zhang02/code/rust/apm_parse_symbol/main.cpp")
DW_AT_decl_line (11)
DW_AT_type (0x0000000000004aca "int")
DW_AT_external (true)
DW_AT_inline (DW_INL_inlined)
0x00006613: DW_TAG_formal_parameter
DW_AT_name ("x")
DW_AT_decl_file ("/Users/chao.zhang02/code/rust/apm_parse_symbol/main.cpp")
DW_AT_decl_line (11)
DW_AT_type (0x0000000000004aca "int")
0x0000661e: NULL
0x0000661f: DW_TAG_subprogram
DW_AT_linkage_name ("_Z4fun2i")
DW_AT_name ("fun2")
DW_AT_decl_file ("/Users/chao.zhang02/code/rust/apm_parse_symbol/main.cpp")
DW_AT_decl_line (5)
DW_AT_type (0x0000000000004aca "int")
DW_AT_external (true)
DW_AT_inline (DW_INL_inlined)
0x0000662f: DW_TAG_formal_parameter
DW_AT_name ("x")
DW_AT_decl_file ("/Users/chao.zhang02/code/rust/apm_parse_symbol/main.cpp")
DW_AT_decl_line (5)
DW_AT_type (0x0000000000004aca "int")
0x0000663a: NULL
0x0000663b: DW_TAG_subprogram
DW_AT_low_pc (0x0000000100002fc0)
DW_AT_high_pc (0x0000000100003028)
DW_AT_frame_base (DW_OP_reg29 W29)
DW_AT_linkage_name ("_Z5printv")
DW_AT_name ("print")
DW_AT_decl_file ("/Users/chao.zhang02/code/rust/apm_parse_symbol/main.cpp")
DW_AT_decl_line (22)
DW_AT_external (true)
0x00006654: DW_TAG_variable
DW_AT_location (DW_OP_breg31 WSP+0)
DW_AT_name ("b")
DW_AT_decl_file ("/Users/chao.zhang02/code/rust/apm_parse_symbol/main.cpp")
DW_AT_decl_line (23)
DW_AT_type (0x0000000000004aca "int")
0x00006662: DW_TAG_inlined_subroutine
DW_AT_abstract_origin (0x00000000000065e7 "_Z3funi")
DW_AT_low_pc (0x0000000100002fd4)
DW_AT_high_pc (0x0000000100002ff0)
DW_AT_call_file ("/Users/chao.zhang02/code/rust/apm_parse_symbol/main.cpp")
DW_AT_call_line (23)
DW_AT_call_column (0x0d)
now,this is dwarf example ,i want to DW_AT_abstract_origin 0x00000000000065e7 to match 0x000065e7: DW_TAG_subprogram,this my code
let match_debug_info_header = dwarf.debug_info.header_from_offset(gimli::DebugInfoOffset(match_line_item.inline_offset as usize));
match match_debug_info_header{
Ok(match_debug_info_header_item) =>{
let match_debug_info_unit = dwarf.unit(match_debug_info_header_item)?;
let mut match_debug_entries = match_debug_info_unit.entries();
while let Some(_) = match_debug_entries.next_entry()? {
if let Some(match_entry) = match_debug_entries.current() {
let mut attrs = match_entry.attrs();
while let Some(attr) = attrs.next()? {
println!("{}: {:?}", attr.name(), attr.value());
}
}
}
},
Err(err) => println!("Error: {}", err),
}
but ,this is not work
Can you be more specific about how it doesn't work? What is the output you are getting from your code, and which part is not working?
Can you be more specific about how it doesn't work? What is the output you are getting from your code, and which part is not working?
because of inlined function,in dwarf file,inlined function need to find DW_AT_abstract_origin infos to match DW_TAG_subprogram
You can read the entry for the abstract origin using Unit::entries_at_offset
.
this is my code ,i want to read dSYM file to origin address infos to deal crash infos
if let gimli::AttributeValue::DebugInfoRef(gimli::DebugInfoOffset(abstract_offset)) = abstract_origin_offset{ dwarf_debug_info_item.inline_offset = abstract_offset as u64; }
Don't discard the DebugInfoOffset newtype like this. Keep it as a DebugInfoOffset.
let match_entry_data = debug_info_unit.entries_at_offset(gimli::UnitOffset(match_line_item.inline_offset as usize));
Because then it would be obvious that this line is wrong because a UnitOffset
is not the same as a DebugInfoOffset
.
You need to use DebugInfoOffset::to_unit_offset
.
i want to read dSYM file to origin address infos to deal crash infos
It may be worth looking at the addr2line
or symbolic
crates which already solve this problem.