manticore/stats.py
Mark Mossberg 04d95735ac Fix empty trace file (#39)
* Improve .trace generation

* Rm unused self.trace stuff
2017-03-01 13:47:55 -05:00

80 lines
3.0 KiB
Python

import sys, os, cPickle, argparse
#Process the data of a workspace and prints out some global information
def parse_arguments():
################################################################################
# parse arguments
parser = argparse.ArgumentParser(description='Extract different statistic and information from a manticore workspace')
parser.add_argument('--workspace', type=str, default=None,
help='A folder name fpor temporaries and results. (default mcore_?????)')
parser.add_argument('--pcfreq', action='store_true', help='Print out visited pc and frequency')
parser.add_argument('--visited', action='store_true', help='Print out visited pc set')
parser.add_argument('--bbs', action='store_true', help='Print out visited basic blocks ')
parser.add_argument('workspace', type=str, nargs=1, metavar='WORKSPACE',
help='The folder name for temporaries and results' )
parsed = parser.parse_args(sys.argv[1:])
parsed.workspace = parsed.workspace[0]
assert int(parsed.pcfreq) + int(parsed.visited)+ int(parsed.bbs) == 1, "Choose one option one option from: --pcfreq --visited"
return parsed
args = parse_arguments()
workspace = args.workspace
#search previously generated states
saved_states = [ os.path.join(workspace, filename) for filename in os.listdir(workspace) if filename.endswith('.pkl') ]
#prepare a dictionary to hold stats
db = {}
edges = {}
for filename in saved_states:
try:
with open(filename, "r") as f:
#load the whole saved state (memory/cpu/solver/..)
state = cPickle.loads(f.read())
lastpc = 'ROOT'
for proc, pc in state.visited:
assert proc == 0, 'Multi process no supported'
db[pc] = db.setdefault(pc,0) + 1
edges.setdefault(lastpc,[]).append(pc)
lastpc=pc
except Exception,e:
print "#Failed to load saved state %s (%s)"%(filename,e)
if args.pcfreq :
print '#PC: frequency'
for pc, freq in sorted(db.items(), key=lambda x: -x[1]):
print '%x: %d'%(pc,freq)
elif args.visited:
print '#PC'
for pc in db.keys():
print '%x'%pc
elif args.bbs:
assert len(set(edges['ROOT'])) == 1, "Something is wrong it should be only one root"
bbs = set()
for targets in edges.values():
if len(set(targets)) > 1:
[ bbs.add(x) for x in set(targets) ]
bbs.add('ROOT')
print '#BBs'
for origin in bbs:
if origin not in edges:
targets = set()
else:
targets = set(edges[origin])
while len(targets) == 1:
node = list(targets)[0]
if node in edges:
targets = set(edges[node])
else:
targets = ['END']
break
def p(x):
return isinstance(x, int) and hex(x) or x
print '%s -> [%s]'%(p(origin), ', '.join(map(p, targets)) )