def __init__(self): settings_manager = SettingsManager() # Set up the settings_manager max_workers = settings_manager.getint('application', 'max-workers') # Get the max workers from settings manager profiler_on = settings_manager.getint('debugging', 'profiler-on') # Get whether there is a profiler absolute = settings_manager.getint('save', 'absolute') # Get whether it's an absolute path save_path = settings_manager.get('save', 'path') # Get whether it's an absolute path if not absolute: save_path = PROJECT_PATH + os.path.sep + save_path executor = ThreadPoolExecutor(max_workers=max_workers, profiler_on=profiler_on) # Set up the thread executor dis = Disassembler(settings_manager) # Build the disassembler server = PyDAServer('0.0.0.0',9000) # Set up the PyDA server save_manager = SaveManager(save_path) if profiler_on: profile = Profile() profile.enable() app.build_and_run(settings_manager, dis, executor, server, save_manager) # Run the interface if profiler_on: profile.disable() stats = executor.getProfileStats() if stats == None: stats = Stats(profile) else: stats.add(profile) with open('profile.stats', 'wb') as statsfile: stats.stream = statsfile stats.sort_stats('cumulative').print_stats()
def stats_to_markdownstr(p: pstats.Stats, prtRowNum: int) -> str: """convert pstats result to markdown table Args: p (pstats.Stats): pstats result prtRowNum (int): only print several functions Returns: str: the markdown string with table """ s = io.StringIO() p.stream = s p.print_stats(prtRowNum) sumlines = [] _line = '' flag = True fp = 0 s.seek(0) while flag: fp = s.tell() _line = s.readline() _pl = _line.rstrip() flag = _line.find(" ncalls tottime") != 0 and _line if _pl and flag: sumlines.append(_pl) s.seek(fp) # rewind before table width, fncs = p.get_print_list((prtRowNum, )) results = [] for func in fncs: cc, nc, tt, ct, callers = p.stats[func] results.append( (nc, cc, tt, tt / nc, ct, ct / nc, pstats.func_std_string(func))) headers = [ 'ncalls', 'pcalls', 'tottime', 'tt percall', 'cumtime', 'ct percall', 'filename:lineno(function)' ] sumstr = '\n'.join(sumlines) tablestr = tabulate.tabulate(results, headers=headers, floatfmt='.3g', tablefmt='pipe') # for markdown resultstr = sumstr + '\n' + tablestr return resultstr
def __init__(self): settings_manager = SettingsManager() # Set up the settings_manager max_workers = settings_manager.getint( 'application', 'max-workers') # Get the max workers from settings manager profiler_on = settings_manager.getint( 'debugging', 'profiler-on') # Get whether there is a profiler absolute = settings_manager.getint( 'save', 'absolute') # Get whether it's an absolute path save_path = settings_manager.get( 'save', 'path') # Get whether it's an absolute path if not absolute: save_path = PROJECT_PATH + os.path.sep + save_path executor = ThreadPoolExecutor( max_workers=max_workers, profiler_on=profiler_on) # Set up the thread executor dis = Disassembler(settings_manager) # Build the disassembler server = PyDAServer('0.0.0.0', 9000) # Set up the PyDA server save_manager = SaveManager(save_path) if profiler_on: profile = Profile() profile.enable() app.build_and_run(settings_manager, dis, executor, server, save_manager) # Run the interface if profiler_on: profile.disable() stats = executor.getProfileStats() if stats == None: stats = Stats(profile) else: stats.add(profile) with open('profile.stats', 'wb') as statsfile: stats.stream = statsfile stats.sort_stats('cumulative').print_stats()
def profile(locals_dict, globals_dict, *args, **kwargs): """ Generates a profile You can request a profile anytime by appending ?profile to the url. If config.profile_passhash is set, then you must use ?profile=password where sha1(password.encode() + b'foobarusrex') == profile_passhash If the password is required and not correct, raises a value error. """ from tempfile import NamedTemporaryFile from hashlib import sha1 from io import StringIO import cProfile from pstats import Stats import regex key = kwargs['profile'].encode() + b'spambarusrex' if sc.config.app['profile_passhash'] and (sha1(key).hexdigest() != sc.config.app['profile_passhash']): raise ValueError('Invalid Password') with NamedTemporaryFile(prefix='profile') as tmpfile: cProfile.runctx("show.default(*args, **kwargs)", globals=globals_dict, locals=locals_dict, filename=tmpfile.name) stats = Stats(tmpfile.name) stats.sort_stats('tottime') stats.stream = StringIO() out = stats.stream.getvalue() splitpoint = out.find('ncalls') preamble = out[:splitpoint] table = out[splitpoint:] def splitdict(d): return ['{}: {}'.format(k, d[k]) for k in sorted(d)] m = regex.search(r'(?<= )(/home/.*)(/site-packages)(?=/)', table) site_packages = m[1] + m[2] if m else 'Unknown' table = table.replace(site_packages, '…') return '''<!DOCTYPE html><html><head><meta charset="utf8"> <title>{}</title>\ <body style="font-family: monospace;"> <h1> {} : Debug and Profile information</h1> <h2> Request Info: </h2> <pre>cherrypy.request.config = {{\n{}\n}}</pre> <pre>cherrypy.request.headers = {{\n{}\n}}</pre> <h2> Profile </h2> <pre>{}\nsite-packages (…) = {}</pre> <table><tbody>{}</tbody></table> <script src="/js/vendor/jquery-1.10.2.min.js"></script> <script src="/js/tablesort.js"></script>'''.format( 'Profile', ''.join('/' + a for a in args), '\n'.join(' ' + e for e in splitdict(cherrypy.request.config)), '\n'.join(' ' + e for e in splitdict(cherrypy.request.headers)), preamble, site_packages, '\n'.join('<tr>' + ''.join( '<td>{}'.format(s) for s in line.split(maxsplit=5)) for line in table.split('\n')) )