1
1
use std:: collections:: HashMap ;
2
- use std:: fs:: File ;
3
2
use std:: ops:: Deref ;
4
3
use std:: os:: unix:: process:: ExitStatusExt ;
5
4
use std:: path:: Path ;
@@ -8,7 +7,7 @@ use std::thread;
8
7
use std:: time:: { Duration , SystemTime } ;
9
8
10
9
use crossbeam_channel:: { Receiver , Sender } ;
11
- use fxprof_processed_profile:: ReferenceTimestamp ;
10
+ use fxprof_processed_profile:: { Profile , ReferenceTimestamp } ;
12
11
use linux_perf_data:: linux_perf_event_reader:: {
13
12
CpuMode , Endianness , EventRecord , Mmap2FileId , Mmap2InodeAndVersion , Mmap2Record , RawData ,
14
13
} ;
@@ -23,27 +22,22 @@ use crate::linux_shared::vdso::VdsoObject;
23
22
use crate :: linux_shared:: {
24
23
ConvertRegs , Converter , EventInterpretation , MmapRangeOrVec , OffCpuIndicator ,
25
24
} ;
26
- use crate :: server:: { start_server_main, ServerProps } ;
27
25
use crate :: shared:: ctrl_c:: CtrlC ;
28
- use crate :: shared:: recording_props :: {
26
+ use crate :: shared:: prop_types :: {
29
27
ProcessLaunchProps , ProfileCreationProps , RecordingMode , RecordingProps ,
30
28
} ;
31
- use crate :: shared:: save_profile:: save_profile_to_file;
32
- use crate :: shared:: symbol_props:: SymbolProps ;
33
29
34
30
#[ cfg( target_arch = "x86_64" ) ]
35
31
pub type ConvertRegsNative = crate :: linux_shared:: ConvertRegsX86_64 ;
36
32
37
33
#[ cfg( target_arch = "aarch64" ) ]
38
34
pub type ConvertRegsNative = crate :: linux_shared:: ConvertRegsAarch64 ;
39
35
40
- pub fn start_recording (
36
+ pub fn run (
41
37
recording_mode : RecordingMode ,
42
38
recording_props : RecordingProps ,
43
39
profile_creation_props : ProfileCreationProps ,
44
- symbol_props : SymbolProps ,
45
- server_props : Option < ServerProps > ,
46
- ) -> Result < ExitStatus , ( ) > {
40
+ ) -> Result < ( Profile , ExitStatus ) , ( ) > {
47
41
let process_launch_props = match recording_mode {
48
42
RecordingMode :: All => {
49
43
// TODO: Implement, by sudo launching a helper process which opens cpu-wide perf events
@@ -52,14 +46,8 @@ pub fn start_recording(
52
46
std:: process:: exit ( 1 )
53
47
}
54
48
RecordingMode :: Pid ( pid) => {
55
- start_profiling_pid (
56
- pid,
57
- recording_props,
58
- profile_creation_props,
59
- symbol_props,
60
- server_props,
61
- ) ;
62
- return Ok ( ExitStatus :: from_raw ( 0 ) ) ;
49
+ let profile = start_profiling_pid ( pid, recording_props, profile_creation_props) ;
50
+ return Ok ( ( profile, ExitStatus :: from_raw ( 0 ) ) ) ;
63
51
}
64
52
RecordingMode :: Launch ( process_launch_props) => process_launch_props,
65
53
} ;
@@ -102,7 +90,6 @@ pub fn start_recording(
102
90
crossbeam_channel:: bounded ( 2 ) ;
103
91
104
92
// Launch the observer thread. This thread will manage the perf events.
105
- let output_file_copy = recording_props. output_file . clone ( ) ;
106
93
let interval = recording_props. interval ;
107
94
let time_limit = recording_props. time_limit ;
108
95
let initial_exec_name = command_name. to_string_lossy ( ) . to_string ( ) ;
@@ -115,7 +102,6 @@ pub fn start_recording(
115
102
} ;
116
103
let initial_exec_name_and_cmdline = ( initial_exec_name, initial_cmdline) ;
117
104
let observer_thread = thread:: spawn ( move || {
118
- let unstable_presymbolicate = profile_creation_props. unstable_presymbolicate ;
119
105
let mut converter = make_converter ( interval, profile_creation_props) ;
120
106
121
107
// Wait for the initial pid to profile.
@@ -142,14 +128,12 @@ pub fn start_recording(
142
128
run_profiler (
143
129
perf_group,
144
130
converter,
145
- & output_file_copy,
146
131
time_limit,
147
132
profile_another_pid_request_receiver,
148
133
profile_another_pid_reply_sender,
149
134
stop_receiver,
150
- unstable_presymbolicate,
151
135
Some ( initial_exec_name_and_cmdline) ,
152
- ) ;
136
+ )
153
137
} ) ;
154
138
155
139
// We're on the main thread here and the observer thread has just been launched.
@@ -243,35 +227,23 @@ pub fn start_recording(
243
227
// Now wait for the observer thread to quit. It will keep running until all
244
228
// perf events are closed, which happens if all processes which the events
245
229
// are attached to have quit.
246
- observer_thread
230
+ let profile = observer_thread
247
231
. join ( )
248
232
. expect ( "couldn't join observer thread" ) ;
249
233
250
- if let Some ( server_props) = server_props {
251
- let profile_filename = & recording_props. output_file ;
252
- let libinfo_map = crate :: profile_json_preparse:: parse_libinfo_map_from_profile_file (
253
- File :: open ( profile_filename) . expect ( "Couldn't open file we just wrote" ) ,
254
- profile_filename,
255
- )
256
- . expect ( "Couldn't parse libinfo map from profile file" ) ;
257
-
258
- start_server_main ( profile_filename, server_props, symbol_props, libinfo_map) ;
259
- }
260
-
261
234
let exit_status = match wait_status {
262
235
WaitStatus :: Exited ( _pid, exit_code) => ExitStatus :: from_raw ( exit_code) ,
263
236
_ => ExitStatus :: default ( ) ,
264
237
} ;
265
- Ok ( exit_status)
238
+
239
+ Ok ( ( profile, exit_status) )
266
240
}
267
241
268
242
fn start_profiling_pid (
269
243
pid : u32 ,
270
244
recording_props : RecordingProps ,
271
245
profile_creation_props : ProfileCreationProps ,
272
- symbol_props : SymbolProps ,
273
- server_props : Option < ServerProps > ,
274
- ) {
246
+ ) -> Profile {
275
247
// When the first Ctrl+C is received, stop recording.
276
248
let ctrl_c_receiver = CtrlC :: observe_oneshot ( ) ;
277
249
@@ -282,12 +254,10 @@ fn start_profiling_pid(
282
254
let ( profile_another_pid_reply_sender, profile_another_pid_reply_receiver) =
283
255
crossbeam_channel:: bounded ( 2 ) ;
284
256
285
- let output_file = recording_props. output_file . clone ( ) ;
286
257
let observer_thread = thread:: spawn ( {
287
258
move || {
288
259
let interval = recording_props. interval ;
289
260
let time_limit = recording_props. time_limit ;
290
- let unstable_presymbolicate = profile_creation_props. unstable_presymbolicate ;
291
261
let mut converter = make_converter ( interval, profile_creation_props) ;
292
262
let SamplerRequest :: StartProfilingAnotherProcess ( pid, attach_mode) =
293
263
profile_another_pid_request_receiver. recv ( ) . unwrap ( )
@@ -299,16 +269,13 @@ fn start_profiling_pid(
299
269
// Tell the main thread that we are now executing.
300
270
profile_another_pid_reply_sender. send ( true ) . unwrap ( ) ;
301
271
302
- let output_file = recording_props. output_file ;
303
272
run_profiler (
304
273
perf_group,
305
274
converter,
306
- & output_file,
307
275
time_limit,
308
276
profile_another_pid_request_receiver,
309
277
profile_another_pid_reply_sender,
310
278
ctrl_c_receiver,
311
- unstable_presymbolicate,
312
279
None ,
313
280
)
314
281
}
@@ -337,20 +304,10 @@ fn start_profiling_pid(
337
304
// which happens if all processes which the events are attached to have quit.
338
305
observer_thread
339
306
. join ( )
340
- . expect ( "couldn't join observer thread" ) ;
307
+ . expect ( "couldn't join observer thread" )
341
308
342
309
// From now on, pressing Ctrl+C will kill our process, because the observer will have
343
310
// dropped its CtrlC receiver by now.
344
-
345
- if let Some ( server_props) = server_props {
346
- let libinfo_map = crate :: profile_json_preparse:: parse_libinfo_map_from_profile_file (
347
- File :: open ( & output_file) . expect ( "Couldn't open file we just wrote" ) ,
348
- & output_file,
349
- )
350
- . expect ( "Couldn't parse libinfo map from profile file" ) ;
351
-
352
- start_server_main ( & output_file, server_props, symbol_props, libinfo_map) ;
353
- }
354
311
}
355
312
356
313
fn paranoia_level ( ) -> Option < u32 > {
@@ -579,14 +536,12 @@ fn run_profiler(
579
536
mut converter : Converter <
580
537
framehop:: UnwinderNative < MmapRangeOrVec , framehop:: MayAllocateDuringUnwind > ,
581
538
> ,
582
- output_filename : & Path ,
583
539
_time_limit : Option < Duration > ,
584
540
more_processes_request_receiver : Receiver < SamplerRequest > ,
585
541
more_processes_reply_sender : Sender < bool > ,
586
542
mut stop_receiver : oneshot:: Receiver < ( ) > ,
587
- unstable_presymbolicate : bool ,
588
543
mut initial_exec_name_and_cmdline : Option < ( String , Vec < String > ) > ,
589
- ) {
544
+ ) -> Profile {
590
545
// eprintln!("Running...");
591
546
592
547
let mut should_stop_profiling_once_perf_events_exhausted = false ;
@@ -729,16 +684,7 @@ fn run_profiler(
729
684
eprintln ! ( "Lost {total_lost_events} events." ) ;
730
685
}
731
686
732
- let profile = converter. finish ( ) ;
733
-
734
- save_profile_to_file ( & profile, output_filename) . expect ( "Couldn't write JSON" ) ;
735
-
736
- if unstable_presymbolicate {
737
- crate :: shared:: symbol_precog:: presymbolicate (
738
- & profile,
739
- & output_filename. with_extension ( "syms.json" ) ,
740
- ) ;
741
- }
687
+ converter. finish ( )
742
688
}
743
689
744
690
pub fn read_string_lossy < P : AsRef < Path > > ( path : P ) -> std:: io:: Result < String > {
0 commit comments