Skip to content

Commit 0896778

Browse files
committed
Drop OProfile support.
1 parent 59b318e commit 0896778

File tree

6 files changed

+1
-14701
lines changed

6 files changed

+1
-14701
lines changed

MANIFEST.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ recursive-include tests *.hprof
99
recursive-include tests *.json
1010
recursive-include tests *.leaked.json
1111
recursive-include tests *.maximum.json
12-
recursive-include tests *.oprofile
1312
recursive-include tests *.perf
1413
recursive-include tests *.prof
1514
recursive-include tests *.skorupski.prof

README.md

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ It can:
77
* read output from:
88
* [Linux perf](https://perf.wiki.kernel.org/)
99
* [Valgrind's callgrind tool](https://valgrind.org/docs/manual/cl-manual.html)
10-
* [OProfile](https://oprofile.sourceforge.net/)
1110
* [Sysprof](http://www.sysprof.com/)
1211
* [Xperf](https://learn.microsoft.com/en-us/windows-hardware/test/wpt/)
1312
* [VTune](https://www.intel.com/content/www/us/en/developer/tools/oneapi/vtune-profiler.html)
@@ -92,7 +91,7 @@ Options:
9291
eliminate edges below this threshold [default: 0.1]
9392
-f FORMAT, --format=FORMAT
9493
profile format: axe, callgrind, collapse, dtrace,
95-
hprof, json, oprofile, perf, prof, pstats, sleepy,
94+
hprof, json, perf, prof, pstats, sleepy,
9695
sysprof or xperf [default: prof]
9796
--total=TOTALMETHOD preferred method of calculating total time: callratios
9897
or callstacks (currently affects only perf format)
@@ -157,15 +156,6 @@ Options:
157156
perf record -g -- /path/to/your/executable
158157
perf script | c++filt | gprof2dot.py -f perf | dot -Tpng -o output.png
159158

160-
### oprofile
161-
162-
opcontrol --callgraph=16
163-
opcontrol --start
164-
/path/to/your/executable arg1 arg2
165-
opcontrol --stop
166-
opcontrol --dump
167-
opreport -cgf | gprof2dot.py -f oprofile | dot -Tpng -o output.png
168-
169159
### xperf
170160

171161
If you're not familiar with xperf then read [this excellent article](https://blogs.msdn.com/b/pigscanfly/archive/2009/08/06/stack-walking-in-xperf.aspx) first. Then do:

gprof2dot.py

Lines changed: 0 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,173 +2114,6 @@ def parse_call(self):
21142114
return function
21152115

21162116

2117-
class OprofileParser(LineParser):
2118-
"""Parser for oprofile callgraph output.
2119-
2120-
See also:
2121-
- http://oprofile.sourceforge.net/doc/opreport.html#opreport-callgraph
2122-
"""
2123-
2124-
_fields_re = {
2125-
'samples': r'(\d+)',
2126-
'%': r'(\S+)',
2127-
'linenr info': r'(?P<source>\(no location information\)|\S+:\d+)',
2128-
'image name': r'(?P<image>\S+(?:\s\(tgid:[^)]*\))?)',
2129-
'app name': r'(?P<application>\S+)',
2130-
'symbol name': r'(?P<symbol>\(no symbols\)|.+?)',
2131-
}
2132-
2133-
def __init__(self, infile):
2134-
LineParser.__init__(self, infile)
2135-
self.entries = {}
2136-
self.entry_re = None
2137-
2138-
def add_entry(self, callers, function, callees):
2139-
try:
2140-
entry = self.entries[function.id]
2141-
except KeyError:
2142-
self.entries[function.id] = (callers, function, callees)
2143-
else:
2144-
callers_total, function_total, callees_total = entry
2145-
self.update_subentries_dict(callers_total, callers)
2146-
function_total.samples += function.samples
2147-
self.update_subentries_dict(callees_total, callees)
2148-
2149-
def update_subentries_dict(self, totals, partials):
2150-
for partial in partials.values():
2151-
try:
2152-
total = totals[partial.id]
2153-
except KeyError:
2154-
totals[partial.id] = partial
2155-
else:
2156-
total.samples += partial.samples
2157-
2158-
def parse(self):
2159-
# read lookahead
2160-
self.readline()
2161-
2162-
self.parse_header()
2163-
while self.lookahead():
2164-
self.parse_entry()
2165-
2166-
profile = Profile()
2167-
2168-
reverse_call_samples = {}
2169-
2170-
# populate the profile
2171-
profile[SAMPLES] = 0
2172-
for _callers, _function, _callees in self.entries.values():
2173-
function = Function(_function.id, _function.name)
2174-
function[SAMPLES] = _function.samples
2175-
profile.add_function(function)
2176-
profile[SAMPLES] += _function.samples
2177-
2178-
if _function.application:
2179-
function.process = os.path.basename(_function.application)
2180-
if _function.image:
2181-
function.module = os.path.basename(_function.image)
2182-
2183-
total_callee_samples = 0
2184-
for _callee in _callees.values():
2185-
total_callee_samples += _callee.samples
2186-
2187-
for _callee in _callees.values():
2188-
if not _callee.self:
2189-
call = Call(_callee.id)
2190-
call[SAMPLES2] = _callee.samples
2191-
function.add_call(call)
2192-
2193-
# compute derived data
2194-
profile.validate()
2195-
profile.find_cycles()
2196-
profile.ratio(TIME_RATIO, SAMPLES)
2197-
profile.call_ratios(SAMPLES2)
2198-
profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO)
2199-
2200-
return profile
2201-
2202-
def parse_header(self):
2203-
while not self.match_header():
2204-
self.consume()
2205-
line = self.lookahead()
2206-
fields = re.split(r'\s\s+', line)
2207-
entry_re = r'^\s*' + r'\s+'.join([self._fields_re[field] for field in fields]) + r'(?P<self>\s+\[self\])?$'
2208-
self.entry_re = re.compile(entry_re)
2209-
self.skip_separator()
2210-
2211-
def parse_entry(self):
2212-
callers = self.parse_subentries()
2213-
if self.match_primary():
2214-
function = self.parse_subentry()
2215-
if function is not None:
2216-
callees = self.parse_subentries()
2217-
self.add_entry(callers, function, callees)
2218-
self.skip_separator()
2219-
2220-
def parse_subentries(self):
2221-
subentries = {}
2222-
while self.match_secondary():
2223-
subentry = self.parse_subentry()
2224-
subentries[subentry.id] = subentry
2225-
return subentries
2226-
2227-
def parse_subentry(self):
2228-
entry = Struct()
2229-
line = self.consume()
2230-
mo = self.entry_re.match(line)
2231-
if not mo:
2232-
raise ParseError('failed to parse', line)
2233-
fields = mo.groupdict()
2234-
entry.samples = int(mo.group(1))
2235-
if 'source' in fields and fields['source'] != '(no location information)':
2236-
source = fields['source']
2237-
filename, lineno = source.split(':')
2238-
entry.filename = filename
2239-
entry.lineno = int(lineno)
2240-
else:
2241-
source = ''
2242-
entry.filename = None
2243-
entry.lineno = None
2244-
entry.image = fields.get('image', '')
2245-
entry.application = fields.get('application', '')
2246-
if 'symbol' in fields and fields['symbol'] != '(no symbols)':
2247-
entry.symbol = fields['symbol']
2248-
else:
2249-
entry.symbol = ''
2250-
if entry.symbol.startswith('"') and entry.symbol.endswith('"'):
2251-
entry.symbol = entry.symbol[1:-1]
2252-
entry.id = ':'.join((entry.application, entry.image, source, entry.symbol))
2253-
entry.self = fields.get('self', None) != None
2254-
if entry.self:
2255-
entry.id += ':self'
2256-
if entry.symbol:
2257-
entry.name = entry.symbol
2258-
else:
2259-
entry.name = entry.image
2260-
return entry
2261-
2262-
def skip_separator(self):
2263-
while not self.match_separator():
2264-
self.consume()
2265-
self.consume()
2266-
2267-
def match_header(self):
2268-
line = self.lookahead()
2269-
return line.startswith('samples')
2270-
2271-
def match_separator(self):
2272-
line = self.lookahead()
2273-
return line == '-'*len(line)
2274-
2275-
def match_primary(self):
2276-
line = self.lookahead()
2277-
return not line[:1].isspace()
2278-
2279-
def match_secondary(self):
2280-
line = self.lookahead()
2281-
return line[:1].isspace()
2282-
2283-
22842117
class HProfParser(LineParser):
22852118
"""Parser for java hprof output
22862119
@@ -3035,7 +2868,6 @@ def _make_function(self, call):
30352868
"collapse": CollapseParser,
30362869
"hprof": HProfParser,
30372870
"json": JsonParser,
3038-
"oprofile": OprofileParser,
30392871
"perf": PerfParser,
30402872
"prof": GprofParser,
30412873
"pstats": PstatsParser,

0 commit comments

Comments
 (0)