def dis(x=None): """Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ if x is None: dismodule.distb() return if hasattr(x, '__func__'): x = x.__func__ if hasattr(x, '__code__'): x = getattr(x, '__code__') if isinstance(x, FunctionType): x = sys.get_func_code(x) if hasattr(x, '__dict__'): items = sorted(x.__dict__.items()) for name, x1 in items: if isinstance( x1, (types.MethodType, types.FunctionType, types.CodeType, type)): print("Disassembly of %s:" % name) try: dis(x1) except TypeError as msg: print("Sorry:", msg) print() elif hasattr(x, 'co_code'): dismodule.disassemble(x) elif isinstance(x, (bytes, bytearray)): dismodule.disassemble_string(x) else: raise TypeError("don't know how to disassemble %s objects" % type(x).__name__)
def dis(x=None): """Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ if x is None: dismodule.distb() return if hasattr(x, '__func__'): x = x.__func__ if hasattr(x, '__code__'): x = getattr(x, '__code__') if isinstance(x, FunctionType): x = sys.get_func_code(x) if hasattr(x, '__dict__'): items = sorted(x.__dict__.items()) for name, x1 in items: if isinstance(x1, (types.MethodType, types.FunctionType, types.CodeType, type)): print("Disassembly of %s:" % name) try: dis(x1) except TypeError as msg: print("Sorry:", msg) print() elif hasattr(x, 'co_code'): dismodule.disassemble(x) elif isinstance(x, (bytes, bytearray)): dismodule.disassemble_string(x) else: raise TypeError("don't know how to disassemble %s objects" % type(x).__name__)
def whoaminow(): "returns name of called calling function" import sys, dis # get frame where calling function is called frame = sys._getframe(2) # get code and next to last instruction from frame code = frame.f_code lasti = frame.f_lasti - 3 # redirect ouput of disassemble (stdout) oldout = sys.stdout sys.stdout = open('log', 'w') dis.disassemble(code, lasti) sys.stdout.close() sys.stdout = oldout # restore stdout # retrieve current byte code line fd = open('log') for line in fd.xreadlines(): if line.startswith('-->'): break else: # couldn't find name line = None fd.close() # isolate function name if line is not None: funcname = line.split()[-1][1:-1] else: funcname = None return funcname
def show_code(code, indent=''): # pprint.pprint({x: getattr(code, x) for x in dir(code) if not x.startswith('__')}) # return print("%scode" % indent) indent += ' ' print("%sargcount %d" % (indent, code.co_argcount)) print("%snlocals %d" % (indent, code.co_nlocals)) print("%sstacksize %d" % (indent, code.co_stacksize)) print("%sflags %04x" % (indent, code.co_flags)) show_hex("code", code.co_code, indent=indent) dis.disassemble(code) print("%sconsts" % indent) for const in code.co_consts: if type(const) == types.CodeType: show_code(const, indent + ' ') else: print(" %s%r" % (indent, const)) print("%snames %r" % (indent, code.co_names)) print("%svarnames %r" % (indent, code.co_varnames)) print("%sfreevars %r" % (indent, code.co_freevars)) print("%scellvars %r" % (indent, code.co_cellvars)) print("%sfilename %r" % (indent, code.co_filename)) print("%skwonlyargcount %r" % (indent, code.co_kwonlyargcount)) print("%sname %r" % (indent, code.co_name)) print("%sfirstlineno %d" % (indent, code.co_firstlineno)) show_hex("lnotab", code.co_lnotab, indent=indent)
def show_code(code, indent='', number=None): label = "" if number is not None: label = "%d: " % number print("%s%scode" % (indent, label)) indent += ' ' print("%sname %r" % (indent, code.co_name)) print("%sargcount %d" % (indent, code.co_argcount)) print("%snlocals %d" % (indent, code.co_nlocals)) print("%sstacksize %d" % (indent, code.co_stacksize)) print("%sflags %04x: %s" % (indent, code.co_flags, flag_words(code.co_flags, CO_FLAGS))) show_hex("code", code.co_code, indent=indent) dis.disassemble(code) print("%sconsts" % indent) for i, const in enumerate(code.co_consts): if type(const) == types.CodeType: show_code(const, indent+' ', number=i) else: print(" %s%d: %r" % (indent, i, const)) print("%snames %r" % (indent, code.co_names)) print("%svarnames %r" % (indent, code.co_varnames)) print("%sfreevars %r" % (indent, code.co_freevars)) print("%scellvars %r" % (indent, code.co_cellvars)) print("%sfilename %r" % (indent, code.co_filename)) print("%sfirstlineno %d" % (indent, code.co_firstlineno)) show_hex("lnotab", code.co_lnotab, indent=indent)
def show_code(code, indent='', i=None): if i: i = "%d: " % i else: i = '' print "%s%scode" % (indent, i) indent += ' ' print "%sargcount %d" % (indent, code.co_argcount) print "%snlocals %d" % (indent, code.co_nlocals) print "%sstacksize %d" % (indent, code.co_stacksize) print "%sflags %04x" % (indent, code.co_flags) show_hex("code", code.co_code, indent=indent) dis.disassemble(code) print "%sconsts" % indent for i, const in zip(range(len(code.co_consts)),code.co_consts): if type(const) == types.CodeType: show_code(const, indent+' ', i) else: print " %s%d: %r" % (indent, i, const) print "%snames" % indent for i, name in zip(range(len(code.co_names)), code.co_names): print " %s%d: %r" % (indent, i, name) print "%svarnames %r" % (indent, code.co_varnames) print "%sfreevars %r" % (indent, code.co_freevars) print "%scellvars %r" % (indent, code.co_cellvars) print "%sfilename %r" % (indent, code.co_filename) print "%sname %r" % (indent, code.co_name) print "%sfirstlineno %d" % (indent, code.co_firstlineno) show_hex("lnotab", code.co_lnotab, indent=indent)
def unpack(exe_data): cookie = Cookie(exe_data[-Cookie.size:]) same_pyver = cookie.pyver == sys.version_info[0] * 10 + sys.version_info[1] if not same_pyver: print ('Warning: Python version does not match, ' 'will not unmarshal data') pkgstart = -cookie.len tocdata = exe_data[pkgstart + cookie.toc: pkgstart + cookie.toc + cookie.toclen] # Extract strings for entry in TOC(tocdata): data = exe_data[pkgstart + entry.pos: pkgstart + entry.pos + entry.len] if entry.cflag: data = decompress(data) if entry.typcd.lower() == 'm': # Module print 'Extracting module', entry.name with open(entry.name + '.pyc', 'wb') as outfile: outfile.write(data) if same_pyver: print 'Disassembling module', entry.name # skip header of pyc/pyo files and unmarshal the code # object code_object = marshal.loads(data[8:]) # Write dis output to file # Note: this is a hack, but dis seems to be a hack, too with wrap_stdio(open(entry.name + '.dis', 'w')): disassemble(code_object) elif entry.typcd == 's': print 'Extracting script', entry.name # Python script with open(entry.name + '.py', 'w') as outfile: outfile.write(data)
def get_disassembly(self, func, lasti=-1, wrapper=True): output = io.StringIO() if wrapper: dis.dis(func, file=output) else: dis.disassemble(func, lasti, file=output) return output.getvalue()
def show_code(code, indent='', number=None): label = "" if number is not None: label = "%d: " % number print("%s%scode" % (indent, label)) indent += ' ' print("%sname %r" % (indent, code.co_name)) print("%sargcount %d" % (indent, code.co_argcount)) print("%snlocals %d" % (indent, code.co_nlocals)) print("%sstacksize %d" % (indent, code.co_stacksize)) print("%sflags %04x: %s" % (indent, code.co_flags, flag_words(code.co_flags, CO_FLAGS))) show_hex("code", code.co_code, indent=indent) dis.disassemble(code) print("%sconsts" % indent) for i, const in enumerate(code.co_consts): if type(const) == types.CodeType: show_code(const, indent + ' ', number=i) else: print(" %s%d: %r" % (indent, i, const)) print("%snames %r" % (indent, code.co_names)) print("%svarnames %r" % (indent, code.co_varnames)) print("%sfreevars %r" % (indent, code.co_freevars)) print("%scellvars %r" % (indent, code.co_cellvars)) print("%sfilename %r" % (indent, code.co_filename)) print("%sfirstlineno %d" % (indent, code.co_firstlineno)) show_hex("lnotab", code.co_lnotab, indent=indent)
def show_code(code, indent=''): old_indent = indent print "%s<code>" % indent indent += ' ' print "%s<argcount> %d </argcount>" % (indent, code.co_argcount) print "%s<nlocals> %d</nlocals>" % (indent, code.co_nlocals) print "%s<stacksize> %d</stacksize>" % (indent, code.co_stacksize) print "%s<flags> %04x</flags>" % (indent, code.co_flags) show_hex("code", code.co_code, indent=indent) print "%s<dis>" % indent dis.disassemble(code) print "%s</dis>" % indent print "%s<names> %r</names>" % (indent, code.co_names) print "%s<varnames> %r</varnames>" % (indent, code.co_varnames) print "%s<freevars> %r</freevars>" % (indent, code.co_freevars) print "%s<cellvars> %r</cellvars>" % (indent, code.co_cellvars) print "%s<filename> %r</filename>" % (indent, code.co_filename) print "%s<name> %r</name>" % (indent, code.co_name) print "%s<firstlineno> %d</firstlineno>" % (indent, code.co_firstlineno) print "%s<consts>" % indent for const in code.co_consts: if type(const) == types.CodeType: show_code(const, indent+' ') else: print " %s%r" % (indent, const) print "%s</consts>" % indent show_hex("lnotab", code.co_lnotab, indent=indent) print "%s</code>" % old_indent
def view_pyc_file(path): """Read and display a content of the Python`s bytecode in a pyc-file.""" file = open(path, 'rb') magic = file.read(4) timestamp = file.read(4) size = None if sys.version_info.major == 3 and sys.version_info.minor >= 3: size = file.read(4) size = struct.unpack('I', size)[0] code = marshal.load(file) magic = binascii.hexlify(magic).decode('utf-8') timestamp = time.asctime( time.localtime(struct.unpack('I', b'D\xa5\xc2X')[0])) dis.disassemble(code) print('-' * 80) print('Python version: {}\nMagic code: {}\nTimestamp: {}\nSize: {}'.format( platform.python_version(), magic, timestamp, size)) file.close()
def f(): '''this function returns its x attribute even if the function's name changes uses the inspect and dis modules''' # look at the stack frame that called us caller = inspect.stack()[1][0] print(f"DEBUG: stack = {caller}") # disassemble the stack frame and pick out the call sys.stdout = io.StringIO() dis.disassemble(caller.f_code, caller.f_lasti) text = sys.stdout.getvalue() sys.stdout = sys.__stdout__ print(f"DEBUG: stack frame = {text}") match = re.search(r'LOAD_NAME.*\((.*?)\)\s+-->', text) name = match.group(1) # the name used to call the function print(f"DEBUG: function name = {name}") # now extract the x attribute value try: func = caller.f_locals[name] print(f"DEBUG: locals = {func}") print(f"DEBUG: x = {func.x}") except KeyError: func = caller.f_globals[name] print(f"x attribute = {func.x}")
def cut_asm(self, line, code): if line == -1: # ignore return code first = 0 last = codesize = len(code.co_code) lines = list(dis.findlinestarts(code)) for pos, (asm_line, src_line) in enumerate(lines): if line != asm_line: continue else: if asm_line == lines[-1][0]: first, last = (asm_line, codesize) else: first, last = (asm_line, lines[pos + 1][0]) break codestr = code.co_code[first:last] # Rebuild code object new_code = type(code)(code.co_argcount, code.co_nlocals, code.co_stacksize, code.co_flags, codestr, code.co_consts, code.co_names, code.co_varnames, code.co_filename, code.co_name, code.co_firstlineno, code.co_lnotab, code.co_freevars, code.co_cellvars) if self.metadebug: dis.disassemble(new_code) return new_code
def dis(): import dis funcs = sorted([f for f in globals() if f.endswith('_int')]) co = get_code('max_int') for f in funcs: print("dis func {0}:\n".format(f)) dis.disassemble(get_code(f))
def show_code(code, indent=''): print "%scode" % indent indent += ' ' print "%sargcount %d" % (indent, code.co_argcount) print "%snlocals %d" % (indent, code.co_nlocals) print "%sstacksize %d" % (indent, code.co_stacksize) print "%sflags %04x" % (indent, code.co_flags) show_hex("code", code.co_code, indent=indent) dis.disassemble(code) print "%sconsts" % indent for const in code.co_consts: if type(const) == types.CodeType: show_code(const, indent + ' ') else: print " %s%r" % (indent, const) print "%snames %r" % (indent, code.co_names) print "%svarnames %r" % (indent, code.co_varnames) print "%sfreevars %r" % (indent, code.co_freevars) print "%scellvars %r" % (indent, code.co_cellvars) print "%sfilename %r" % (indent, code.co_filename) print "%sname %r" % (indent, code.co_name) print "%sfirstlineno %d" % (indent, code.co_firstlineno) show_hex("lnotab", code.co_lnotab, indent=indent)
def get_disassembly(self, func, lasti=-1, wrapper=True): output = io.StringIO() with contextlib.redirect_stdout(output): if wrapper: dis.dis(func) else: dis.disassemble(func, lasti) return output.getvalue()
def eval_tree(t, verbose=False, dis=False): src = flatten_tree(t) if verbose: print(src, end='\n\n') fn = eval_def(src) if dis: print(fn.__name__ + ':', end='\n\n') disassemble(fn) print('\n\n') return fn
def dump(code_obj): for attr in sorted(dir(code_obj)): if not attr.startswith("__"): print(attr, getattr(code_obj, attr)) dis.disassemble(code_obj) for c in code_obj.co_consts: if hasattr(c, "co_code"): print() dump(c)
def get_disassembly(self, func, lasti=-1, wrapper=True): # We want to test the default printing behaviour, not the file arg output = io.StringIO() with contextlib.redirect_stdout(output): if wrapper: dis.dis(func) else: dis.disassemble(func, lasti) return output.getvalue()
def show_bytecode(code, level=0): indent = INDENT * level print(to_hexstr(code.co_code, level, wrap=True)) print(indent + "disassembled:") buffer = StringIO() sys.stdout = buffer dis.disassemble(code) sys.stdout = sys.__stdout__ print(indent + buffer.getvalue().replace("\n", "\n" + indent))
def show_bytecode(code, level=0): indent = INDENT*level print(to_hexstr(code.co_code, level, wrap=True)) print(indent+"disassembled:") buffer = StringIO() sys.stdout = buffer dis.disassemble(code) sys.stdout = sys.__stdout__ print(indent + buffer.getvalue().replace("\n", "\n"+indent))
def process(self, x, nextx): opcode, arg, nextopcode, nextarg = map( u8char, (x.opcode, x.arg, nextx.opcode, nextx.arg)) # if we are recursive if arg and arg >= 256: self.process(mk_extended_arg(arg >> 8, x), x) arg = u8char(arg % 256) need_close = (self.state >= U8.start2 and not opcode.cont or self.state >= U8.start3 and not arg.cont or self.state == U8.start2 and arg.cont or self.state == U8.start4 and not nextopcode.cont and opcode == dis.EXTENDED_ARG) self.need_ignore = False if self.verbose > 2: print(f'{x=}, {self.state=}, {need_close=}') if need_close and self.state >= U8.start2: self.maybe_insert_cont() # thankfully all opcodes are currently < 0xc0 if opcode.cont and self.state < U8.start2: val = 0xc3 if arg.cont: val = 0xe1 # escape arg as well if nextopcode.cont and not nextarg.cont: val = 0xf1 # escape next opcode as well self.maybe_insert_start(val, x) if self.need_ignore and opcode >= dis.HAVE_ARGUMENT: if self.newcode[-1] is None: self.newcode[-1] = ANY_ASCII self.newcode.extend((dis.opmap['NOP'], None)) if self.newcode[-1:] == [None]: self.newcode[-1] = ANY_ASCII self.newcode.extend((opcode, arg)) self.was_extended_arg = opcode == dis.EXTENDED_ARG if opcode.ascii and arg and arg.cont: print('Warn: opcode is low and arg is ' f'0x80 <= {arg:#02x} < 0xc2') if self.verbose > 1: dis.disassemble(self.codeobj, x.offset) if not arg: self.state = U8.ascii elif arg.start: self.state = arg.type elif opcode.start: # impossible self.state = opcode.type - 1 elif self.state >= U8.start2: self.state -= 2
def show_all(code): print('\n# Disassemble At : %s\n# Method Name : %s \n# File Name : %s\n' % (time.ctime(), re.search(r'<code object (.*?) at ', repr(code)).group(1), sys.argv[1])) dis.disassemble(code) for const in code.co_consts: if type(const) == types.CodeType: show_all(const) else: pass
def show_bytecode(code, level=0): indent = INDENT * level print(to_hexstr(code.co_code, level, wrap=True)) print(indent + "disassembled:") buffer = StringIO() sys.stdout = buffer # NOTE: This format has addresses in it, disable for now dis.disassemble(code) sys.stdout = sys.__stdout__ print(indent + buffer.getvalue().replace("\n", "\n" + indent))
def _disassemble_recursive(co, depth=None): disassemble(co) if depth is None or depth > 0: if depth is not None: depth = depth - 1 for x in co.co_consts: if hasattr(x, 'co_code'): print() print("Disassembly of %r:" % (x, )) _disassemble_recursive(x, depth=depth)
def disassemble(code): """Given a code object, return output from dis.disassemble as a string. (dis.disassemble writes its output to stdout.)""" rem = sys.stdout sys.stdout = cStringIO.StringIO() dis.disassemble(code) ret = sys.stdout.getvalue() ret = ret.replace(']]>', ']]X>') sys.stdout = rem return hex_pat.sub('0x...', ret)
def performance(): import dis dis.disassemble(some_function.__code__) size= len(some_function.__code__.co_code) print( "size", size) import timeit t= timeit.timeit( """some_function(4)""", """from Chapter_12.ch12_ex1 import some_function""" ) print( "time", t ) print( "byte/sec", 1000000*size/t )
def disassemble(code, depth=0): original_stdout = sys.stdout string_io = StringIO() sys.stdout = string_io dis.disassemble(code) sys.stdout = original_stdout assembly = string_io.getvalue().split('\n') interpret_call_function_arg(assembly) # in-place change space = ' ' assembly = '\n'.join([space * 2 * depth + line for line in assembly]) return assembly
def _disassemble_recursive(co, *, file=None, depth=None): import dis dis.disassemble(co, file=file) if depth is None or depth > 0: if depth is not None: depth = depth - 1 for x in co.co_consts: if hasattr(x, 'co_code'): print(file=file) print("Disassembly of %r:" % (x, ), file=file) _disassemble_recursive(x, file=file, depth=depth)
def get_disassembly(self, func, lasti=-1, wrapper=True): s = io.StringIO() save_stdout = sys.stdout sys.stdout = s try: if wrapper: dis.dis(func) else: dis.disassemble(func, lasti) finally: sys.stdout = save_stdout # Trim trailing blanks (if any). return [line.rstrip() for line in s.getvalue().splitlines()]
def performance(): import dis dis.disassemble(some_function.__code__) size = len(some_function.__code__.co_code) print(f"size {size} bytes") import timeit t = timeit.timeit( """some_function(4)""", """from Chapter_12.ch12_ex1 import some_function""" ) print(f"total time {t:.3f} sec. for 1,000,000 iterations") rate = 1_000_000*size/t print(f"rate {rate:,.0f} bytes/sec") print(f"rate {rate/1_000_000:,.1f} Mbytes/sec")
def f(): '''this function prints its name, even if called through a new reference''' # look at the stack frame that called us caller = inspect.stack()[1][0] print(f"DEBUG: stack = {caller}") # disassemble the stack frame and pick out the call sys.stdout = io.StringIO() dis.disassemble(caller.f_code, caller.f_lasti) text = sys.stdout.getvalue() sys.stdout = sys.__stdout__ print(f"DEBUG: stack frame = {text}") match = re.search(r'LOAD_NAME.*\((.*?)\)\s+-->', text) name = match.group(1) # the name used to call the function print(f"DEBUG: function name = {name}") print(f"I was called through: {name}")
def function_info(f): print('-----------------------------------------------') print('__name__:', f.__name__) print('__qualname__:', f.__qualname__) print('__doc__:', f.__doc__) print('__module__:', f.__module__) print('__dict__:', f.__dict__) print('__code__:', f.__code__) if True: print('__code__.co_argcount:', f.__code__.co_argcount) print('__code__.co_cellvars:', f.__code__.co_cellvars) print('__code__.co_code:', f.__code__.co_code) print('__code__.co_consts:', f.__code__.co_consts) print('__code__.co_filename:', f.__code__.co_filename) print('__code__.co_firstlineno:', f.__code__.co_firstlineno) print('__code__.co_flags:', f.__code__.co_flags) print('__code__.co_freevars:', f.__code__.co_freevars) print('__code__.co_kwonlyargcount:', f.__code__.co_kwonlyargcount) print('__code__.co_lnotab:', f.__code__.co_lnotab) print('__code__.co_name:', f.__code__.co_name) print('__code__.co_names:', f.__code__.co_names) print('__code__.co_nlocals:', f.__code__.co_nlocals) print('__code__.co_stacksize:', f.__code__.co_stacksize) print('__code__.co_varnames:', f.__code__.co_varnames) print('__defaults__:', f.__defaults__) print(dis.disassemble(f.__code__)) print('__kwdefaults__:', f.__kwdefaults__) print('__annotations__:', f.__annotations__) print('__closure__:', f.__closure__)
def reload2(target_module_obj): print 'import {}'.format(target_module_obj.__name__) reload(target_module_obj) with open(target_module_obj.__file__, 'rb') as f: f.read(8) module_code = marshal.load(f) stdout = cStringIO.StringIO() sys.stdout = stdout dis.disassemble(module_code) sys.stdout = sys.__stdout__ assembly_str = stdout.getvalue() stdout.close() print assembly_str
def caller_assignment_name(depth=0): frame = sys._getframe(depth + 2) dis.disassemble(frame.f_code, frame.f_lasti) # from pprint import pprint # pprint(list(dis.get_instructions(frame.f_code))) for op in list(dis.get_instructions(frame.f_code)): if op.offset < frame.f_lasti: continue if op.starts_line is not None: # We hit a new source line. break if op.opname == "STORE_NAME": return op.argval raise RuntimeError("Return value of caller must be assigned to a variable")
def f(): '''this function returns its x attribute even if the function's name changes uses the inspect and dis modules''' # look at the stack frame that called us caller = inspect.stack()[1][0] # disassemble the stack frame and pick out the call sys.stdout = io.StringIO() dis.disassemble(caller.f_code, caller.f_lasti) text = sys.stdout.getvalue() sys.stdout = sys.__stdout__ match = re.search(r'LOAD_NAME.*\((.*?)\)\s+-->', text) name = match.group(1) # the name used to call the function # now extract the x attribute value try: func = caller.f_locals[name] except KeyError: func = caller.f_globals[name] return func.x
def show_code(code, indent=''): print "%scode" % indent indent += ' ' print "%sargcount %d" % (indent, code.co_argcount) print "%snlocals %d" % (indent, code.co_nlocals) print "%sstacksize %d" % (indent, code.co_stacksize) print "%sflags %04x" % (indent, code.co_flags) show_hex("code", code.co_code, indent=indent) dis.disassemble(code) print "%sconsts" % indent for const in code.co_consts: if type(const) == types.CodeType: show_code(const, indent+' ') else: print " %s%r" % (indent, const) print "%snames %r" % (indent, code.co_names) print "%svarnames %r" % (indent, code.co_varnames) print "%sfreevars %r" % (indent, code.co_freevars) print "%scellvars %r" % (indent, code.co_cellvars) print "%sfilename %r" % (indent, code.co_filename) print "%sname %r" % (indent, code.co_name) print "%sfirstlineno %d" % (indent, code.co_firstlineno) show_hex("lnotab", code.co_lnotab, indent=indent)
import dis def add(pos,n): if (n%4)==0: return pos[0]+1,pos[1] if (n%4)==1: return pos[0],pos[1]+1 if (n%4)==2: return pos[0]-1,pos[1] return pos[0],pos[1]-1 def orthgen(pos): for n in range(4): yield add(pos,n) def orth(pos): res=[] for n in range(4): res.append(add(pos,n)) return res pos=(10,4) dis.dis(orthgen) dis.disassemble(orthgen) #~ print range(40)
#!/usr/bin/env python3 import dis def myFunc(): x = 1 y = 2 z = 'abc' # noqa return x + y print(myFunc.__name__) print(myFunc.__code__.co_varnames) print(myFunc.__code__.co_consts) print(myFunc.__code__.co_code) dis.disassemble(myFunc.__code__)
def disassemble(code_object): saver = out_saver() saver.start() dis.disassemble(code_object) s = saver.stop() return s
def show_bytecode(code, level=0): indent = INDENT * level print (to_hexstr(code.co_code, level, wrap=True)) print (indent + "disassembled:") dis.disassemble(code)
def send_head(self): global codebufs # CT self.trace_prev = None self.trace_next = None self.trace_addr = () if self.path == '/' or self.path == '/all': all = self.path == '/all' if all: title = 'List of ALL code objects' else: title = 'List of all named code objects' data = ['<ul>'] named = 0 proxies = 0 for codebuf in codebufs: if codebuf.data and codebuf.co_name: named += 1 else: if not codebuf.data: proxies += 1 if not all: continue data.append('<li>%s:\t%s:\t%s:\t%s\t(%d bytes)</li>\n' % ( codebuf.co_filename, codebuf.co_name, codebuf.get_next_instr(), self.symhtml(codebuf, codebuf.addr), len(codebuf.data))) data.append('</ul>\n') data.append('<br><a href="/">%d named buffers</a>; ' % named + '<a href="/all">%d buffers in total</a>, ' % len(codebufs) + 'including %d proxies' % proxies) data = ''.join(data) return self.donepage(title, data) match = re_codebuf.match(self.path) if match: addr = long(match.group(1), 16) codebuf = xam.codeat(addr) if not codebuf: self.send_error(404, "No code buffer at this address") return None if codebuf.addr != addr: self.trace_addr = [addr] title = '%s code buffer at 0x%x' % (codebuf.mode.capitalize(), codebuf.addr) data = self.bufferpage(codebuf) return self.donepage(title, data) match = re_trace.match(self.path) if match: tracepos = int(match.group(1), 16) f = open(tracefilename, 'rb') try: def traceat(p, f=f): f.seek(p) data = f.read(4) if len(data) == 4: addr, = struct.unpack('L', data) return addr else: raise IOError addr = traceat(tracepos) codebuf = xam.codeat(addr) if not codebuf: self.send_error(404, "No code buffer at 0x%x" % addr) return None start = codebuf.addr end = start + len(codebuf.data) while tracepos > 0: addr1 = traceat(tracepos-4) if not (start <= addr1 < addr): break tracepos -= 4 addr = addr1 self.trace_prev = tracepos-4 self.trace_addr = [] while 1: self.trace_addr.append(addr) addr1 = traceat(tracepos+4) if not (addr < addr1 < end): break tracepos += 4 addr = addr1 self.trace_next = tracepos+4 finally: f.close() title = '%s code buffer at 0x%x' % (codebuf.mode.capitalize(), codebuf.addr) data = self.bufferpage(codebuf) return self.donepage(title, data) match = re_traces.match(self.path) if match: traceaddr = long(match.group(1), 16) f = open(tracefilename, 'rb') plist = find4(f, struct.pack('L', traceaddr)) f.close() title = 'Traces through 0x%x' % traceaddr data = ['<ul>'] for p in plist: data.append("<li><a href='/trace0x%x'>0x%x</a>\n" % (p, p)) data.append('</ul>') data = ''.join(data) return self.donepage(title, data) match = re_trlist.match(self.path) if match: start = int(match.group(1), 16) end = int(match.group(2), 16) title = 'Traces timed 0x%x to 0x%x' % (start, end) data = ["<p><a href='/trace0x%x-0x%x'><<<<</a></p>\n" % (start-(end-start), start), '<ul>'] f = open(tracefilename, 'rb') f.seek(start) prevname = None for p in range(start, end, 4): addr, = struct.unpack('L', f.read(4)) s = self.try_hard_to_name(addr) if s == prevname: continue data.append("<li><a href='/trace0x%x'>0x%x: %s</a>\n" % (p,p,s)) prevname = s data.append('</ul>') data.append( "<p><a href='/trace0x%x-0x%x'>>>>></a></p>\n" % (end, end+(end-start))) f.close() data = ''.join(data) return self.donepage(title, data) match = re_proxy.match(self.path) if match: title = 'Snapshot' n = int(match.group(1)) proxy = codebufs[n] for n1 in xrange(n-1, -1, -1): pprev = codebufs[n1] if (pprev.nextinstr == proxy.nextinstr and pprev.co_name == proxy.co_name and pprev.co_filename == proxy.co_filename): pprev = n1 break else: pprev = None for n1 in xrange(n+1, len(codebufs)): pnext = codebufs[n1] if (pnext.nextinstr == proxy.nextinstr and pnext.co_name == proxy.co_name and pnext.co_filename == proxy.co_filename): pnext = n1 break else: pnext = None filename = os.path.join(DIRECTORY, proxy.co_filename) co = cache_load(filename, proxy.co_name) data = '<p>PsycoObject structure at this point:' data += ' ' * 20 data += '[' data += ' <a href="summary%d">summary</a> ' % n if pprev is not None or pnext is not None: if pprev is not None: data += ' <a href="proxy%d"><<< previous</a> ' % pprev if pnext is not None: data += ' <a href="proxy%d">next >>></a> ' % pnext data += ']' data += '</p>\n' data += show_vinfos(proxy.vlocals, {}, co) data += '<hr><p>Disassembly of %s:%s:%s:</p>\n' % ( proxy.co_filename, proxy.co_name, proxy.get_next_instr()) if co is None: #moduledata is None: txt = "(exception while loading the file '%s')\n" % ( filename) else: if not hasattr(co, 'co_code'): txt = "(no function object '%s' in file '%s')\n" % ( proxy.co_name, filename) else: txt = cStringIO.StringIO() oldstdout = sys.stdout try: sys.stdout = txt dis.disassemble(co, proxy.get_next_instr()) finally: sys.stdout = oldstdout txt = txt.getvalue() data += '<pre>%s</pre>\n' % txt data += "<br><a href='/0x%x'>Back</a>\n" % proxy.addr return self.donepage(title, data) match = re_summary.match(self.path) if match: n = int(match.group(1)) proxy = codebufs[n] data = summary_vinfos(proxy.vlocals, {}) f = cStringIO.StringIO(data) self.send_response(200) self.send_header("Content-type", "text/plain") self.end_headers() return f if self.path == '/checkall': for codebuf in codebufs: codebuf.cache_text f = cStringIO.StringIO('done') self.send_response(200) self.send_header("Content-type", "text/plain") self.end_headers() return f ## CT: simple reload feature if self.path == "/reload": codebufs = xam.readdump(FILENAME) self.path = "/all" return self.send_head() self.send_error(404, "Invalid path") return None
x = x.im_func if isinstance(x, types.FunctionType): x = sys.get_func_code(x) if hasattr(x, "__dict__"): items = x.__dict__.items() items.sort() for name, x1 in items: if type(x1) in (types.MethodType, types.FunctionType, types.CodeType, types.ClassType): print "Disassembly of %s:" % name try: dis(x1) except TypeError, msg: print "Sorry:", msg print elif hasattr(x, "co_code"): dismodule.disassemble(x) elif isinstance(x, str): dismodule.disassemble_string(x) else: raise TypeError, "don't know how to disassemble %s objects" % type(x).__name__ def getargspec(func): """Get the names and default values of a function's arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments. """
import dis def square(x): print "running" return x*x dis.disassemble(square.func_code) # 4 0 LOAD_CONST 1 ('running') # 3 PRINT_ITEM # 4 PRINT_NEWLINE # 5 5 LOAD_FAST 0 (x) # 8 LOAD_FAST 0 (x) # 11 BINARY_MULTIPLY # 12 RETURN_VALUE
import dis import inspect import timeit programs = dict( loop=""" multiples_of_two = [] for x in range(100): if x % 2 == 0: multiples_of_two.append(x) """, comprehension='multiples_of_two = [x for x in range(100) if x % 2 == 0]', ) for name, text in programs.iteritems(): print name, timeit.Timer(stmt=text).timeit() code = compile(text, '<string>', 'exec') dis.disassemble(code)