Fix the --stats flag (#26)

* start re-integrating profiling functionality

* profiling works

* rename X class

* make profile a private attribute

* nomenclature fixes

* profiling -> profile

* remove _dump stats

* always initialize self._profile

* remove extra setting of profiling
This commit is contained in:
JP Smith 2017-02-27 14:45:12 -06:00 committed by GitHub
parent d6393cc8a6
commit d052d3b2d7
3 changed files with 24 additions and 32 deletions

View File

@ -25,7 +25,7 @@ def parse_arguments():
parser.add_argument('--log', type=str, default='-',
help='The log filename')
parser.add_argument('--verbose', action='store_true', help='Enable debug mode.')
parser.add_argument('--stats', action='store_true', help='Enable profiling mode.')
parser.add_argument('--profile', action='store_true', help='Enable profiling mode.')
parser.add_argument('--buffer', type=str, help='Specify buffer to make symbolic')
parser.add_argument('--size', type=str, help='Specify buffer full size')
@ -84,6 +84,9 @@ def main():
if args.log:
m.log_file = args.log
if args.profile:
m.should_profile = args.profile
if args.dumpafter != 0:
m.dumpafter = args.dumpafter

View File

@ -29,6 +29,7 @@ import time
import os
import copy
import cPickle
import cProfile
import random
import logging
import traceback
@ -315,9 +316,9 @@ class Executor(object):
self.max_states = options.get('maxstates', 0)
self.max_storage = options.get('maxstorage', 0)
self.replay_path = options.get('replay', None) #(dest, cond, origin)
self.profiling = None
self._dump_every = options.get('dumpafter', 0)
self._dump_stats = options.get('dumpstats', False)
self._profile = cProfile.Profile()
self.profiling = options.get('dumpstats', False)
# Signals
self.will_execute_pc = Signal()
@ -363,13 +364,13 @@ class Executor(object):
#If we are continuin from a set of saved states replay is not supported
assert self.replay_path is None
def dumpStats(self):
def dump_stats(self):
if not self.profiling:
logger.debug("Profiling not enabled.")
return
import pstats
class X:
class PstatsFormatted:
def __init__(self, d):
self.stats = dict(d)
def create_stats(self):
@ -377,10 +378,14 @@ class Executor(object):
ps = None
for item in self._stats:
if ps is None:
ps = pstats.Stats(X(item))
else:
ps.add(X(item))
try:
stat = PstatsFormatted(item)
if ps is None:
ps = pstats.Stats(stat)
else:
ps.add(stat)
except TypeError:
logger.debug("Incorrectly formatted profiling information in _stats, skipping")
if ps is None:
logger.info("Profiling failed")
@ -837,22 +842,9 @@ class Executor(object):
self._count.value += count
self._lock.notify_all()
@property
def profiling(self):
return (self.profile is not None)
@profiling.setter
def profiling(self, enable):
if enable:
if not self.profile:
import cProfile
self.profile = cProfile.Profile()
else:
self.profile = None
def run(self):
if self.profiling:
self._profile.enable()
policy_order=self.policy_order
policy=self.policy
@ -1073,11 +1065,11 @@ class Executor(object):
with DelayedKeyboardInterrupt():
#notify siblings we are about to stop this run
self._stopRun(count)
if self._dump_stats:
pr.disable()
pr.create_stats()
if self.profiling:
self._profile.disable()
self._profile.create_stats()
with self._lock:
self._stats.append(pr.stats.items())
self._stats.append(self._profile.stats.items())
return count

View File

@ -564,9 +564,6 @@ class Manticore(object):
if self._assertions:
self._executor.will_execute_pc += self._assertions_callback
if self.should_profile:
self._executor.profiling = True
self._time_started = time.time()
self._running = True
@ -632,7 +629,7 @@ class Manticore(object):
for m in self._executor.errors:
f.write(fmt.format(m))
self._executor.dumpStats()
self._executor.dump_stats()
logger.info('Results dumped in %s', self.workspace)
logger.info('Instructions executed: %d', self._executor.count)