diff options
Diffstat (limited to 'simpleperf/scripts/stackcollapse.py')
-rwxr-xr-x | simpleperf/scripts/stackcollapse.py | 138 |
1 files changed, 0 insertions, 138 deletions
diff --git a/simpleperf/scripts/stackcollapse.py b/simpleperf/scripts/stackcollapse.py deleted file mode 100755 index e0e1d86f..00000000 --- a/simpleperf/scripts/stackcollapse.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2021 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -"""stackcollapse.py: convert perf.data to Brendan Gregg's "Folded Stacks" format, - which can be read by https://github.com/brendangregg/FlameGraph, and many - other tools. - - Example: - ./app_profiler.py - ./stackcollapse.py | ~/FlameGraph/flamegraph.pl --color=java --countname=ns > flamegraph.svg -""" - -from collections import defaultdict -from simpleperf_report_lib import ReportLib -from simpleperf_utils import BaseArgumentParser, flatten_arg_list, ReportLibOptions -from typing import DefaultDict, List, Optional, Set - -import logging -import sys - - -def collapse_stacks( - record_file: str, - symfs_dir: str, - kallsyms_file: str, - event_filter: str, - include_pid: bool, - include_tid: bool, - annotate_kernel: bool, - annotate_jit: bool, - include_addrs: bool, - report_lib_options: ReportLibOptions): - """read record_file, aggregate per-stack and print totals per-stack""" - lib = ReportLib() - - if include_addrs: - lib.ShowIpForUnknownSymbol() - if symfs_dir is not None: - lib.SetSymfs(symfs_dir) - if record_file is not None: - lib.SetRecordFile(record_file) - if kallsyms_file is not None: - lib.SetKallsymsFile(kallsyms_file) - lib.SetReportOptions(report_lib_options) - - stacks: DefaultDict[str, int] = defaultdict(int) - event_defaulted = False - event_warning_shown = False - while True: - sample = lib.GetNextSample() - if sample is None: - lib.Close() - break - event = lib.GetEventOfCurrentSample() - symbol = lib.GetSymbolOfCurrentSample() - callchain = lib.GetCallChainOfCurrentSample() - if not event_filter: - event_filter = event.name - event_defaulted = True - elif event.name != event_filter: - if event_defaulted and not event_warning_shown: - logging.warning( - 'Input has multiple event types. Filtering for the first event type seen: %s' % - event_filter) - event_warning_shown = True - continue - - stack = [] - for i in range(callchain.nr): - entry = callchain.entries[i] - func = entry.symbol.symbol_name - if annotate_kernel and "kallsyms" in entry.symbol.dso_name or ".ko" in entry.symbol.dso_name: - func += '_[k]' # kernel - if annotate_jit and entry.symbol.dso_name == "[JIT app cache]": - func += '_[j]' # jit - stack.append(func) - if include_tid: - stack.append("%s-%d/%d" % (sample.thread_comm, sample.pid, sample.tid)) - elif include_pid: - stack.append("%s-%d" % (sample.thread_comm, sample.pid)) - else: - stack.append(sample.thread_comm) - stack.reverse() - stacks[";".join(stack)] += sample.period - - for k in sorted(stacks.keys()): - print("%s %d" % (k, stacks[k])) - - -def main(): - parser = BaseArgumentParser(description=__doc__) - parser.add_argument('--symfs', - help='Set the path to find binaries with symbols and debug info.') - 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.') - parser.add_argument('--pid', action='store_true', help='Include PID with process names') - parser.add_argument('--tid', action='store_true', help='Include TID and PID with process names') - parser.add_argument('--kernel', action='store_true', - help='Annotate kernel functions with a _[k]') - parser.add_argument('--jit', action='store_true', help='Annotate JIT functions with a _[j]') - 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') - sample_filter_group.add_argument('--event-filter', nargs='?', default='', - help='Event type filter e.g. "cpu-cycles" or "instructions"') - 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, - symfs_dir=args.symfs, - kallsyms_file=args.kallsyms, - event_filter=args.event_filter, - include_pid=args.pid, - include_tid=args.tid, - annotate_kernel=args.kernel, - annotate_jit=args.jit, - include_addrs=args.addrs, - report_lib_options=args.report_lib_options) - - -if __name__ == '__main__': - main() |