diff options
Diffstat (limited to 'inferno/inferno.py')
-rwxr-xr-x | inferno/inferno.py | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/inferno/inferno.py b/inferno/inferno.py index 4566f3e..12b9d90 100755 --- a/inferno/inferno.py +++ b/inferno/inferno.py @@ -40,7 +40,7 @@ import sys SCRIPTS_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) sys.path.append(SCRIPTS_PATH) from simpleperf_report_lib import ReportLib -from utils import log_exit, log_info, AdbHelper, open_report_in_browser +from utils import log_exit, log_fatal, log_info, AdbHelper, open_report_in_browser from data_types import Process from svg_renderer import get_proper_scaled_time_string, render_svg @@ -55,8 +55,10 @@ def collect_data(args): app_profiler_args += ["-np", args.native_program] elif args.pid != -1: app_profiler_args += ['--pid', str(args.pid)] + elif args.system_wide: + app_profiler_args += ['--system_wide'] else: - log_exit("Please set profiling target with -p, -np or --pid option.") + log_exit("Please set profiling target with -p, -np, --pid or --system_wide option.") if args.compile_java_code: app_profiler_args.append("--compile_java_code") if args.disable_adb_root: @@ -141,7 +143,7 @@ def parse_samples(process, args, sample_filter_fn): for thread in process.threads.values(): min_event_count = thread.num_events * args.min_callchain_percentage * 0.01 - thread.flamegraph.trim_callchain(min_event_count) + thread.flamegraph.trim_callchain(min_event_count, args.max_callchain_depth) log_info("Parsed %s callchains." % process.num_samples) @@ -271,6 +273,7 @@ def main(): record_group.add_argument('--record_file', default='perf.data', help='Default is perf.data.') record_group.add_argument('-sc', '--skip_collection', action='store_true', help="""Skip data collection""") + record_group.add_argument('--system_wide', action='store_true', help='Profile system wide.') record_group.add_argument('-t', '--capture_duration', type=int, default=10, help="""Capture duration in seconds.""") @@ -286,6 +289,11 @@ def main(): It is used to limit nodes shown in the flamegraph. For example, when set to 0.01, only callchains taking >= 0.01%% of the event count of the owner thread are collected in the report.""") + report_group.add_argument('--max_callchain_depth', default=1000000000, type=int, help=""" + Set maximum depth of callchains shown in the report. It is used + to limit the nodes shown in the flamegraph and avoid processing + limits. For example, when set to 10, callstacks will be cut after + the tenth frame.""") report_group.add_argument('--no_browser', action='store_true', help="""Don't open report in browser.""") report_group.add_argument('-o', '--report_path', default='report.html', help="""Set report @@ -308,9 +316,15 @@ def main(): if args.pid != -1: process.pid = args.pid args.native_program = '' + if args.system_wide: + process.pid = -1 + args.native_program = '' - process.name = args.app or args.native_program or ('Process %d' % args.pid) - log_info("Starting data collection stage for process '%s'." % process.name) + if args.system_wide: + process.name = 'system_wide' + else: + process.name = args.app or args.native_program or ('Process %d' % args.pid) + log_info("Starting data collection stage for '%s'." % process.name) if not collect_data(args): log_exit("Unable to collect data.") if process.pid == 0: @@ -334,11 +348,16 @@ def main(): args.title = '' args.title += '(One Flamegraph)' - parse_samples(process, args, sample_filter_fn) - generate_threads_offsets(process) - report_path = output_report(process, args) - if not args.no_browser: - open_report_in_browser(report_path) + try: + parse_samples(process, args, sample_filter_fn) + generate_threads_offsets(process) + report_path = output_report(process, args) + if not args.no_browser: + open_report_in_browser(report_path) + except RuntimeError as r: + if 'maximum recursion depth' in r.__str__(): + log_fatal("Recursion limit exceeded (%s), try --max_callchain_depth." % r) + raise r log_info("Flamegraph generated at '%s'." % report_path) |