summaryrefslogtreecommitdiff
path: root/simpleperf/scripts/stackcollapse.py
diff options
context:
space:
mode:
Diffstat (limited to 'simpleperf/scripts/stackcollapse.py')
-rwxr-xr-xsimpleperf/scripts/stackcollapse.py138
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()