summaryrefslogtreecommitdiff
path: root/simpleperf
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2024-02-27 12:42:21 -0800
committerYabin Cui <yabinc@google.com>2024-03-04 15:24:24 -0800
commit656e35dd6eb1b4be25253d8b52ec818db9b6c605 (patch)
tree19ea6ad7d564fd7c5c25439c8c75316cfaf2974c /simpleperf
parentecef3dcb2f47e33898de7920ecec1997933bd81c (diff)
downloadextras-656e35dd6eb1b4be25253d8b52ec818db9b6c605.tar.gz
simpleperf: scripts: add --remove-method
Add --remove-method to remove methods with name containing the given regular expressions. The removed methods will not be shown in callchains. Also fix TestProtoFileReportLib.test_set_trace_offcpu_mode. Bug: 325429554 Test: run test/test.py --only-host-test Change-Id: Idd1c8c0e98e058eadc1030b04be7e8f4409257f6
Diffstat (limited to 'simpleperf')
-rw-r--r--simpleperf/scripts/simpleperf_report_lib.py52
-rw-r--r--simpleperf/scripts/simpleperf_utils.py7
-rw-r--r--simpleperf/scripts/test/pprof_proto_generator_test.py2
-rw-r--r--simpleperf/scripts/test/report_lib_test.py27
4 files changed, 58 insertions, 30 deletions
diff --git a/simpleperf/scripts/simpleperf_report_lib.py b/simpleperf/scripts/simpleperf_report_lib.py
index 60c0c430..0f4be8c8 100644
--- a/simpleperf/scripts/simpleperf_report_lib.py
+++ b/simpleperf/scripts/simpleperf_report_lib.py
@@ -238,6 +238,23 @@ class ReportLibStructure(ct.Structure):
_fields_ = []
+def SetReportOptionsForReportLib(report_lib, options: ReportLibOptions):
+ if options.proguard_mapping_files:
+ for file_path in options.proguard_mapping_files:
+ report_lib.AddProguardMappingFile(file_path)
+ if options.show_art_frames:
+ report_lib.ShowArtFrames(True)
+ if options.remove_method:
+ for name in options.remove_method:
+ report_lib.RemoveMethod(name)
+ if options.trace_offcpu:
+ report_lib.SetTraceOffCpuMode(options.trace_offcpu)
+ if options.sample_filters:
+ report_lib.SetSampleFilter(options.sample_filters)
+ if options.aggregate_threads:
+ report_lib.AggregateThreads(options.aggregate_threads)
+
+
# pylint: disable=invalid-name
class ReportLib(object):
""" Read contents from perf.data. """
@@ -257,6 +274,8 @@ class ReportLib(object):
self._SetKallsymsFileFunc = self._lib.SetKallsymsFile
self._ShowIpForUnknownSymbolFunc = self._lib.ShowIpForUnknownSymbol
self._ShowArtFramesFunc = self._lib.ShowArtFrames
+ self._RemoveMethodFunc = self._lib.RemoveMethod
+ self._RemoveMethodFunc.restype = ct.c_bool
self._MergeJavaMethodsFunc = self._lib.MergeJavaMethods
self._AddProguardMappingFileFunc = self._lib.AddProguardMappingFile
self._AddProguardMappingFileFunc.restype = ct.c_bool
@@ -304,17 +323,7 @@ class ReportLib(object):
def SetReportOptions(self, options: ReportLibOptions):
""" Set report options in one call. """
- if options.proguard_mapping_files:
- for file_path in options.proguard_mapping_files:
- self.AddProguardMappingFile(file_path)
- if options.show_art_frames:
- self.ShowArtFrames(True)
- if options.trace_offcpu:
- self.SetTraceOffCpuMode(options.trace_offcpu)
- if options.sample_filters:
- self.SetSampleFilter(options.sample_filters)
- if options.aggregate_threads:
- self.AggregateThreads(options.aggregate_threads)
+ SetReportOptionsForReportLib(self, options)
def SetLogSeverity(self, log_level: str = 'info'):
""" Set log severity of native lib, can be verbose,debug,info,error,fatal."""
@@ -338,6 +347,11 @@ class ReportLib(object):
""" Show frames of internal methods of the Java interpreter. """
self._ShowArtFramesFunc(self.getInstance(), show)
+ def RemoveMethod(self, method_name_regex: str):
+ """ Remove methods with name containing method_name_regex. """
+ res = self._RemoveMethodFunc(self.getInstance(), _char_pt(method_name_regex))
+ _check(res, f'failed to call RemoveMethod({method_name_regex})')
+
def MergeJavaMethods(self, merge: bool = True):
""" This option merges jitted java methods with the same name but in different jit
symfiles. If possible, it also merges jitted methods with interpreted methods,
@@ -583,17 +597,7 @@ class ProtoFileReportLib:
def SetReportOptions(self, options: ReportLibOptions):
""" Set report options in one call. """
- if options.proguard_mapping_files:
- for file_path in options.proguard_mapping_files:
- self.AddProguardMappingFile(file_path)
- if options.show_art_frames:
- self.ShowArtFrames(True)
- if options.trace_offcpu:
- self.SetTraceOffCpuMode(options.trace_offcpu)
- if options.sample_filters:
- self.SetSampleFilter(options.sample_filters)
- if options.aggregate_threads:
- self.AggregateThreads(options.aggregate_threads)
+ SetReportOptionsForReportLib(self, options)
def SetLogSeverity(self, log_level: str = 'info'):
pass
@@ -646,6 +650,10 @@ class ProtoFileReportLib:
raise NotImplementedError(
'Showing art frames are not implemented for report_sample profiles')
+ def RemoveMethod(self, method_name_regex: str):
+ """ Remove methods with name containing method_name_regex. """
+ raise NotImplementedError("Removing method isn't implemented for report_sample profiles")
+
def SetSampleFilter(self, filters: List[str]):
raise NotImplementedError('sample filters are not implemented for report_sample profiles')
diff --git a/simpleperf/scripts/simpleperf_utils.py b/simpleperf/scripts/simpleperf_utils.py
index af4fca1b..90f94cf7 100644
--- a/simpleperf/scripts/simpleperf_utils.py
+++ b/simpleperf/scripts/simpleperf_utils.py
@@ -1096,6 +1096,7 @@ class ArgParseFormatter(
@dataclass
class ReportLibOptions:
show_art_frames: bool
+ remove_method: List[str]
trace_offcpu: str
proguard_mapping_files: List[str]
sample_filters: List[str]
@@ -1121,6 +1122,8 @@ class BaseArgumentParser(argparse.ArgumentParser):
parser.add_argument('--show-art-frames', '--show_art_frames',
action=argparse.BooleanOptionalAction, default=default_show_art_frames,
help='Show frames of internal methods in the ART Java interpreter.')
+ parser.add_argument('--remove-method', nargs='+', metavar='method_name_regex',
+ help='remove methods with name containing the regular expression')
parser.add_argument(
'--trace-offcpu', choices=['on-cpu', 'off-cpu', 'on-off-cpu', 'mixed-on-off-cpu'],
help="""Set report mode for profiles recorded with --trace-offcpu option. All possible
@@ -1220,8 +1223,8 @@ class BaseArgumentParser(argparse.ArgumentParser):
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,
- sample_filters, namespace.aggregate_threads)
+ namespace.show_art_frames, namespace.remove_method, namespace.trace_offcpu,
+ namespace.proguard_mapping_file, sample_filters, namespace.aggregate_threads)
setattr(namespace, 'report_lib_options', report_lib_options)
if not Log.initialized:
diff --git a/simpleperf/scripts/test/pprof_proto_generator_test.py b/simpleperf/scripts/test/pprof_proto_generator_test.py
index b8db48a3..1abd61b8 100644
--- a/simpleperf/scripts/test/pprof_proto_generator_test.py
+++ b/simpleperf/scripts/test/pprof_proto_generator_test.py
@@ -222,7 +222,7 @@ class TestPprofProtoGenerator(TestBase):
# Read recording file.
config = {'ndk_path': TestHelper.ndk_path, 'max_chain_length': 1000000,
- 'report_lib_options': ReportLibOptions(False, '', None, None, None)}
+ 'report_lib_options': ReportLibOptions(False, None, '', None, 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 29b9c22a..e633b6ab 100644
--- a/simpleperf/scripts/test/report_lib_test.py
+++ b/simpleperf/scripts/test/report_lib_test.py
@@ -137,6 +137,28 @@ class TestReportLib(TestBase):
report_lib.ShowArtFrames(True)
self.assertTrue(has_art_frame(report_lib))
+ def test_remove_method(self):
+ def get_methods(report_lib) -> Set[str]:
+ methods = set()
+ report_lib.SetRecordFile(TestHelper.testdata_path('perf_display_bitmaps.data'))
+ while True:
+ sample = report_lib.GetNextSample()
+ if not sample:
+ break
+ methods.add(report_lib.GetSymbolOfCurrentSample().symbol_name)
+ callchain = report_lib.GetCallChainOfCurrentSample()
+ for i in range(callchain.nr):
+ methods.add(callchain.entries[i].symbol.symbol_name)
+ report_lib.Close()
+ return methods
+
+ report_lib = ReportLib()
+ report_lib.RemoveMethod('android.view')
+ methods = get_methods(report_lib)
+ self.assertFalse(any('android.view' in method for method in methods))
+ self.assertTrue(any('android.widget' in method for method in methods))
+
+
def test_merge_java_methods(self):
def parse_dso_names(report_lib):
dso_names = set()
@@ -409,9 +431,6 @@ class TestProtoFileReportLib(TestBase):
# GetSupportedTraceOffCpuModes() before SetRecordFile() triggers RuntimeError.
with self.assertRaises(RuntimeError):
report_lib.GetSupportedTraceOffCpuModes()
- # SetTraceOffCpuModes() before SetRecordFile() triggers RuntimeError.
- with self.assertRaises(RuntimeError):
- report_lib.SetTraceOffCpuMode('on-cpu')
mode_dict = {
'on-cpu': {
@@ -468,5 +487,3 @@ class TestProtoFileReportLib(TestBase):
TestHelper.testdata_path('perf.data'))
report_lib.SetRecordFile(proto_file_path)
self.assertEqual(report_lib.GetSupportedTraceOffCpuModes(), [])
- with self.assertRaises(RuntimeError):
- report_lib.SetTraceOffCpuMode('on-cpu')