2020from .stack_collector import CollapsedStackCollector , FlamegraphCollector , DiffFlamegraphCollector
2121from .heatmap_collector import HeatmapCollector
2222from .gecko_collector import GeckoCollector
23+ from .perfetto_collector import PerfettoCollector
2324from .jsonl_collector import JsonlCollector
2425from .binary_collector import BinaryCollector
2526from .binary_reader import BinaryReader
@@ -101,6 +102,7 @@ def __call__(self, parser, namespace, values, option_string=None):
101102 "flamegraph" : "html" ,
102103 "diff_flamegraph" : "html" ,
103104 "gecko" : "json" ,
105+ "perfetto" : "pftrace" ,
104106 "heatmap" : "html" ,
105107 "jsonl" : "jsonl" ,
106108 "binary" : "bin" ,
@@ -112,6 +114,7 @@ def __call__(self, parser, namespace, values, option_string=None):
112114 "flamegraph" : FlamegraphCollector ,
113115 "diff_flamegraph" : DiffFlamegraphCollector ,
114116 "gecko" : GeckoCollector ,
117+ "perfetto" : PerfettoCollector ,
115118 "heatmap" : HeatmapCollector ,
116119 "jsonl" : JsonlCollector ,
117120 "binary" : BinaryCollector ,
@@ -483,6 +486,13 @@ def _add_format_options(parser, include_compression=True, include_binary=True):
483486 dest = "format" ,
484487 help = "Generate Gecko format for Firefox Profiler" ,
485488 )
489+ format_group .add_argument (
490+ "--perfetto" ,
491+ action = "store_const" ,
492+ const = "perfetto" ,
493+ dest = "format" ,
494+ help = "Generate a Perfetto trace (StackSample protos) for the Perfetto UI" ,
495+ )
486496 format_group .add_argument (
487497 "--heatmap" ,
488498 action = "store_const" ,
@@ -631,7 +641,7 @@ def _sort_to_mode(sort_choice):
631641
632642def _create_collector (format_type , sample_interval_usec , skip_idle , opcodes = False ,
633643 mode = None , output_file = None , compression = 'auto' ,
634- diff_baseline = None ):
644+ diff_baseline = None , target_pid = None ):
635645 """Create the appropriate collector based on format type.
636646
637647 Args:
@@ -645,6 +655,7 @@ def _create_collector(format_type, sample_interval_usec, skip_idle, opcodes=Fals
645655 output_file: Output file path (required for binary format)
646656 compression: Compression type for binary format ('auto', 'zstd', 'none')
647657 diff_baseline: Path to baseline binary file for differential flamegraph
658+ target_pid: PID of the process being profiled
648659
649660 Returns:
650661 A collector instance of the appropriate type
@@ -677,6 +688,13 @@ def _create_collector(format_type, sample_interval_usec, skip_idle, opcodes=Fals
677688 skip_idle = False
678689 return collector_class (sample_interval_usec , skip_idle = skip_idle , opcodes = opcodes )
679690
691+ if format_type == "perfetto" :
692+ # Like gecko, keep all threads so idle/GIL-wait state intervals are seen.
693+ return collector_class (
694+ sample_interval_usec , skip_idle = False , opcodes = opcodes ,
695+ pid = target_pid ,
696+ )
697+
680698 if format_type == "jsonl" :
681699 return collector_class (
682700 sample_interval_usec , skip_idle = skip_idle , mode = mode
@@ -957,7 +975,7 @@ def _validate_args(args, parser):
957975 )
958976
959977 # Validate --opcodes is only used with compatible formats
960- opcodes_compatible_formats = ("live" , "gecko" , "flamegraph" , "diff_flamegraph" , "heatmap" , "binary" )
978+ opcodes_compatible_formats = ("live" , "gecko" , "perfetto" , " flamegraph" , "diff_flamegraph" , "heatmap" , "binary" )
961979 if getattr (args , 'opcodes' , False ) and args .format not in opcodes_compatible_formats :
962980 parser .error (
963981 f"--opcodes is only compatible with { ', ' .join ('--' + f for f in opcodes_compatible_formats )} ."
@@ -1177,7 +1195,8 @@ def _handle_attach(args):
11771195 args .format , args .sample_interval_usec , skip_idle , args .opcodes , mode ,
11781196 output_file = output_file ,
11791197 compression = getattr (args , 'compression' , 'auto' ),
1180- diff_baseline = args .diff_baseline
1198+ diff_baseline = args .diff_baseline ,
1199+ target_pid = args .pid ,
11811200 )
11821201
11831202 with _get_child_monitor_context (args , args .pid ):
@@ -1284,7 +1303,8 @@ def _handle_run(args):
12841303 args .format , args .sample_interval_usec , skip_idle , args .opcodes , mode ,
12851304 output_file = output_file ,
12861305 compression = getattr (args , 'compression' , 'auto' ),
1287- diff_baseline = args .diff_baseline
1306+ diff_baseline = args .diff_baseline ,
1307+ target_pid = process .pid ,
12881308 )
12891309
12901310 with _get_child_monitor_context (args , process .pid ):
0 commit comments