tools/profiler/merge-profiles.py

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:f91a922d56f7
1 #!/usr/bin/env python
2 #
3 # This script takes b2g process profiles and merged them into a single profile.
4 # The meta data is taken from the first profile. The startTime for each profile
5 # is used to syncronized the samples. Each thread is moved into the merged
6 # profile.
7 #
8 import json
9 import re
10 import sys
11
12 def MergeProfiles(files):
13 threads = []
14 fileData = []
15 symTable = dict()
16 meta = None
17 libs = None
18 minStartTime = None
19
20 for fname in files:
21 match = re.match('profile_([0-9]+)_(.+)\.sym', fname)
22 if match is None:
23 raise Exception("Filename '" + fname + "' doesn't match expected pattern")
24 pid = match.groups(0)[0]
25 pname = match.groups(0)[1]
26
27 fp = open(fname, "r")
28 fileData = json.load(fp)
29 fp.close()
30
31 if meta is None:
32 meta = fileData['profileJSON']['meta'].copy()
33 libs = fileData['profileJSON']['libs']
34 minStartTime = meta['startTime']
35 else:
36 minStartTime = min(minStartTime, fileData['profileJSON']['meta']['startTime'])
37 meta['startTime'] = minStartTime
38
39 for thread in fileData['profileJSON']['threads']:
40 thread['name'] = thread['name'] + " (" + pname + ":" + pid + ")"
41 threads.append(thread)
42
43 # Note that pid + sym, pid + location could be ambigious
44 # if we had pid=11 sym=1 && pid=1 sym=11.
45 pidStr = pid + ":"
46
47 thread['startTime'] = fileData['profileJSON']['meta']['startTime']
48 samples = thread['samples']
49 for sample in thread['samples']:
50 for frame in sample['frames']:
51 if "location" in frame and frame['location'][0:2] == '0x':
52 oldLoc = frame['location']
53 newLoc = pidStr + oldLoc
54 frame['location'] = newLoc
55 # Default to the unprefixed symbol if no translation is available
56 symTable[newLoc] = oldLoc
57
58 filesyms = fileData['symbolicationTable']
59 for sym in filesyms.keys():
60 symTable[pidStr + sym] = filesyms[sym]
61
62 # For each thread, make the time offsets line up based on the
63 # earliest start
64 for thread in threads:
65 delta = thread['startTime'] - minStartTime
66 for sample in thread['samples']:
67 if "time" in sample:
68 sample['time'] += delta
69
70 result = dict()
71 result['profileJSON'] = dict()
72 result['profileJSON']['meta'] = meta
73 result['profileJSON']['libs'] = libs
74 result['profileJSON']['threads'] = threads
75 result['symbolicationTable'] = symTable
76 result['format'] = "profileJSONWithSymbolicationTable,1"
77
78 json.dump(result, sys.stdout)
79
80
81 if len(sys.argv) > 1:
82 MergeProfiles(sys.argv[1:])
83 sys.exit(0)
84
85 print "Usage: merge-profile.py profile_<pid1>_<pname1>.sym profile_<pid2>_<pname2>.sym > merged.sym"
86
87
88

mercurial