@@ -5,7 +5,7 @@ use crate::{
55use linux_perf_data:: jitdump:: { JitDumpReader , JitDumpRecord } ;
66use runner_shared:: unwind_data:: { ProcessUnwindData , UnwindData } ;
77use std:: {
8- collections:: { HashMap , HashSet } ,
8+ collections:: HashMap ,
99 path:: { Path , PathBuf } ,
1010} ;
1111
@@ -108,44 +108,10 @@ impl JitDump {
108108 }
109109}
110110
111- /// Finds all jitdump file paths for a given PID .
111+ /// Converts all the `jit-<pid>.dump` into a perf-<pid>.map with symbols, and collects the unwind data .
112112///
113- /// Searches in order:
114- /// 1. `/tmp/jit-{pid}.dump` (standard perf jitdump location)
115- /// 2. `{jitdumpdir}/.debug/jit/*/jit-{pid}.dump` where `jitdumpdir` is `$JITDUMPDIR` or `$HOME`
116- /// (LLVM ORC JIT / PerfSupportPlugin location)
117- fn find_jit_dumps_for_pid ( pid : libc:: pid_t ) -> Vec < PathBuf > {
118- let name = format ! ( "jit-{pid}.dump" ) ;
119- let mut paths = Vec :: new ( ) ;
120-
121- // Standard perf location.
122- let tmp_path = PathBuf :: from ( "/tmp" ) . join ( & name) ;
123- if tmp_path. exists ( ) {
124- paths. push ( tmp_path) ;
125- }
126-
127- // LLVM ORC JIT location: {base}/.debug/jit/*/jit-{pid}.dump
128- // See LLVM's JITLoaderPerf.cpp for the path construction logic.
129- let base_dir = std:: env:: var ( "JITDUMPDIR" )
130- . or_else ( |_| std:: env:: var ( "HOME" ) )
131- . ok ( )
132- . map ( PathBuf :: from) ;
133- if let Some ( base) = base_dir {
134- let jit_dir = base. join ( ".debug/jit" ) ;
135- if let Ok ( entries) = std:: fs:: read_dir ( & jit_dir) {
136- for entry in entries. filter_map ( |e| e. ok ( ) ) {
137- let candidate = entry. path ( ) . join ( & name) ;
138- if candidate. exists ( ) {
139- paths. push ( candidate) ;
140- }
141- }
142- }
143- }
144-
145- paths
146- }
147-
148- /// Converts all the `jit-<pid>.dump` into a perf-<pid>.map with symbols, and collects the unwind data
113+ /// Jitdump file paths are discovered from MMAP2 records in the perf data, since JIT runtimes
114+ /// mmap the jitdump file and perf records the mapping with the actual path on disk.
149115///
150116/// # Symbols
151117/// Since a jit dump is by definition specific to a single pid, we append the harvested symbols
@@ -155,16 +121,11 @@ fn find_jit_dumps_for_pid(pid: libc::pid_t) -> Vec<PathBuf> {
155121/// Unwind data is generated as a list
156122pub async fn save_symbols_and_harvest_unwind_data_for_pids (
157123 profile_folder : & Path ,
158- pids : & HashSet < libc:: pid_t > ,
124+ jit_dump_paths_by_pid : & HashMap < libc:: pid_t , Vec < PathBuf > > ,
159125) -> Result < HashMap < i32 , Vec < ( UnwindData , ProcessUnwindData ) > > > {
160- let mut jit_unwind_data_by_path = HashMap :: new ( ) ;
161-
162- for pid in pids {
163- let paths = find_jit_dumps_for_pid ( * pid) ;
164- if paths. is_empty ( ) {
165- continue ;
166- }
126+ let mut jit_unwind_data_by_pid = HashMap :: new ( ) ;
167127
128+ for ( pid, paths) in jit_dump_paths_by_pid {
168129 for path in paths {
169130 debug ! ( "Found JIT dump file: {path:?}" ) ;
170131
@@ -178,20 +139,20 @@ pub async fn save_symbols_and_harvest_unwind_data_for_pids(
178139
179140 symbols. append_to_file ( profile_folder. join ( format ! ( "perf-{pid}.map" ) ) ) ?;
180141
181- let jit_unwind_data = match JitDump :: new ( path) . into_unwind_data ( ) {
142+ let jit_unwind_data = match JitDump :: new ( path. clone ( ) ) . into_unwind_data ( ) {
182143 Ok ( data) => data,
183144 Err ( error) => {
184145 warn ! ( "Failed to convert jit dump into unwind data: {error:?}" ) ;
185146 continue ;
186147 }
187148 } ;
188149
189- jit_unwind_data_by_path
150+ jit_unwind_data_by_pid
190151 . entry ( * pid)
191152 . or_insert_with ( Vec :: new)
192153 . extend ( jit_unwind_data) ;
193154 }
194155 }
195156
196- Ok ( jit_unwind_data_by_path )
157+ Ok ( jit_unwind_data_by_pid )
197158}
0 commit comments