monotone

monotone Mtn Source Tree

Root/contrib/op2calltree.py

  • Property mtn:execute set to true
1#!/usr/bin/python
2
3# feed this file opreport -gcf on stdin, and it will spit out
4# calltree on stdout
5
6# http://kcachegrind.sourceforge.net/cgi-bin/show.cgi/KcacheGrindCalltreeFormat
7
8import sys
9import os.path
10
11def main():
12 convert(sys.stdin, sys.stdout)
13
14# need to store:
15# bunch of function data
16# for each function, its file/line location, plus name
17# plus total samples directly in it
18# plus list of functions called
19# -- call count (which we don't have)
20# -- the file/line number/name of the function called
21# -- inclusive cost of those calls
22def convert(op, ct):
23 for line in op:
24 if line.startswith("Counted "):
25 ct.write("events: %s" % line.split(" ", 3)[1])
26 continue
27 if line.startswith("-" * 70):
28 # found our first stanza
29 break
30 stanza = []
31 for line in op:
32 if line.startswith("-" * 70):
33 process_stanza(stanza, ct)
34 stanza = []
35 else:
36 stanza.append(line)
37
38# some sample lines:
39# 601802 9.9042 botan/sha160.cpp:54 /home/njs/src/monotone/vlogs-test/mtn-client _ZN5Botan7SHA_1604hashEPKh
40# 1585865 26.0995 (no location information) /usr/lib/libstdc++.so.6.0.7 (no symbols)
41# we return the tuple: (count, filename, line, object, symbol)
42def parse_line(line):
43 rest = line.strip()
44 count, percent, rest = rest.split(None, 2)
45 if rest.startswith("(no location information)"):
46 filename = "(unknown)"
47 line = "0"
48 blah, blah, blah, rest = rest.split(None, 3)
49 else:
50 filename_line, rest = rest.split(None, 1)
51 assert ":" in filename_line
52 filename, line = filename_line.split(":")
53 object, rest = rest.split(None, 1)
54 symbol = rest.strip()
55 return (count, filename, line, object, symbol)
56
57def process_stanza(stanza, ct):
58 ct.write("\n")
59 it = iter(stanza)
60 # skip over the parent call info
61 for line in it:
62 # skip past the caller lines
63 if line[0] not in "0123456789":
64 continue
65 # process the direct cost line
66 count, filename, line, object, symbol = parse_line(line)
67 ct.write("fl=%s\n" % filename)
68 ct.write("ob=%s\n" % object)
69 ct.write("fn=%s\n" % symbol)
70 ct.write("%s %s\n" % (line, count))
71 # save for later
72 caller_line = line
73 # start processing next set of lines
74 break
75 # process the cumulative child cost lines
76 for line in it:
77 if "[self]" in line:
78 continue
79 count, filename, line, object, symbol = parse_line(line)
80 ct.write("cfi=%s\n" % filename)
81 ct.write("cob=%s\n" % object)
82 ct.write("cfn=%s\n" % symbol)
83 # we don't know how many calls were made, so just hard-code to "1"
84 # and we don't know the line number the calls were made from, so just
85 # pretend everything came from the same line our function started on
86 ct.write("calls=%s %s\n" % (1, line))
87 ct.write("%s %s\n" % (caller_line, count))
88
89if __name__ == "__main__":
90 main()

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status