tools/profiler/merge-profiles.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial