diff options
author | Yabin Cui <yabinc@google.com> | 2022-03-24 17:33:08 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-03-24 17:33:08 +0000 |
commit | ed8610fedf6a3087962e78756b6c1521e7f515ba (patch) | |
tree | a6fa5066efe7d13b7af34e11fa3b324b7efce95c | |
parent | df6aafabd3ab6996ac086be32cf941d6bf7f327e (diff) | |
parent | a9a6f4b64db7c65ae4011296759f781dc3f32ca6 (diff) | |
download | extras-ed8610fedf6a3087962e78756b6c1521e7f515ba.tar.gz |
Merge changes Id3087199,I707cf4dd,I64e3d7fc,I4c9cdc63 am: 1ea3d5fc2e am: a9a6f4b64d
Original change: https://android-review.googlesource.com/c/platform/system/extras/+/2041023
Change-Id: Ie9fca87869811a392b1461fc3b10c965bbfa7d9f
21 files changed, 59 insertions, 130 deletions
diff --git a/simpleperf/scripts/annotate.py b/simpleperf/scripts/annotate.py index ecfb2fdb..7bf8fe92 100755 --- a/simpleperf/scripts/annotate.py +++ b/simpleperf/scripts/annotate.py @@ -146,7 +146,7 @@ class SourceFileAnnotator(object): def __init__(self, config): # check config variables - config_names = ['perf_data_list', 'source_dirs', 'comm_filters', 'dso_filters', 'ndk_path'] + config_names = ['perf_data_list', 'source_dirs', 'dso_filters', 'ndk_path'] for name in config_names: if name not in config: log_exit('config [%s] is missing' % name) @@ -161,7 +161,6 @@ class SourceFileAnnotator(object): self.config = config self.symfs_dir = symfs_dir self.kallsyms = kallsyms - self.comm_filter = set(config['comm_filters']) if config.get('comm_filters') else None self.dso_filter = set(config['dso_filters']) if config.get('dso_filters') else None config['annotate_dest_dir'] = 'annotated_files' @@ -193,16 +192,12 @@ class SourceFileAnnotator(object): lib.SetSymfs(self.symfs_dir) if self.kallsyms: lib.SetKallsymsFile(self.kallsyms) - if self.config.get('sample_filter'): - lib.SetSampleFilter(self.config.get('sample_filter')) lib.SetReportOptions(self.config['report_lib_options']) while True: sample = lib.GetNextSample() if sample is None: lib.Close() break - if not self._filter_sample(sample): - continue symbols = [] symbols.append(lib.GetSymbolOfCurrentSample()) callchain = lib.GetCallChainOfCurrentSample() @@ -216,13 +211,6 @@ class SourceFileAnnotator(object): self.addr2line.add_addr(symbol.dso_name, build_id, symbol.symbol_addr, symbol.symbol_addr) - def _filter_sample(self, sample): - """Return true if the sample can be used.""" - if self.comm_filter: - if sample.thread_comm not in self.comm_filter: - return False - return True - def _filter_symbol(self, symbol): if not self.dso_filter or symbol.dso_name in self.dso_filter: return True @@ -242,16 +230,12 @@ class SourceFileAnnotator(object): lib.SetSymfs(self.symfs_dir) if self.kallsyms: lib.SetKallsymsFile(self.kallsyms) - if self.config.get('sample_filter'): - lib.SetSampleFilter(self.config.get('sample_filter')) lib.SetReportOptions(self.config['report_lib_options']) while True: sample = lib.GetNextSample() if sample is None: lib.Close() break - if not self._filter_sample(sample): - continue self._generate_periods_for_sample(lib, sample) def _generate_periods_for_sample(self, lib, sample): @@ -479,12 +463,9 @@ def main(): help='show raw period instead of percentage') parser.add_argument('--summary-width', type=int, default=80, help='max width of summary file') sample_filter_group = parser.add_argument_group('Sample filter options') - parser.add_sample_filter_options(sample_filter_group) - sample_filter_group.add_argument('--comm', nargs='+', action='append', help=""" - Use samples only in threads with selected names.""") sample_filter_group.add_argument('--dso', nargs='+', action='append', help=""" Use samples only in selected binaries.""") - parser.add_report_lib_options() + parser.add_report_lib_options(sample_filter_group=sample_filter_group) args = parser.parse_args() config = {} @@ -492,12 +473,10 @@ def main(): if not config['perf_data_list']: config['perf_data_list'].append('perf.data') config['source_dirs'] = flatten_arg_list(args.source_dirs) - config['comm_filters'] = flatten_arg_list(args.comm) config['dso_filters'] = flatten_arg_list(args.dso) config['ndk_path'] = args.ndk_path config['raw_period'] = args.raw_period config['summary_width'] = args.summary_width - config['sample_filter'] = args.sample_filter config['report_lib_options'] = args.report_lib_options annotator = SourceFileAnnotator(config) diff --git a/simpleperf/scripts/bin/android/arm/simpleperf b/simpleperf/scripts/bin/android/arm/simpleperf Binary files differindex 5ccbd4f1..db2fde7f 100755 --- a/simpleperf/scripts/bin/android/arm/simpleperf +++ b/simpleperf/scripts/bin/android/arm/simpleperf diff --git a/simpleperf/scripts/bin/android/arm64/simpleperf b/simpleperf/scripts/bin/android/arm64/simpleperf Binary files differindex 862e4d93..785b6e33 100755 --- a/simpleperf/scripts/bin/android/arm64/simpleperf +++ b/simpleperf/scripts/bin/android/arm64/simpleperf diff --git a/simpleperf/scripts/bin/android/x86/simpleperf b/simpleperf/scripts/bin/android/x86/simpleperf Binary files differindex a78e0514..97a168d5 100755 --- a/simpleperf/scripts/bin/android/x86/simpleperf +++ b/simpleperf/scripts/bin/android/x86/simpleperf diff --git a/simpleperf/scripts/bin/android/x86_64/simpleperf b/simpleperf/scripts/bin/android/x86_64/simpleperf Binary files differindex 8872cf4a..c250c450 100755 --- a/simpleperf/scripts/bin/android/x86_64/simpleperf +++ b/simpleperf/scripts/bin/android/x86_64/simpleperf diff --git a/simpleperf/scripts/bin/darwin/x86_64/libsimpleperf_report.dylib b/simpleperf/scripts/bin/darwin/x86_64/libsimpleperf_report.dylib Binary files differindex 32631f67..191e51f8 100755 --- a/simpleperf/scripts/bin/darwin/x86_64/libsimpleperf_report.dylib +++ b/simpleperf/scripts/bin/darwin/x86_64/libsimpleperf_report.dylib diff --git a/simpleperf/scripts/bin/darwin/x86_64/simpleperf b/simpleperf/scripts/bin/darwin/x86_64/simpleperf Binary files differindex c4daaf2b..1a6a8875 100755 --- a/simpleperf/scripts/bin/darwin/x86_64/simpleperf +++ b/simpleperf/scripts/bin/darwin/x86_64/simpleperf diff --git a/simpleperf/scripts/bin/linux/x86_64/libsimpleperf_report.so b/simpleperf/scripts/bin/linux/x86_64/libsimpleperf_report.so Binary files differindex 6f148a8e..ca444ec9 100755 --- a/simpleperf/scripts/bin/linux/x86_64/libsimpleperf_report.so +++ b/simpleperf/scripts/bin/linux/x86_64/libsimpleperf_report.so diff --git a/simpleperf/scripts/bin/linux/x86_64/simpleperf b/simpleperf/scripts/bin/linux/x86_64/simpleperf Binary files differindex f2968884..dca7b30d 100755 --- a/simpleperf/scripts/bin/linux/x86_64/simpleperf +++ b/simpleperf/scripts/bin/linux/x86_64/simpleperf diff --git a/simpleperf/scripts/bin/windows/x86_64/libsimpleperf_report.dll b/simpleperf/scripts/bin/windows/x86_64/libsimpleperf_report.dll Binary files differindex 074bff34..b49e8f8f 100755 --- a/simpleperf/scripts/bin/windows/x86_64/libsimpleperf_report.dll +++ b/simpleperf/scripts/bin/windows/x86_64/libsimpleperf_report.dll diff --git a/simpleperf/scripts/bin/windows/x86_64/simpleperf.exe b/simpleperf/scripts/bin/windows/x86_64/simpleperf.exe Binary files differindex fc98293a..9838e771 100755 --- a/simpleperf/scripts/bin/windows/x86_64/simpleperf.exe +++ b/simpleperf/scripts/bin/windows/x86_64/simpleperf.exe diff --git a/simpleperf/scripts/gecko_profile_generator.py b/simpleperf/scripts/gecko_profile_generator.py index 683a5696..396c9a58 100755 --- a/simpleperf/scripts/gecko_profile_generator.py +++ b/simpleperf/scripts/gecko_profile_generator.py @@ -295,8 +295,6 @@ def _gecko_profile( record_file: str, symfs_dir: Optional[str], kallsyms_file: Optional[str], - comm_filter: Set[str], - sample_filter: Optional[str], report_lib_options: ReportLibOptions) -> GeckoProfile: """convert a simpleperf profile to gecko format""" lib = ReportLib() @@ -307,8 +305,6 @@ def _gecko_profile( lib.SetRecordFile(record_file) if kallsyms_file is not None: lib.SetKallsymsFile(kallsyms_file) - if sample_filter: - lib.SetSampleFilter(sample_filter) lib.SetReportOptions(report_lib_options) arch = lib.GetArch() @@ -323,9 +319,6 @@ def _gecko_profile( if sample is None: lib.Close() break - if comm_filter: - if sample.thread_comm not in comm_filter: - continue event = lib.GetEventOfCurrentSample() symbol = lib.GetSymbolOfCurrentSample() callchain = lib.GetCallChainOfCurrentSample() @@ -404,18 +397,12 @@ def main() -> None: parser.add_argument('--kallsyms', help='Set the path to find kernel symbols.') parser.add_argument('-i', '--record_file', nargs='?', default='perf.data', help='Default is perf.data.') - sample_filter_group = parser.add_argument_group('Sample filter options') - parser.add_sample_filter_options(sample_filter_group) - sample_filter_group.add_argument('--comm', nargs='+', action='append', help=""" - Use samples only in threads with selected names.""") parser.add_report_lib_options() args = parser.parse_args() profile = _gecko_profile( record_file=args.record_file, symfs_dir=args.symfs, kallsyms_file=args.kallsyms, - comm_filter=set(flatten_arg_list(args.comm)), - sample_filter=args.sample_filter, report_lib_options=args.report_lib_options) json.dump(profile, sys.stdout, sort_keys=True) diff --git a/simpleperf/scripts/inferno/inferno.py b/simpleperf/scripts/inferno/inferno.py index 42cbeaca..ccf1b6b6 100755 --- a/simpleperf/scripts/inferno/inferno.py +++ b/simpleperf/scripts/inferno/inferno.py @@ -111,8 +111,6 @@ def parse_samples(process, args, sample_filter_fn): lib.SetRecordFile(record_file) if kallsyms_file: lib.SetKallsymsFile(kallsyms_file) - if args.sample_filter: - lib.SetSampleFilter(args.sample_filter) lib.SetReportOptions(args.report_lib_options) process.cmd = lib.GetRecordCmd() product_props = lib.MetaInfo().get("product_props") @@ -308,8 +306,8 @@ def main(): report_group.add_argument('--symfs', help="""Set the path to find binaries with symbols and debug info.""") report_group.add_argument('--title', help='Show a title in the report.') - parser.add_sample_filter_options(report_group, False) - parser.add_report_lib_options(report_group) + parser.add_report_lib_options( + report_group, sample_filter_group=report_group, sample_filter_with_pid_shortcut=False) debug_group = parser.add_argument_group('Debug options') debug_group.add_argument('--disable_adb_root', action='store_true', help="""Force adb to run diff --git a/simpleperf/scripts/pprof_proto_generator.py b/simpleperf/scripts/pprof_proto_generator.py index e3e2d11f..57c988b9 100755 --- a/simpleperf/scripts/pprof_proto_generator.py +++ b/simpleperf/scripts/pprof_proto_generator.py @@ -270,7 +270,6 @@ class PprofProfileGenerator(object): config['binary_cache_dir'] = 'binary_cache' if not os.path.isdir(config['binary_cache_dir']): config['binary_cache_dir'] = None - self.comm_filter = set(config['comm_filters']) if config.get('comm_filters') else None self.dso_filter = set(config['dso_filters']) if config.get('dso_filters') else None self.max_chain_length = config['max_chain_length'] self.profile = profile_pb2.Profile() @@ -303,8 +302,6 @@ class PprofProfileGenerator(object): if self.config.get('show_art_frames'): self.lib.ShowArtFrames() - if self.config.get('sample_filter'): - self.lib.SetSampleFilter(self.config['sample_filter']) self.lib.SetReportOptions(self.config['report_lib_options']) comments = [ @@ -328,9 +325,6 @@ class PprofProfileGenerator(object): symbol = self.lib.GetSymbolOfCurrentSample() callchain = self.lib.GetCallChainOfCurrentSample() - if not self._filter_report_sample(report_sample): - continue - sample_type_id = self.get_sample_type_id(event.name) sample = Sample() sample.add_value(sample_type_id, 1) @@ -378,13 +372,6 @@ class PprofProfileGenerator(object): return self.profile - def _filter_report_sample(self, sample): - """Return true if the sample can be used.""" - if self.comm_filter: - if sample.thread_comm not in self.comm_filter: - return False - return True - def _filter_symbol(self, symbol): if not self.dso_filter or symbol.dso_name in self.dso_filter: return True @@ -636,12 +623,9 @@ def main(): '-j', '--jobs', type=int, default=os.cpu_count(), help='Use multithreading to speed up source code annotation.') sample_filter_group = parser.add_argument_group('Sample filter options') - parser.add_sample_filter_options(sample_filter_group) - sample_filter_group.add_argument('--comm', nargs='+', action='append', help=""" - Use samples only in threads with selected names.""") sample_filter_group.add_argument('--dso', nargs='+', action='append', help=""" Use samples only in selected binaries.""") - parser.add_report_lib_options() + parser.add_report_lib_options(sample_filter_group=sample_filter_group) args = parser.parse_args() if args.show: @@ -653,11 +637,9 @@ def main(): config = {} config['output_file'] = args.output_file - config['comm_filters'] = flatten_arg_list(args.comm) config['dso_filters'] = flatten_arg_list(args.dso) config['ndk_path'] = args.ndk_path config['max_chain_length'] = args.max_chain_length - config['sample_filter'] = args.sample_filter config['report_lib_options'] = args.report_lib_options generator = PprofProfileGenerator(config) for record_file in args.record_file: diff --git a/simpleperf/scripts/report_html.py b/simpleperf/scripts/report_html.py index 9c00131b..56f8dae5 100755 --- a/simpleperf/scripts/report_html.py +++ b/simpleperf/scripts/report_html.py @@ -620,9 +620,7 @@ class RecordData(object): self.gen_addr_hit_map_in_record_info = False self.binary_finder = BinaryFinder(binary_cache_path, ReadElf(ndk_path)) - def load_record_file( - self, record_file: str, report_lib_options: ReportLibOptions, - sample_filter: Optional[str]): + def load_record_file(self, record_file: str, report_lib_options: ReportLibOptions): lib = ReportLib() lib.SetRecordFile(record_file) # If not showing ip for unknown symbols, the percent of the unknown symbol may be @@ -630,8 +628,6 @@ class RecordData(object): lib.ShowIpForUnknownSymbol() if self.binary_cache_path: lib.SetSymfs(self.binary_cache_path) - if sample_filter: - lib.SetSampleFilter(sample_filter) lib.SetReportOptions(report_lib_options) self.meta_info = lib.MetaInfo() self.cmdline = lib.GetRecordCmd() @@ -983,7 +979,6 @@ def get_args() -> argparse.Namespace: parser.add_argument('--aggregate-by-thread-name', action='store_true', help="""aggregate samples by thread name instead of thread id. This is useful for showing multiple perf.data generated for the same app.""") - parser.add_sample_filter_options() parser.add_report_lib_options() return parser.parse_args() @@ -1012,7 +1007,7 @@ def main(): # 2. Produce record data. record_data = RecordData(binary_cache_path, ndk_path, build_addr_hit_map) for record_file in args.record_file: - record_data.load_record_file(record_file, args.report_lib_options, args.sample_filter) + record_data.load_record_file(record_file, args.report_lib_options) if args.aggregate_by_thread_name: record_data.aggregate_by_thread_name() record_data.limit_percents(args.min_func_percent, args.min_callchain_percent) diff --git a/simpleperf/scripts/report_sample.py b/simpleperf/scripts/report_sample.py index d99bbf9e..dc5c4e2b 100755 --- a/simpleperf/scripts/report_sample.py +++ b/simpleperf/scripts/report_sample.py @@ -29,8 +29,6 @@ def report_sample( kallsyms_file: str, show_tracing_data: bool, header: bool, - comm_filter: Set[str], - sample_filter: Optional[str], report_lib_options: ReportLibOptions): """ read record_file, and print each sample""" lib = ReportLib() @@ -42,8 +40,6 @@ def report_sample( lib.SetRecordFile(record_file) if kallsyms_file is not None: lib.SetKallsymsFile(kallsyms_file) - if sample_filter: - lib.SetSampleFilter(sample_filter) lib.SetReportOptions(report_lib_options) if header: @@ -60,9 +56,6 @@ def report_sample( if sample is None: lib.Close() break - if comm_filter: - if sample.thread_comm not in comm_filter: - continue event = lib.GetEventOfCurrentSample() symbol = lib.GetSymbolOfCurrentSample() callchain = lib.GetCallChainOfCurrentSample() @@ -95,9 +88,6 @@ def main(): parser.add_argument('--show_tracing_data', action='store_true', help='print tracing data.') parser.add_argument('--header', action='store_true', help='Show metadata header, like perf script --header') - parser.add_argument('--comm', nargs='+', action='append', help=""" - Use samples only in threads with selected names.""") - parser.add_sample_filter_options() parser.add_report_lib_options() args = parser.parse_args() report_sample( @@ -106,8 +96,6 @@ def main(): kallsyms_file=args.kallsyms, show_tracing_data=args.show_tracing_data, header=args.header, - comm_filter=set(flatten_arg_list(args.comm)), - sample_filter=args.sample_filter, report_lib_options=args.report_lib_options) diff --git a/simpleperf/scripts/simpleperf_report_lib.py b/simpleperf/scripts/simpleperf_report_lib.py index 45938882..48b31199 100644 --- a/simpleperf/scripts/simpleperf_report_lib.py +++ b/simpleperf/scripts/simpleperf_report_lib.py @@ -307,6 +307,8 @@ class ReportLib(object): self.ShowArtFrames(True) if options.trace_offcpu: self.SetTraceOffCpuMode(options.trace_offcpu) + if options.sample_filters: + self.SetSampleFilter(options.sample_filters) def SetLogSeverity(self, log_level: str = 'info'): """ Set log severity of native lib, can be verbose,debug,info,error,fatal.""" @@ -373,7 +375,7 @@ class ReportLib(object): res: bool = self._SetTraceOffCpuModeFunc(self.getInstance(), _char_pt(mode)) _check(res, f'Failed to call SetTraceOffCpuMode({mode})') - def SetSampleFilter(self, filter: str): + def SetSampleFilter(self, filters: List[str]): """ Set options used to filter samples. Available options are: --exclude-pid pid1,pid2,... Exclude samples for selected processes. --exclude-tid tid1,tid2,... Exclude samples for selected threads. @@ -392,8 +394,10 @@ class ReportLib(object): The filter argument should be a concatenation of options. """ - res: bool = self._SetSampleFilterFunc(self.getInstance(), _char_pt(filter)) - _check(res, f'Failed to call SetSampleFilter({filter})') + filter_array = (ct.c_char_p * len(filters))() + filter_array[:] = [_char_pt(f) for f in filters] + res: bool = self._SetSampleFilterFunc(self.getInstance(), filter_array, len(filters)) + _check(res, f'Failed to call SetSampleFilter({filters})') def GetNextSample(self) -> Optional[SampleStruct]: """ Return the next sample. If no more samples, return None. """ diff --git a/simpleperf/scripts/simpleperf_utils.py b/simpleperf/scripts/simpleperf_utils.py index f11d0a0d..2a7dfd35 100644 --- a/simpleperf/scripts/simpleperf_utils.py +++ b/simpleperf/scripts/simpleperf_utils.py @@ -1005,6 +1005,7 @@ class ReportLibOptions: show_art_frames: bool trace_offcpu: str proguard_mapping_files: List[str] + sample_filters: List[str] class BaseArgumentParser(argparse.ArgumentParser): @@ -1015,7 +1016,9 @@ class BaseArgumentParser(argparse.ArgumentParser): self.has_report_lib_options = False def add_report_lib_options(self, group: Optional[Any] = None, - default_show_art_frames: bool = False): + default_show_art_frames: bool = False, + sample_filter_group: Optional[Any] = None, + sample_filter_with_pid_shortcut: bool = True): self.has_report_lib_options = True parser = group if group else self parser.add_argument( @@ -1032,8 +1035,9 @@ class BaseArgumentParser(argparse.ArgumentParser): mixed-on-off-cpu (on-cpu and off-cpu samples using the same event name). If not set, mixed-on-off-cpu mode is used. """) + self._add_sample_filter_options(sample_filter_group, sample_filter_with_pid_shortcut) - def add_sample_filter_options( + def _add_sample_filter_options( self, group: Optional[Any] = None, with_pid_shortcut: bool = True): if not group: group = self.add_argument_group('Sample filter options') @@ -1061,7 +1065,8 @@ class BaseArgumentParser(argparse.ArgumentParser): '--include-process-name', metavar='process_name_regex', nargs='+', help='only include samples for processes with name containing the regular expression') group.add_argument( - '--include-thread-name', metavar='thread_name_regex', nargs='+', + '--comm', '--include-thread-name', metavar='thread_name_regex', + dest='include_thread_name', nargs='+', help='only include samples for threads with name containing the regular expression') group.add_argument( '--filter-file', metavar='file', @@ -1070,40 +1075,38 @@ class BaseArgumentParser(argparse.ArgumentParser): self.has_sample_filter_options = True self.sample_filter_with_pid_shortcut = with_pid_shortcut - def _build_sample_filter(self, args: argparse.Namespace) -> Optional[str]: - """ Convert sample filter options into a sample filter string, which can be passed to - ReportLib.SetSampleFilter(). - """ + def _build_sample_filter(self, args: argparse.Namespace) -> List[str]: + """ Build sample filters, which can be passed to ReportLib.SetSampleFilter(). """ filters = [] if args.exclude_pid: - filters.append('--exclude-pid ' + ','.join(str(pid) for pid in args.exclude_pid)) + filters.extend(['--exclude-pid', ','.join(str(pid) for pid in args.exclude_pid)]) if args.exclude_tid: - filters.append('--exclude-tid ' + ','.join(str(tid) for tid in args.exclude_tid)) + filters.extend(['--exclude-tid', ','.join(str(tid) for tid in args.exclude_tid)]) if args.exclude_process_name: for name in args.exclude_process_name: - filters.append('--exclude-process-name ' + name) + filters.extend(['--exclude-process-name', name]) if args.exclude_thread_name: for name in args.exclude_thread_name: - filters.append('--exclude-thread-name ' + name) + filters.extend(['--exclude-thread-name', name]) if args.include_pid: - filters.append('--include-pid ' + ','.join(str(pid) for pid in args.include_pid)) + filters.extend(['--include-pid', ','.join(str(pid) for pid in args.include_pid)]) if args.include_tid: - filters.append('--include-tid ' + ','.join(str(tid) for tid in args.include_tid)) + filters.extend(['--include-tid', ','.join(str(tid) for tid in args.include_tid)]) if self.sample_filter_with_pid_shortcut: if args.pid: - filters.append('--include-pid ' + ','.join(str(pid) for pid in args.pid)) + filters.extend(['--include-pid', ','.join(str(pid) for pid in args.pid)]) if args.tid: - filters.append('--include-tid ' + ','.join(str(pid) for pid in args.tid)) + filters.extend(['--include-tid', ','.join(str(pid) for pid in args.tid)]) if args.include_process_name: for name in args.include_process_name: - filters.append('--include-process-name ' + name) + filters.extend(['--include-process-name', name]) if args.include_thread_name: for name in args.include_thread_name: - filters.append('--include-thread-name ' + name) + filters.extend(['--include-thread-name', name]) if args.filter_file: - filters.append('--filter-file ' + args.filter_file) - return ' '.join(filters) + filters.extend(['--filter-file', args.filter_file]) + return filters def parse_known_args(self, *args, **kwargs): self.add_argument( @@ -1111,12 +1114,11 @@ class BaseArgumentParser(argparse.ArgumentParser): default='info', help='set log level') namespace, left_args = super().parse_known_args(*args, **kwargs) - if self.has_sample_filter_options: - setattr(namespace, 'sample_filter', self._build_sample_filter(namespace)) - if self.has_report_lib_options: + sample_filters = self._build_sample_filter(namespace) report_lib_options = ReportLibOptions( - namespace.show_art_frames, namespace.trace_offcpu, namespace.proguard_mapping_file) + namespace.show_art_frames, namespace.trace_offcpu, namespace.proguard_mapping_file, + sample_filters) setattr(namespace, 'report_lib_options', report_lib_options) if not Log.initialized: diff --git a/simpleperf/scripts/stackcollapse.py b/simpleperf/scripts/stackcollapse.py index ee82a0ba..e0e1d86f 100755 --- a/simpleperf/scripts/stackcollapse.py +++ b/simpleperf/scripts/stackcollapse.py @@ -43,8 +43,6 @@ def collapse_stacks( annotate_kernel: bool, annotate_jit: bool, include_addrs: bool, - comm_filter: Set[str], - sample_filter: Optional[str], report_lib_options: ReportLibOptions): """read record_file, aggregate per-stack and print totals per-stack""" lib = ReportLib() @@ -57,8 +55,6 @@ def collapse_stacks( lib.SetRecordFile(record_file) if kallsyms_file is not None: lib.SetKallsymsFile(kallsyms_file) - if sample_filter: - lib.SetSampleFilter(sample_filter) lib.SetReportOptions(report_lib_options) stacks: DefaultDict[str, int] = defaultdict(int) @@ -69,9 +65,6 @@ def collapse_stacks( if sample is None: lib.Close() break - if comm_filter: - if sample.thread_comm not in comm_filter: - continue event = lib.GetEventOfCurrentSample() symbol = lib.GetSymbolOfCurrentSample() callchain = lib.GetCallChainOfCurrentSample() @@ -123,12 +116,10 @@ def main(): parser.add_argument('--addrs', action='store_true', help='include raw addresses where symbols can\'t be found') sample_filter_group = parser.add_argument_group('Sample filter options') - parser.add_sample_filter_options(sample_filter_group, False) sample_filter_group.add_argument('--event-filter', nargs='?', default='', help='Event type filter e.g. "cpu-cycles" or "instructions"') - sample_filter_group.add_argument('--comm', nargs='+', action='append', help=""" - Use samples only in threads with selected names.""") - parser.add_report_lib_options() + parser.add_report_lib_options(sample_filter_group=sample_filter_group, + sample_filter_with_pid_shortcut=False) args = parser.parse_args() collapse_stacks( record_file=args.record_file, @@ -140,8 +131,6 @@ def main(): annotate_kernel=args.kernel, annotate_jit=args.jit, include_addrs=args.addrs, - comm_filter=set(flatten_arg_list(args.comm)), - sample_filter=args.sample_filter, report_lib_options=args.report_lib_options) diff --git a/simpleperf/scripts/test/pprof_proto_generator_test.py b/simpleperf/scripts/test/pprof_proto_generator_test.py index 8e39d1a7..cbeb8d6a 100644 --- a/simpleperf/scripts/test/pprof_proto_generator_test.py +++ b/simpleperf/scripts/test/pprof_proto_generator_test.py @@ -218,7 +218,7 @@ class TestPprofProtoGenerator(TestBase): # Read recording file. config = {'ndk_path': None, 'max_chain_length': 1000000, - 'report_lib_options': ReportLibOptions(False, '', None)} + 'report_lib_options': ReportLibOptions(False, '', None, None)} generator = PprofProfileGenerator(config) generator.load_record_file(testdata_file) diff --git a/simpleperf/scripts/test/report_lib_test.py b/simpleperf/scripts/test/report_lib_test.py index ba7ae466..1447c5ae 100644 --- a/simpleperf/scripts/test/report_lib_test.py +++ b/simpleperf/scripts/test/report_lib_test.py @@ -16,7 +16,7 @@ import os import tempfile -from typing import Set +from typing import List, Set from simpleperf_report_lib import ReportLib from . test_utils import TestBase, TestHelper @@ -275,34 +275,39 @@ class TestReportLib(TestBase): def test_set_sample_filter(self): """ Test using ReportLib.SetSampleFilter(). """ - def get_threads_for_filter(filter: str) -> Set[int]: + def get_threads_for_filter(filters: List[str]) -> Set[int]: self.report_lib.Close() self.report_lib = ReportLib() self.report_lib.SetRecordFile(TestHelper.testdata_path('perf_display_bitmaps.data')) - self.report_lib.SetSampleFilter(filter) + self.report_lib.SetSampleFilter(filters) threads = set() while self.report_lib.GetNextSample(): sample = self.report_lib.GetCurrentSample() threads.add(sample.tid) return threads - self.assertNotIn(31850, get_threads_for_filter('--exclude-pid 31850')) - self.assertIn(31850, get_threads_for_filter('--include-pid 31850')) - self.assertNotIn(31881, get_threads_for_filter('--exclude-tid 31881')) - self.assertIn(31881, get_threads_for_filter('--include-tid 31881')) + self.assertNotIn(31850, get_threads_for_filter(['--exclude-pid', '31850'])) + self.assertIn(31850, get_threads_for_filter(['--include-pid', '31850'])) + self.assertNotIn(31881, get_threads_for_filter(['--exclude-tid', '31881'])) + self.assertIn(31881, get_threads_for_filter(['--include-tid', '31881'])) self.assertNotIn(31881, get_threads_for_filter( - '--exclude-process-name com.example.android.displayingbitmaps')) + ['--exclude-process-name', 'com.example.android.displayingbitmaps'])) self.assertIn(31881, get_threads_for_filter( - '--include-process-name com.example.android.displayingbitmaps')) + ['--include-process-name', 'com.example.android.displayingbitmaps'])) self.assertNotIn(31850, get_threads_for_filter( - '--exclude-thread-name com.example.android.displayingbitmaps')) + ['--exclude-thread-name', 'com.example.android.displayingbitmaps'])) self.assertIn(31850, get_threads_for_filter( - '--include-thread-name com.example.android.displayingbitmaps')) + ['--include-thread-name', 'com.example.android.displayingbitmaps'])) + + # Check that thread name can have space. + self.assertNotIn(31856, get_threads_for_filter( + ['--exclude-thread-name', 'Jit thread pool'])) + self.assertIn(31856, get_threads_for_filter(['--include-thread-name', 'Jit thread pool'])) with tempfile.NamedTemporaryFile('w', delete=False) as filter_file: filter_file.write('GLOBAL_BEGIN 684943449406175\nGLOBAL_END 684943449406176') filter_file.flush() - threads = get_threads_for_filter('--filter-file ' + filter_file.name) + threads = get_threads_for_filter(['--filter-file', filter_file.name]) self.assertIn(31881, threads) self.assertNotIn(31850, threads) os.unlink(filter_file.name) |