diff options
Diffstat (limited to 'simpleperf/scripts/annotate.py')
-rw-r--r-- | simpleperf/scripts/annotate.py | 74 |
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() |