@@ -9,6 +9,8 @@ use serde::{Deserialize, Serialize};
99use std:: collections:: HashMap ;
1010#[ cfg( unix) ]
1111use std:: path:: PathBuf ;
12+ #[ cfg( unix) ]
13+ use std:: rc:: Rc ;
1214
1315#[ derive( Debug , Clone , PartialEq , Serialize , Deserialize , JsonSchema ) ]
1416pub struct ErrorData {
@@ -23,49 +25,69 @@ pub struct ErrorData {
2325}
2426
2527#[ cfg( unix) ]
26- # [ derive ( Default ) ]
27- pub struct CachedElfResolvers {
28- elf_resolvers : HashMap < PathBuf , ElfResolver > ,
28+ pub struct CachedElfResolvers < ' a > {
29+ symbolizer : & ' a mut blazesym :: symbolize :: Symbolizer ,
30+ elf_resolvers : HashMap < PathBuf , Rc < ElfResolver > > ,
2931}
3032
3133#[ cfg( unix) ]
32- impl CachedElfResolvers {
33- pub fn get ( & mut self , file_path : & PathBuf ) -> anyhow:: Result < & ElfResolver > {
34+ impl < ' a > CachedElfResolvers < ' a > {
35+ pub fn new ( symbolizer : & ' a mut blazesym:: symbolize:: Symbolizer ) -> Self {
36+ Self {
37+ symbolizer,
38+ elf_resolvers : HashMap :: new ( ) ,
39+ }
40+ }
41+
42+ pub fn get ( & mut self , file_path : & PathBuf ) -> anyhow:: Result < Rc < ElfResolver > > {
3443 use anyhow:: Context ;
3544 if !self . elf_resolvers . contains_key ( file_path. as_path ( ) ) {
36- let resolver = ElfResolver :: open ( file_path) . with_context ( || {
45+ let resolver = Rc :: new ( ElfResolver :: open ( file_path) . with_context ( || {
3746 format ! (
3847 "ElfResolver::open failed for '{}'" ,
3948 file_path. to_string_lossy( )
4049 )
41- } ) ?;
50+ } ) ?) ;
51+ let _ = self
52+ . symbolizer
53+ . register_elf_resolver ( file_path. as_path ( ) , Rc :: clone ( & resolver) ) ;
4254 self . elf_resolvers . insert ( file_path. clone ( ) , resolver) ;
4355 }
4456 self . elf_resolvers
4557 . get ( file_path. as_path ( ) )
4658 . with_context ( || "key '{}' not found in ElfResolver cache" )
59+ . cloned ( )
4760 }
4861}
4962
5063#[ cfg( unix) ]
5164impl ErrorData {
5265 pub fn normalize_ips ( & mut self , pid : u32 ) -> anyhow:: Result < ( ) > {
53- let mut errors = 0 ;
54- let mut elf_resolvers = CachedElfResolvers :: default ( ) ;
66+ let mut symbolizer = blazesym :: symbolize :: Symbolizer :: new ( ) ;
67+ let mut elf_resolvers = CachedElfResolvers :: new ( & mut symbolizer ) ;
5568 let normalizer = blazesym:: normalize:: Normalizer :: builder ( )
5669 . enable_vma_caching ( true )
5770 . enable_build_ids ( true )
5871 . enable_build_id_caching ( true )
5972 . build ( ) ;
60- let pid = pid. into ( ) ;
73+ self . normalize_ips_impl ( pid, & normalizer, & mut elf_resolvers)
74+ }
75+
76+ pub ( crate ) fn normalize_ips_impl (
77+ & mut self ,
78+ pid : u32 ,
79+ normalizer : & blazesym:: normalize:: Normalizer ,
80+ elf_resolvers : & mut CachedElfResolvers ,
81+ ) -> anyhow:: Result < ( ) > {
82+ let mut errors = 0 ;
6183 self . stack
62- . normalize_ips ( & normalizer, pid, & mut elf_resolvers)
84+ . normalize_ips ( normalizer, pid. into ( ) , elf_resolvers)
6385 . unwrap_or_else ( |_| errors += 1 ) ;
6486
6587 for thread in & mut self . threads {
6688 thread
6789 . stack
68- . normalize_ips ( & normalizer, pid, & mut elf_resolvers)
90+ . normalize_ips ( normalizer, pid. into ( ) , elf_resolvers)
6991 . unwrap_or_else ( |_| errors += 1 ) ;
7092 }
7193 anyhow:: ensure!(
@@ -75,21 +97,43 @@ impl ErrorData {
7597 Ok ( ( ) )
7698 }
7799
78- pub fn resolve_names ( & mut self , pid : u32 ) -> anyhow:: Result < ( ) > {
79- let mut errors = 0 ;
100+ pub ( crate ) fn create_symbolizer_source < ' a > (
101+ pid : u32 ,
102+ ) -> blazesym:: symbolize:: source:: Source < ' a > {
80103 let mut process = blazesym:: symbolize:: source:: Process :: new ( pid. into ( ) ) ;
81104 // https://github.com/libbpf/blazesym/issues/518
82105 process. map_files = false ;
83- let src = blazesym:: symbolize:: source:: Source :: Process ( process) ;
106+ blazesym:: symbolize:: source:: Source :: Process ( process)
107+ }
108+
109+ pub ( crate ) fn create_normalizer ( ) -> blazesym:: normalize:: Normalizer {
110+ blazesym:: normalize:: Normalizer :: builder ( )
111+ . enable_vma_caching ( true )
112+ . enable_build_ids ( true )
113+ . enable_build_id_caching ( true )
114+ . build ( )
115+ }
116+
117+ pub fn resolve_names ( & mut self , pid : u32 ) -> anyhow:: Result < ( ) > {
118+ let src = Self :: create_symbolizer_source ( pid) ;
84119 let symbolizer = blazesym:: symbolize:: Symbolizer :: new ( ) ;
120+ self . resolve_names_impl ( & symbolizer, & src)
121+ }
122+
123+ pub ( crate ) fn resolve_names_impl (
124+ & mut self ,
125+ symbolizer : & blazesym:: symbolize:: Symbolizer ,
126+ src : & blazesym:: symbolize:: source:: Source ,
127+ ) -> anyhow:: Result < ( ) > {
128+ let mut errors = 0 ;
85129 self . stack
86- . resolve_names ( & src, & symbolizer)
130+ . resolve_names ( src, symbolizer)
87131 . unwrap_or_else ( |_| errors += 1 ) ;
88132
89133 for thread in & mut self . threads {
90134 thread
91135 . stack
92- . resolve_names ( & src, & symbolizer)
136+ . resolve_names ( src, symbolizer)
93137 . unwrap_or_else ( |_| errors += 1 ) ;
94138 }
95139 anyhow:: ensure!(
0 commit comments