gimli-rs / gimli

A library for reading and writing the DWARF debugging format

Home Page:https://docs.rs/gimli/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

gimli/examples/dwarfdump.rs

Lines 1492 to 1495 in 24a25b9

gimli::AttributeValue::RangeListsRef(offset) => {
let offset = dwarf.ranges_offset_from_raw(unit, offset);
dump_range_list(w, offset, unit, dwarf)?;
}
and
let mut ranges = dwarf.ranges(unit, offset)?;
should help with that I think.

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

Please provide more of the code that you are trying to compile. It seems that you didn't use the ? operator in this line:

let raw_ranges = dwarf.raw_ranges(unit, offset)?;

You may also need to use the FallibleIterator trait:

use fallible_iterator::FallibleIterator;

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.