summaryrefslogtreecommitdiff
path: root/simpleperf/scripts/annotate.py
diff options
context:
space:
mode:
Diffstat (limited to 'simpleperf/scripts/annotate.py')
-rw-r--r--simpleperf/scripts/annotate.py74
1 files changed, 54 insertions, 20 deletions
diff --git a/simpleperf/scripts/annotate.py b/simpleperf/scripts/annotate.py
index 2b253bd7..27414ac6 100644
--- a/simpleperf/scripts/annotate.py
+++ b/simpleperf/scripts/annotate.py
@@ -57,7 +57,12 @@ class Addr2Line(object):
"""
def __init__(self, addr2line_path, symfs_dir=None):
self.dso_dict = dict()
- self.addr2line_path = addr2line_path
+ if addr2line_path and is_executable_available(addr2line_path):
+ self.addr2line_path = addr2line_path
+ else:
+ self.addr2line_path = find_tool_path('addr2line')
+ if not self.addr2line_path:
+ log_exit("Can't find addr2line.")
self.symfs_dir = symfs_dir
@@ -267,27 +272,28 @@ class SourceFileAnnotator(object):
"""group code for annotating source files"""
def __init__(self, config):
# check config variables
- config_names = ['perf_data_list', 'symfs_dir', 'source_dirs',
- 'annotate_dest_dir', 'comm_filters', 'pid_filters',
- 'tid_filters', 'dso_filters', 'addr2line_path']
+ config_names = ['perf_data_list', 'source_dirs', 'comm_filters',
+ 'pid_filters', 'tid_filters', 'dso_filters', 'addr2line_path']
for name in config_names:
if name not in config:
- log_fatal('config [%s] is missing' % name)
- symfs_dir = config['symfs_dir']
- if symfs_dir and not os.path.isdir(symfs_dir):
- log_fatal('[symfs_dir] "%s" is not a dir' % symfs_dir)
- kallsyms = config['kallsyms']
- if kallsyms and not os.path.isfile(kallsyms):
- log_fatal('[kallsyms] "%s" is not a file' % kallsyms)
+ log_exit('config [%s] is missing' % name)
+ symfs_dir = 'binary_cache'
+ if not os.path.isdir(symfs_dir):
+ symfs_dir = None
+ kallsyms = 'binary_cache/kallsyms'
+ if not os.path.isfile(kallsyms):
+ kallsyms = None
source_dirs = config['source_dirs']
for dir in source_dirs:
if not os.path.isdir(dir):
- log_fatal('[source_dirs] "%s" is not a dir' % dir)
+ log_exit('[source_dirs] "%s" is not a dir' % dir)
+ if not config['source_dirs']:
+ log_exit('Please set source directories.')
# init member variables
self.config = config
- self.symfs_dir = config.get('symfs_dir')
- self.kallsyms = config.get('kallsyms')
+ self.symfs_dir = symfs_dir
+ self.kallsyms = kallsyms
self.comm_filter = set(config['comm_filters']) if config.get('comm_filters') else None
if config.get('pid_filters'):
self.pid_filter = {int(x) for x in config['pid_filters']}
@@ -299,6 +305,7 @@ class SourceFileAnnotator(object):
self.tid_filter = None
self.dso_filter = set(config['dso_filters']) if config.get('dso_filters') else None
+ config['annotate_dest_dir'] = 'annotated_files'
output_dir = config['annotate_dest_dir']
if os.path.isdir(output_dir):
shutil.rmtree(output_dir)
@@ -623,14 +630,41 @@ class SourceFileAnnotator(object):
wf.write(annotate)
wf.write(lines[line-1])
+def main():
+ parser = argparse.ArgumentParser(description=
+"""Annotate source files based on profiling data. It reads line information from
+binary_cache generated by app_profiler.py or binary_cache_builder.py, and
+generate annotated source files in annotated_files directory.""")
+ parser.add_argument('-i', '--perf_data_list', nargs='+', action='append', help=
+"""The paths of profiling data. Default is perf.data.""")
+ parser.add_argument('-s', '--source_dirs', nargs='+', action='append', help=
+"""Directories to find source files.""")
+ parser.add_argument('--comm', nargs='+', action='append', help=
+"""Use samples only in threads with selected names.""")
+ parser.add_argument('--pid', nargs='+', action='append', help=
+"""Use samples only in processes with selected process ids.""")
+ parser.add_argument('--tid', nargs='+', action='append', help=
+"""Use samples only in threads with selected thread ids.""")
+ parser.add_argument('--dso', nargs='+', action='append', help=
+"""Use samples only in selected binaries.""")
+ parser.add_argument('--addr2line', help=
+"""Set the path of addr2line.""")
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(
- description='Annotate based on perf.data. See configurations in annotate.config.')
- parser.add_argument('--config', default='annotate.config',
- help='Set configuration file. Default is annotate.config.')
args = parser.parse_args()
- config = load_config(args.config)
+ config = {}
+ config['perf_data_list'] = flatten_arg_list(args.perf_data_list)
+ 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['pid_filters'] = flatten_arg_list(args.pid)
+ config['tid_filters'] = flatten_arg_list(args.tid)
+ config['dso_filters'] = flatten_arg_list(args.dso)
+ config['addr2line_path'] = args.addr2line
+
annotator = SourceFileAnnotator(config)
annotator.annotate()
log_info('annotate finish successfully, please check result in annotated_files/.')
+
+if __name__ == '__main__':
+ main()