tools/profiler/merge-profiles.py

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rwxr-xr-x

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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
    12 def MergeProfiles(files):
    13     threads = []
    14     fileData = []
    15     symTable = dict()
    16     meta = None
    17     libs = None
    18     minStartTime = None
    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]
    27         fp = open(fname, "r")
    28         fileData = json.load(fp)
    29         fp.close()
    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
    39         for thread in fileData['profileJSON']['threads']:
    40             thread['name'] = thread['name'] + " (" + pname + ":" + pid + ")"
    41             threads.append(thread)
    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 + ":"
    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
    58         filesyms = fileData['symbolicationTable']
    59         for sym in filesyms.keys():
    60             symTable[pidStr + sym] = filesyms[sym]
    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
    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"
    78     json.dump(result, sys.stdout)
    81 if len(sys.argv) > 1:
    82     MergeProfiles(sys.argv[1:])
    83     sys.exit(0)
    85 print "Usage: merge-profile.py profile_<pid1>_<pname1>.sym profile_<pid2>_<pname2>.sym > merged.sym"

mercurial