summaryrefslogtreecommitdiff
path: root/simpleperf
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2016-11-30 19:39:53 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2016-11-30 19:39:54 +0000
commit090785e4dd013bd3d69dcb47659dc3b7e60ff090 (patch)
treedc67fc3aced9530791d007b401bf48882b252cfc /simpleperf
parent1bc97843cbabdc375b3658704a3292c6f2f395d2 (diff)
parent4ff9c6fd83baa05effade39a2a000b1b233fa371 (diff)
downloadextras-090785e4dd013bd3d69dcb47659dc3b7e60ff090.tar.gz
Merge "simpleperf: improve script interface."
Diffstat (limited to 'simpleperf')
-rw-r--r--simpleperf/scripts/report_sample.py15
-rw-r--r--simpleperf/scripts/simpleperf_report_lib.py91
2 files changed, 88 insertions, 18 deletions
diff --git a/simpleperf/scripts/report_sample.py b/simpleperf/scripts/report_sample.py
index 7e733266..0da37977 100644
--- a/simpleperf/scripts/report_sample.py
+++ b/simpleperf/scripts/report_sample.py
@@ -18,6 +18,7 @@
"""report_sample.py: report samples in the same format as `perf script`.
"""
+from __future__ import print_function
import sys
from simpleperf_report_lib import *
@@ -51,12 +52,14 @@ def report_sample(record_file, symfs_dir, kallsyms_file=None):
symbol = lib.GetSymbolOfCurrentSample()
callchain = lib.GetCallChainOfCurrentSample()
- sec = sample[0].time / 1000000000
- usec = (sample[0].time - sec * 1000000000) / 1000
- print('%s\t%d [%03d] %d.%d:\t\t%d %s:' % (sample[0].thread_comm, sample[0].tid, sample[0].cpu, sec, usec, sample[0].period, event[0].name))
- print('%16x\t%s (%s)' % (sample[0].ip, symbol[0].symbol_name, symbol[0].dso_name))
- for i in range(callchain[0].nr):
- entry = callchain[0].entries[i]
+ sec = sample.time / 1000000000
+ usec = (sample.time - sec * 1000000000) / 1000
+ print('%s\t%d [%03d] %d.%d:\t\t%d %s:' % (sample.thread_comm,
+ sample.tid, sample.cpu, sec,
+ usec, sample.period, event.name))
+ print('%16x\t%s (%s)' % (sample.ip, symbol.symbol_name, symbol.dso_name))
+ for i in range(callchain.nr):
+ entry = callchain.entries[i]
print('%16x\t%s (%s)' % (entry.ip, entry.symbol.symbol_name, entry.symbol.dso_name))
print('')
diff --git a/simpleperf/scripts/simpleperf_report_lib.py b/simpleperf/scripts/simpleperf_report_lib.py
index 1ccecdcd..46264beb 100644
--- a/simpleperf/scripts/simpleperf_report_lib.py
+++ b/simpleperf/scripts/simpleperf_report_lib.py
@@ -63,7 +63,6 @@ def _char_pt_to_str(char_pt):
return char_pt.decode('utf-8')
-# TODO: convert fields of type c_char_p into str for python3.
class SampleStruct(ct.Structure):
_fields_ = [('ip', ct.c_uint64),
('pid', ct.c_uint32),
@@ -95,6 +94,47 @@ class CallChainStructure(ct.Structure):
_fields_ = [('nr', ct.c_uint32),
('entries', ct.POINTER(CallChainEntryStructure))]
+
+# convert char_p to str for python3.
+class SampleStructUsingStr(object):
+ def __init__(self, sample):
+ self.ip = sample.ip
+ self.pid = sample.pid
+ self.tid = sample.tid
+ self.thread_comm = _char_pt_to_str(sample.thread_comm)
+ self.time = sample.time
+ self.in_kernel = sample.in_kernel
+ self.cpu = sample.cpu
+ self.period = sample.period
+
+
+class EventStructUsingStr(object):
+ def __init__(self, event):
+ self.name = _char_pt_to_str(event.name)
+
+
+class SymbolStructUsingStr(object):
+ def __init__(self, symbol):
+ self.dso_name = _char_pt_to_str(symbol.dso_name)
+ self.vaddr_in_file = symbol.vaddr_in_file
+ self.symbol_name = _char_pt_to_str(symbol.symbol_name)
+ self.symbol_addr = symbol.symbol_addr
+
+
+class CallChainEntryStructureUsingStr(object):
+ def __init__(self, entry):
+ self.ip = entry.ip
+ self.symbol = SymbolStructUsingStr(entry.symbol)
+
+
+class CallChainStructureUsingStr(object):
+ def __init__(self, callchain):
+ self.nr = callchain.nr
+ self.entries = []
+ for i in range(self.nr):
+ self.entries.append(CallChainEntryStructureUsingStr(callchain.entries[i]))
+
+
class ReportLibStructure(ct.Structure):
_fields_ = []
@@ -129,6 +169,8 @@ class ReportLib(object):
self._instance = self._CreateReportLibFunc()
assert(not _is_null(self._instance))
+ self.convert_to_str = (sys.version_info >= (3, 0))
+
def _load_dependent_lib(self):
# As the windows dll is built with mingw we need to also find "libwinpthread-1.dll".
# Load it before libsimpleperf_report.dll if it does exist in the same folder as this script.
@@ -170,22 +212,30 @@ class ReportLib(object):
sample = self._GetNextSampleFunc(self.getInstance())
if _is_null(sample):
return None
- return sample
+ if self.convert_to_str:
+ return SampleStructUsingStr(sample[0])
+ return sample[0]
def GetEventOfCurrentSample(self):
event = self._GetEventOfCurrentSampleFunc(self.getInstance())
assert(not _is_null(event))
- return event
+ if self.convert_to_str:
+ return EventStructUsingStr(event[0])
+ return event[0]
def GetSymbolOfCurrentSample(self):
symbol = self._GetSymbolOfCurrentSampleFunc(self.getInstance())
assert(not _is_null(symbol))
- return symbol
+ if self.convert_to_str:
+ return SymbolStructUsingStr(symbol[0])
+ return symbol[0]
def GetCallChainOfCurrentSample(self):
callchain = self._GetCallChainOfCurrentSampleFunc(self.getInstance())
assert(not _is_null(callchain))
- return callchain
+ if self.convert_to_str:
+ return CallChainStructureUsingStr(callchain[0])
+ return callchain[0]
def GetBuildIdForPath(self, path):
build_id = self._GetBuildIdForPathFunc(self.getInstance(), _char_pt(path))
@@ -219,18 +269,35 @@ class TestReportLib(unittest.TestCase):
self.assertEqual(build_id, '0x70f1fe24500fc8b0d9eb477199ca1ca21acca4de')
def test_symbol_addr(self):
- met_func2 = False
+ found_func2 = False
while True:
sample = self.report_lib.GetNextSample()
if sample is None:
break
- event = self.report_lib.GetEventOfCurrentSample()
symbol = self.report_lib.GetSymbolOfCurrentSample()
- symbol_name = _char_pt_to_str(symbol[0].symbol_name)
- if symbol_name == 'func2(int, int)':
- met_func2 = True
- self.assertEqual(symbol[0].symbol_addr, 0x4004ed)
- self.assertTrue(met_func2)
+ if symbol.symbol_name == 'func2(int, int)':
+ found_func2 = True
+ self.assertEqual(symbol.symbol_addr, 0x4004ed)
+ self.assertTrue(found_func2)
+
+ def test_sample(self):
+ found_sample = False
+ while True:
+ sample = self.report_lib.GetNextSample()
+ if sample is None:
+ break
+ if sample.ip == 0x4004ff and sample.time == 7637889424953:
+ found_sample = True
+ self.assertEqual(sample.pid, 15926)
+ self.assertEqual(sample.tid, 15926)
+ self.assertEqual(sample.thread_comm, 't2')
+ self.assertEqual(sample.cpu, 5)
+ self.assertEqual(sample.period, 694614)
+ event = self.report_lib.GetEventOfCurrentSample()
+ self.assertEqual(event.name, 'cpu-cycles')
+ callchain = self.report_lib.GetCallChainOfCurrentSample()
+ self.assertEqual(callchain.nr, 0)
+ self.assertTrue(found_sample)
def main():