@@ -2,46 +2,43 @@ use crate::prelude::*;
22use crate :: run:: runner:: wall_time:: perf:: perf_map:: ModuleSymbols ;
33use libc:: pid_t;
44use object:: { Object , ObjectSection } ;
5- use serde:: { Deserialize , Serialize } ;
6- use std:: { fmt:: Debug , path:: Path } ;
7-
8- #[ derive( Hash , PartialEq , Eq , Clone , Serialize , Deserialize ) ]
9- pub struct DebugInfo {
10- pub addr : u64 ,
11- pub size : u64 ,
12- #[ serde( skip_serializing_if = "Option::is_none" ) ]
13- pub name : Option < String > ,
14- #[ serde( skip_serializing_if = "Option::is_none" ) ]
15- pub file : Option < String > ,
16- #[ serde( skip_serializing_if = "Option::is_none" ) ]
17- pub line : Option < u32 > ,
18- }
5+ use runner_shared:: debug_info:: { DebugInfo , ModuleDebugInfo } ;
6+ use std:: path:: Path ;
7+
8+ pub trait ModuleDebugInfoExt {
9+ fn from_symbols < P : AsRef < Path > > ( path : P , symbols : & ModuleSymbols ) -> anyhow:: Result < Self >
10+ where
11+ Self : Sized ;
1912
20- impl Debug for DebugInfo {
21- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
22- let location = match ( & self . file , self . line ) {
23- ( Some ( file) , Some ( line) ) => format ! ( "{file}:{line}" ) ,
24- ( Some ( file) , None ) => file. clone ( ) ,
25- _ => String :: from ( "<unknown>" ) ,
13+ fn create_dwarf_context (
14+ object : & object:: File ,
15+ ) -> anyhow:: Result < addr2line:: Context < gimli:: EndianRcSlice < gimli:: RunTimeEndian > > > {
16+ let endian = if object. is_little_endian ( ) {
17+ gimli:: RunTimeEndian :: Little
18+ } else {
19+ gimli:: RunTimeEndian :: Big
20+ } ;
21+
22+ type EndianRcSlice = gimli:: EndianRcSlice < gimli:: RunTimeEndian > ;
23+ let load_section = |id : gimli:: SectionId | -> Result < EndianRcSlice , gimli:: Error > {
24+ let data = object
25+ . section_by_name ( id. name ( ) )
26+ . and_then ( |s| s. uncompressed_data ( ) . ok ( ) )
27+ . unwrap_or ( std:: borrow:: Cow :: Borrowed ( & [ ] ) ) ;
28+ Ok ( gimli:: EndianRcSlice :: new (
29+ std:: rc:: Rc :: from ( data. as_ref ( ) ) ,
30+ endian,
31+ ) )
2632 } ;
27- let name = self . name . as_deref ( ) . unwrap_or ( "<no symbol>" ) ;
28- write ! (
29- f,
30- "DebugInfo {{ addr: {:x}, size: {:x}, name: {}, location: {} }}" ,
31- self . addr, self . size, name, location
32- )
33- }
34- }
3533
36- #[ derive( Debug , Clone , Serialize , Deserialize ) ]
37- pub struct ModuleDebugInfo {
38- load_bias : u64 ,
39- debug_infos : Vec < DebugInfo > ,
34+ let dwarf = gimli:: Dwarf :: load ( load_section) ?;
35+ addr2line:: Context :: from_dwarf ( dwarf) . map_err ( Into :: into)
36+ }
4037}
4138
42- impl ModuleDebugInfo {
39+ impl ModuleDebugInfoExt for ModuleDebugInfo {
4340 /// Create debug info from existing symbols by looking up file/line in DWARF
44- pub fn from_symbols < P : AsRef < Path > > ( path : P , symbols : & ModuleSymbols ) -> anyhow:: Result < Self > {
41+ fn from_symbols < P : AsRef < Path > > ( path : P , symbols : & ModuleSymbols ) -> anyhow:: Result < Self > {
4542 let content = std:: fs:: read ( path. as_ref ( ) ) ?;
4643 let object = object:: File :: parse ( & * content) ?;
4744
@@ -62,43 +59,18 @@ impl ModuleDebugInfo {
6259 Some ( DebugInfo {
6360 addr : symbol. addr ,
6461 size : symbol. size ,
65- name : Some ( symbol. name . clone ( ) ) ,
66- file : Some ( file ) ,
62+ name : symbol. name . clone ( ) ,
63+ file,
6764 line,
6865 } )
6966 } )
7067 . collect ( ) ;
7168
72- Ok ( Self {
69+ Ok ( ModuleDebugInfo {
7370 load_bias,
7471 debug_infos,
7572 } )
7673 }
77-
78- fn create_dwarf_context (
79- object : & object:: File ,
80- ) -> anyhow:: Result < addr2line:: Context < gimli:: EndianRcSlice < gimli:: RunTimeEndian > > > {
81- let endian = if object. is_little_endian ( ) {
82- gimli:: RunTimeEndian :: Little
83- } else {
84- gimli:: RunTimeEndian :: Big
85- } ;
86-
87- type EndianRcSlice = gimli:: EndianRcSlice < gimli:: RunTimeEndian > ;
88- let load_section = |id : gimli:: SectionId | -> Result < EndianRcSlice , gimli:: Error > {
89- let data = object
90- . section_by_name ( id. name ( ) )
91- . and_then ( |s| s. uncompressed_data ( ) . ok ( ) )
92- . unwrap_or ( std:: borrow:: Cow :: Borrowed ( & [ ] ) ) ;
93- Ok ( gimli:: EndianRcSlice :: new (
94- std:: rc:: Rc :: from ( data. as_ref ( ) ) ,
95- endian,
96- ) )
97- } ;
98-
99- let dwarf = gimli:: Dwarf :: load ( load_section) ?;
100- addr2line:: Context :: from_dwarf ( dwarf) . map_err ( Into :: into)
101- }
10274}
10375
10476/// Represents all the modules inside a process and their debug info.
0 commit comments