def event_processor(self, frame, event, event_arg, prompt='trepan3k'): 'command event processor: reading a commands do something with them.' self.frame = frame self.event = event self.event_arg = event_arg filename = frame.f_code.co_filename lineno = frame.f_lineno line = linecache.getline(filename, lineno, frame.f_globals) if not line: opts = { 'output': 'plain', 'reload_on_change': self.settings('reload'), 'strip_nl': False } m = re.search('^<frozen (.*)>', filename) if m and m.group(1): filename = pyficache.unmap_file(m.group(1)) line = pyficache.getline(filename, lineno, opts) self.current_source_text = line if self.settings('skip') is not None: if Mbytecode.is_def_stmt(line, frame): return True if Mbytecode.is_class_def(line, frame): return True pass self.thread_name = Mthread.current_thread_name() self.frame_thread_name = self.thread_name self.set_prompt(prompt) self.process_commands() if filename == '<string>': pyficache.remove_remap_file('<string>') return True
def format_location(proc_obj): """Show where we are. GUI's and front-end interfaces often use this to update displays. So it is helpful to make sure we give at least some place that's located in a file. """ i_stack = proc_obj.curindex if i_stack is None or proc_obj.stack is None: return False location = {} core_obj = proc_obj.core dbgr_obj = proc_obj.debugger # Evaluation routines like "exec" don't show useful location # info. In these cases, we will use the position before that in # the stack. Hence the looping below which in practices loops # once and sometimes twice. remapped_file = None while i_stack >= 0: frame_lineno = proc_obj.stack[i_stack] i_stack -= 1 frame, lineno = frame_lineno filename = Mstack.frame2file(core_obj, frame) location['filename'] = filename location['fn_name'] = frame.f_code.co_name location['lineno'] = lineno if '<string>' == filename and dbgr_obj.eval_string: remapped_file = filename filename = pyficache.unmap_file(filename) if '<string>' == filename: fd = tempfile.NamedTemporaryFile(suffix='.py', prefix='eval_string', delete=False) fd.write(bytes(dbgr_obj.eval_string, 'UTF-8')) fd.close() pyficache.remap_file(fd.name, '<string>') filename = fd.name pass pass opts = { 'reload_on_change': proc_obj.settings('reload'), 'output': 'plain' } line = pyficache.getline(filename, lineno, opts) if not line: line = linecache.getline(filename, lineno, proc_obj.curframe.f_globals) pass if line and len(line.strip()) != 0: location['text'] = line pass if '<string>' != filename: break pass return location
def format_location(proc_obj): """Show where we are. GUI's and front-end interfaces often use this to update displays. So it is helpful to make sure we give at least some place that's located in a file. """ i_stack = proc_obj.curindex if i_stack is None or proc_obj.stack is None: return False location = {} core_obj = proc_obj.core dbgr_obj = proc_obj.debugger # Evaluation routines like "exec" don't show useful location # info. In these cases, we will use the position before that in # the stack. Hence the looping below which in practices loops # once and sometimes twice. remapped_file = None while i_stack >= 0: frame_lineno = proc_obj.stack[i_stack] i_stack -= 1 frame, lineno = frame_lineno filename = Mstack.frame2file(core_obj, frame) location['filename'] = filename location['fn_name'] = frame.f_code.co_name location['lineno'] = lineno if '<string>' == filename and dbgr_obj.eval_string: remapped_file = filename filename = pyficache.unmap_file(filename) if '<string>' == filename: fd = tempfile.NamedTemporaryFile(suffix='.py', prefix='eval_string', delete=False) fd.write(bytes(dbgr_obj.eval_string, 'UTF-8')) fd.close() pyficache.remap_file(fd.name, '<string>') filename = fd.name pass pass opts = { 'reload_on_change' : proc_obj.settings('reload'), 'output' : 'plain' } line = pyficache.getline(filename, lineno, opts) if not line: line = linecache.getline(filename, lineno, proc_obj.curframe.f_globals) pass if line and len(line.strip()) != 0: location['text'] = line pass if '<string>' != filename: break pass return location
def event_processor(self, frame, event, event_arg, prompt="trepan3k"): """ command event processor: reading a commands do something with them. See https://docs.python.org/3/library/sys.html#sys.settrace for how this protocol works and what the events means. Of particular note those is what we return: The local trace function should return a reference to itself (or to another function for further tracing in that scope), or None to turn off tracing in that scope. If there is any error occurred in the trace function, it will be unset, just like settrace(None) is called. """ self.frame = frame self.event = event self.event_arg = event_arg filename = frame.f_code.co_filename lineno = frame.f_lineno line = linecache.getline(filename, lineno, frame.f_globals) if not line: opts = { "output": "plain", "reload_on_change": self.settings("reload"), "strip_nl": False, } m = re.search("^<frozen (.*)>", filename) if m and m.group(1): filename = pyficache.unmap_file(m.group(1)) line = pyficache.getline(filename, lineno, opts) self.current_source_text = line if self.settings("skip") is not None: if is_def_stmt(line, frame): return self.event_processor if is_class_def(line, frame): return self.event_processor pass self.thread_name = Mthread.current_thread_name() self.frame_thread_name = self.thread_name self.set_prompt(prompt) self.process_commands() if filename == "<string>": pyficache.remove_remap_file("<string>") return self.event_processor
def frame_setup(frame): filename = frame.f_code.co_filename lineno = frame.f_lineno line = linecache.getline(filename, lineno, frame.f_globals) if not line: opts = { "output": "plain", "reload_on_change": self.settings("reload"), "strip_nl": False, } m = re.search("^<frozen (.*)>", filename) if m and m.group(1): filename = pyficache.unmap_file(m.group(1)) line = pyficache.getline(filename, lineno, opts) self.current_source_text = line return line, filename
def canonic(self, filename): """ Turns `filename' into its canonic representation and returns this string. This allows a user to refer to a given file in one of several equivalent ways. Relative filenames need to be fully resolved, since the current working directory might change over the course of execution. If filename is enclosed in < ... >, then we assume it is one of the bogus internal Python names like <string> which is seen for example when executing "exec cmd". """ if filename == "<" + filename[1:-1] + ">": return filename canonic = self.filename_cache.get(filename) if not canonic: lead_dir = filename.split(os.sep)[0] if lead_dir == os.curdir or lead_dir == os.pardir: # We may have invoked the program from a directory # other than where the program resides. filename is # relative to where the program resides. So make sure # to use that. canonic = os.path.abspath(os.path.join(self.main_dirname, filename)) else: canonic = os.path.abspath(filename) pass if not os.path.isfile(canonic): canonic = Mclifns.search_file(filename, self.search_path, self.main_dirname) # FIXME: is this is right for utter failure? if not canonic: self.filename_cache[filename] = filename return filename pass canonic = os.path.realpath(os.path.normcase(canonic)) self.filename_cache[filename] = canonic canonic = pyficache.unmap_file(canonic) return canonic
def run(self, args): filename, first, last = self.parse_list_cmd(args[1:]) curframe = self.proc.curframe if filename is None: return m = re.search('^<frozen (.*)>', filename) if m and m.group(1): filename = m.group(1) canonic_filename = pyficache.unmap_file(filename) else: filename = pyc2py(filename) canonic_filename = os.path.realpath(os.path.normcase(filename)) max_line = pyficache.size(filename) # FIXME: Should use the below: # max_line = pyficache.maxline(filename) # We now have range information. Do the listing. if max_line is None: self.errmsg('No file %s found' % filename) return if first > max_line: self.errmsg('Bad start line %d - file "%s" has only %d lines' % (first, filename, max_line)) return if last > max_line: self.msg('End position changed to last line %d ' % max_line) last = max_line bplist = self.core.bpmgr.bplist opts = { 'reload_on_change' : self.settings['reload'], 'output' : self.settings['highlight'], 'strip_nl' : False, } if 'style' in self.settings: opts['style'] = self.settings['style'] try: for lineno in range(first, last+1): line = pyficache.getline(filename, lineno, opts) if line is None: line = linecache.getline(filename, lineno, self.proc.frame.f_globals) pass if line is None: self.msg('[EOF]') break else: line = line.rstrip('\n') s = self.proc._saferepr(lineno).rjust(3) if len(s) < 5: s += ' ' if (canonic_filename, lineno,) in list(bplist.keys()): bp = bplist[(canonic_filename, lineno,)][0] a_pad = '%02d' % bp.number s += bp.icon_char() else: s += ' ' a_pad = ' ' pass if curframe and lineno == inspect.getlineno(curframe): s += '->' if 'plain' != self.settings['highlight']: s = colorize('bold', s) else: s += a_pad pass self.msg(s + '\t' + line) self.proc.list_lineno = lineno pass pass except KeyboardInterrupt: pass return False
def print_location(proc_obj): """Show where we are. GUI's and front-end interfaces often use this to update displays. So it is helpful to make sure we give at least some place that's located in a file. """ i_stack = proc_obj.curindex if i_stack is None or proc_obj.stack is None: return False core_obj = proc_obj.core dbgr_obj = proc_obj.debugger intf_obj = dbgr_obj.intf[-1] # Evaluation routines like "exec" don't show useful location # info. In these cases, we will use the position before that in # the stack. Hence the looping below which in practices loops # once and sometimes twice. remapped_file = None while i_stack >= 0: frame_lineno = proc_obj.stack[i_stack] i_stack -= 1 frame, lineno = frame_lineno # # Next check to see that local variable breadcrumb exists and # # has the magic dynamic value. # # If so, it's us and we don't normally show this.a # if 'breadcrumb' in frame.f_locals: # if self.run == frame.f_locals['breadcrumb']: # break filename = Mstack.frame2file(core_obj, frame, canonic=False) if '<string>' == filename and dbgr_obj.eval_string: remapped_file = filename filename = pyficache.unmap_file(filename) if '<string>' == filename: fd = tempfile.NamedTemporaryFile(suffix='.py', prefix='eval_string', delete=False) with fd: fd.write(dbgr_obj.eval_string) fd.close() pass pyficache.remap_file(fd.name, '<string>') filename = fd.name pass pass else: if filename in pyficache.file2file_remap: remapped_file = pyficache.unmap_file(filename) # FIXME: a remapped_file shouldn't be the same as its unmapped version if remapped_file == filename: remapped_file = None pass pass pass opts = { 'reload_on_change' : proc_obj.settings('reload'), 'output' : proc_obj.settings('highlight') } if 'style' in proc_obj.debugger.settings: opts['style'] = proc_obj.settings('style') pyficache.update_cache(filename) line = pyficache.getline(filename, lineno, opts) if not line: # FIXME: # try with good ol linecache and consider fixing pyficache lines = linecache.getlines(filename) if lines: # FIXME: DRY code with version in cmdproc.py print_location prefix = os.path.basename(filename).split('.')[0] fd = tempfile.NamedTemporaryFile(suffix='.py', prefix=prefix, delete=False) with fd: fd.write(''.join(lines)) remapped_file = fd.name pyficache.remap_file(remapped_file, filename) fd.close() pass line = linecache.getline(filename, lineno, proc_obj.curframe.f_globals) pass fn_name = frame.f_code.co_name last_i = frame.f_lasti print_source_location_info(intf_obj.msg, filename, lineno, fn_name, remapped_file = remapped_file, f_lasti = last_i) if line and len(line.strip()) != 0: if proc_obj.event: print_source_line(intf_obj.msg, lineno, line, proc_obj.event2short[proc_obj.event]) pass if '<string>' != filename: break pass if proc_obj.event in ['return', 'exception']: val = proc_obj.event_arg intf_obj.msg('R=> %s' % proc_obj._saferepr(val)) pass return True
def run(self, args): proc = self.proc dbg_obj = self.core.debugger listsize = dbg_obj.settings["listsize"] filename, first, last = parse_list_cmd(proc, args, listsize) curframe = proc.curframe if filename is None: return filename = pyficache.unmap_file( pyficache.resolve_name_to_path(filename)) # We now have range information. Do the listing. max_line = pyficache.size(filename) if max_line is None: bytecode = curframe.f_code if bytecode not in deparse_cache.keys(): self.errmsg( 'No file %s found; using "deparse" command instead to show source' % filename) proc.commands["deparse"].run(["deparse"]) return canonic_filename = osp.realpath(osp.normcase(filename)) if first > max_line: self.errmsg('Bad start line %d - file "%s" has only %d lines' % (first, filename, max_line)) return if last > max_line: self.msg("End position changed to last line %d " % max_line) last = max_line bplist = self.core.bpmgr.bplist opts = { "reload_on_change": self.settings["reload"], "output": self.settings["highlight"], "strip_nl": False, } if "style" in self.settings: opts["style"] = self.settings["style"] if first <= 0: first = 1 try: for lineno in range(first, last + 1): line = pyficache.getline(filename, lineno, opts) if line is None: line = linecache.getline(filename, lineno, proc.frame.f_globals) pass if line is None: self.msg("[EOF]") break else: line = line.rstrip("\n") s = proc._saferepr(lineno).rjust(3) if len(s) < 5: s += " " if ( canonic_filename, lineno, ) in list(bplist.keys()): bp = bplist[( canonic_filename, lineno, )][0] a_pad = "%02d" % bp.number s += bp.icon_char() else: s += " " a_pad = " " pass if curframe and lineno == inspect.getlineno(curframe): s += "->" if "plain" != self.settings["highlight"]: s = colorize("bold", s) else: s += a_pad pass self.msg(s + "\t" + line) proc.list_lineno = lineno pass pass pass except KeyboardInterrupt: pass return False
def print_location(proc_obj): """Show where we are. GUI's and front-end interfaces often use this to update displays. So it is helpful to make sure we give at least some place that's located in a file. """ i_stack = proc_obj.curindex if i_stack is None or proc_obj.stack is None: return False core_obj = proc_obj.core dbgr_obj = proc_obj.debugger intf_obj = dbgr_obj.intf[-1] # Evaluation routines like "exec" don't show useful location # info. In these cases, we will use the position before that in # the stack. Hence the looping below which in practices loops # once and sometimes twice. remapped_file = None source_text = None while i_stack >= 0: frame_lineno = proc_obj.stack[i_stack] i_stack -= 1 frame, lineno = frame_lineno # # Next check to see that local variable breadcrumb exists and # # has the magic dynamic value. # # If so, it's us and we don't normally show this.a # if 'breadcrumb' in frame.f_locals: # if self.run == frame.f_locals['breadcrumb']: # break filename = Mstack.frame2file(core_obj, frame, canonic=False) if "<string>" == filename and dbgr_obj.eval_string: remapped_file = filename filename = pyficache.unmap_file(filename) if "<string>" == filename: remapped = source_tempfile_remap( "eval_string", dbgr_obj.eval_string, tempdir=proc_obj.settings("tempdir")) pyficache.remap_file(filename, remapped) filename = remapped lineno = pyficache.unmap_file_line(filename, lineno) pass pass elif "<string>" == filename: source_text = deparse_fn(frame.f_code) filename = "<string: '%s'>" % source_text pass elif filename in proc_obj.file2file_remap: remapped_file = proc_obj.file2file_remap[filename] elif filename in pyficache.file2file_remap: remapped_file = pyficache.unmap_file(filename) # FIXME: a remapped_file shouldn't be the same as its unmapped version if remapped_file == filename: remapped_file = None pass pass elif pyficache.main.remap_re_hash: remapped_file = pyficache.remap_file_pat( filename, pyficache.main.remap_re_hash) opts = { "reload_on_change": proc_obj.settings("reload"), "output": proc_obj.settings("highlight"), } if "style" in proc_obj.debugger.settings: opts["style"] = proc_obj.settings("style") pyficache.update_cache(filename) line = pyficache.getline(filename, lineno, opts) if not line: if (not source_text and filename.startswith("<string: ") and proc_obj.curframe.f_code): # Deparse the code object into a temp file and remap the line from code # into the corresponding line of the tempfile co = proc_obj.curframe.f_code tempdir = proc_obj.settings("tempdir") temp_filename, name_for_code = deparse_and_cache( co, proc_obj.errmsg, tempdir=tempdir) lineno = 1 # _, lineno = pyficache.unmap_file_line(temp_filename, lineno, True) if temp_filename: filename = temp_filename pass else: # FIXME: if source_text: lines = source_text.split("\n") temp_name = "string-" else: # try with good ol linecache and consider fixing pyficache lines = linecache.getlines(filename) temp_name = filename if lines: # FIXME: DRY code with version in cmdproc.py print_location prefix = osp.basename(temp_name).split(".")[0] fd = tempfile.NamedTemporaryFile( suffix=".py", prefix=prefix, delete=False, dir=proc_obj.settings("tempdir"), ) with fd: fd.write("".join(lines)) remapped_file = fd.name pyficache.remap_file(remapped_file, filename) fd.close() pass line = linecache.getline(filename, lineno, proc_obj.curframe.f_globals) pass fn_name = frame.f_code.co_name last_i = frame.f_lasti print_source_location_info( intf_obj.msg, filename, lineno, fn_name, remapped_file=remapped_file, f_lasti=last_i, ) if line and len(line.strip()) != 0: if proc_obj.event: print_source_line(intf_obj.msg, lineno, line, proc_obj.event2short[proc_obj.event]) pass if "<string>" != filename: break pass if proc_obj.event in ["return", "exception"]: val = proc_obj.event_arg intf_obj.msg("R=> %s" % proc_obj._saferepr(val)) pass return True
def print_location(proc_obj): """Show where we are. GUI's and front-end interfaces often use this to update displays. So it is helpful to make sure we give at least some place that's located in a file. """ i_stack = proc_obj.curindex if i_stack is None or proc_obj.stack is None: return False core_obj = proc_obj.core dbgr_obj = proc_obj.debugger intf_obj = dbgr_obj.intf[-1] # Evaluation routines like "exec" don't show useful location # info. In these cases, we will use the position before that in # the stack. Hence the looping below which in practices loops # once and sometimes twice. remapped_file = None while i_stack >= 0: frame_lineno = proc_obj.stack[i_stack] i_stack -= 1 frame, lineno = frame_lineno # # Next check to see that local variable breadcrumb exists and # # has the magic dynamic value. # # If so, it's us and we don't normally show this.a # if 'breadcrumb' in frame.f_locals: # if self.run == frame.f_locals['breadcrumb']: # break filename = Mstack.frame2file(core_obj, frame, canonic=False) if '<string>' == filename and dbgr_obj.eval_string: remapped_file = filename filename = pyficache.unmap_file(filename) if '<string>' == filename: remapped = cmdfns.source_tempfile_remap( 'eval_string', dbgr_obj.eval_string) pyficache.remap_file(filename, remapped) filename = remapped pass pass else: m = re.search('^<frozen (.*)>', filename) if m and m.group(1) in pyficache.file2file_remap: remapped_file = pyficache.file2file_remap[m.group(1)] pass elif filename in pyficache.file2file_remap: remapped_file = pyficache.unmap_file(filename) # FIXME: a remapped_file shouldn't be the same as its unmapped version if remapped_file == filename: remapped_file = None pass pass elif m and m.group(1) in sys.modules: remapped_file = m.group(1) pyficache.remap_file(filename, remapped_file) pass code = frame.f_code fn_name = code.co_name last_i = frame.f_lasti opts = { 'reload_on_change': proc_obj.settings('reload'), 'output': proc_obj.settings('highlight') } if 'style' in proc_obj.debugger.settings: opts['style'] = proc_obj.settings('style') line = pyficache.getline(filename, lineno, opts) if not line: line = linecache.getline(filename, lineno, proc_obj.curframe.f_globals) if not line: m = re.search('^<frozen (.*)>', filename) if m and m.group(1): remapped_file = m.group(1) try_module = sys.modules.get(remapped_file) if (try_module and inspect.ismodule(try_module) and hasattr(try_module, '__file__')): remapped_file = sys.modules[remapped_file].__file__ pyficache.remap_file(filename, remapped_file) line = linecache.getline(remapped_file, lineno, proc_obj.curframe.f_globals) else: remapped_file = m.group(1) filename, line = cmdfns.deparse_getline( code, remapped_file, lineno, opts) pass pass try: match, reason = Mstack.check_path_with_frame(frame, filename) if not match: if filename not in warned_file_mismatches: proc_obj.errmsg(reason) warned_file_mismatches.add(filename) except: pass print_source_location_info(intf_obj.msg, filename, lineno, fn_name, remapped_file=remapped_file, f_lasti=last_i) if line and len(line.strip()) != 0: if proc_obj.event: print_source_line(intf_obj.msg, lineno, line, proc_obj.event2short[proc_obj.event]) pass if '<string>' != filename: break pass if proc_obj.event in ['return', 'exception']: val = proc_obj.event_arg intf_obj.msg('R=> %s' % proc_obj._saferepr(val)) pass return True
def run(self, args): """Get file information""" if len(args) == 0: if not self.proc.curframe: self.errmsg("No frame - no default file.") return False filename = self.proc.curframe.f_code.co_filename else: filename = args[0] pass m = filename + " is" filename_cache = self.core.filename_cache if filename in filename_cache: m += " cached in debugger" if filename_cache[filename] != filename: m += " as:" m = Mmisc.wrapped_lines(m, filename_cache[filename] + ".", self.settings["width"]) else: m += "." pass self.msg(m) else: matches = [file for file in file_list() if file.endswith(filename)] if len(matches) > 1: self.msg("Multiple files found ending filename string:") for match_file in matches: self.msg("\t%s" % match_file) pass elif len(matches) == 1: canonic_name = pyficache.unmap_file(matches[0]) m += " matched debugger cache file:\n " + canonic_name self.msg(m) else: self.msg(m + " not cached in debugger.") pass canonic_name = self.core.canonic(filename) self.msg(Mmisc.wrapped_lines("Canonic name:", canonic_name, self.settings["width"])) for name in (canonic_name, filename): if name in sys.modules: for key in [k for k, v in list(sys.modules.items()) if name == v]: self.msg("module: %s", key) pass pass pass for arg in args[1:]: processed_arg = False if arg in ["all", "size"]: if pyficache.size(canonic_name): self.msg("File has %d lines." % pyficache.size(canonic_name)) pass processed_arg = True pass if arg in ["all", "sha1"]: self.msg("SHA1 is %s." % pyficache.sha1(canonic_name)) processed_arg = True pass if arg in ["all", "brkpts"]: lines = pyficache.trace_line_numbers(canonic_name) if lines: self.section("Possible breakpoint line numbers:") fmt_lines = columnize.columnize(lines, ljust=False, arrange_vertical=False, lineprefix=" ") self.msg(fmt_lines) pass processed_arg = True pass if not processed_arg: self.errmsg("Don't understand sub-option %s." % arg) pass pass return
def run(self, args): """**info files** [*filename* [**all** | **brkpts** | **lines** | **sha1** | **size**]] Show information about the current file. If no filename is given and the program is running then the current file associated with the current stack entry is used. Sub options which can be shown about a file are: * **brkpts** Line numbers where there are statement boundaries. These lines can be used in breakpoint commands. * **sha1** A SHA1 hash of the source text. The following may be useful in comparing source code. * **size** The number of lines in the file. * **all** All of the above information. """ if len(args) == 0: if not self.proc.curframe: self.errmsg("No frame - no default file.") return False filename = self.proc.curframe.f_code.co_filename else: filename = args[0] pass m = filename + " is" filename_cache = self.core.filename_cache if filename in filename_cache: m += " cached in debugger" if filename_cache[filename] != filename: m += " as:" m = Mmisc.wrapped_lines(m, filename_cache[filename] + ".", self.settings["width"]) else: m += "." pass self.msg(m) else: matches = [file for file in file_list() if file.endswith(filename)] if len(matches) > 1: self.msg("Multiple files found ending filename string:") for match_file in matches: self.msg("\t%s" % match_file) pass elif len(matches) == 1: canonic_name = pyficache.unmap_file(matches[0]) m += " matched debugger cache file:\n " + canonic_name self.msg(m) else: self.msg(m + " not cached in debugger.") pass canonic_name = self.core.canonic(filename) self.msg( Mmisc.wrapped_lines("Canonic name:", canonic_name, self.settings["width"])) for name in (canonic_name, filename): if name in sys.modules: for key in [ k for k, v in list(sys.modules.items()) if name == v ]: self.msg("module: %s", key) pass pass pass for arg in args[1:]: processed_arg = False if arg in ["all", "size"]: if pyficache.size(canonic_name): self.msg("File has %d lines." % pyficache.size(canonic_name)) pass processed_arg = True pass if arg in ["all", "sha1"]: self.msg("SHA1 is %s." % pyficache.sha1(canonic_name)) processed_arg = True pass if arg in ["all", "brkpts"]: lines = pyficache.trace_line_numbers(canonic_name) if lines: self.section("Possible breakpoint line numbers:") fmt_lines = columnize.columnize( list(lines), ljust=False, arrange_vertical=False, lineprefix=" ", ) self.msg(fmt_lines) pass processed_arg = True pass if not processed_arg: self.errmsg("Don't understand sub-option %s." % arg) pass pass return
def run(self, args): filename, first, last = self.parse_list_cmd(args[1:]) curframe = self.proc.curframe if filename is None: return filename = pyficache.unmap_file(pyc2py(filename)) # We now have range information. Do the listing. max_line = pyficache.size(filename) if max_line is None: self.errmsg('No file %s found' % filename) return canonic_filename = os.path.realpath(os.path.normcase(filename)) if first > max_line: self.errmsg('Bad start line %d - file "%s" has only %d lines' % (first, filename, max_line)) return if last > max_line: self.msg('End position changed to last line %d ' % max_line) last = max_line bplist = self.core.bpmgr.bplist opts = { 'reload_on_change' : self.settings['reload'], 'output' : self.settings['highlight'], 'strip_nl' : False, } if 'style' in self.settings: opts['style'] = self.settings['style'] try: for lineno in range(first, last+1): line = pyficache.getline(filename, lineno, opts) if line is None: line = linecache.getline(filename, lineno, self.proc.frame.f_globals) pass if line is None: self.msg('[EOF]') break else: line = line.rstrip('\n') s = self.proc._saferepr(lineno).rjust(3) if len(s) < 5: s += ' ' if (canonic_filename, lineno,) in list(bplist.keys()): bp = bplist[(canonic_filename, lineno,)][0] a_pad = '%02d' % bp.number s += bp.icon_char() else: s += ' ' a_pad = ' ' pass if curframe and lineno == inspect.getlineno(curframe): s += '->' if 'plain' != self.settings['highlight']: s = colorize('bold', s) else: s += a_pad pass self.msg(s + '\t' + line) self.proc.list_lineno = lineno pass pass except KeyboardInterrupt: pass return False
def print_location(proc_obj): """Show where we are. GUI's and front-end interfaces often use this to update displays. So it is helpful to make sure we give at least some place that's located in a file. """ i_stack = proc_obj.curindex if i_stack is None or proc_obj.stack is None: return False core_obj = proc_obj.core dbgr_obj = proc_obj.debugger intf_obj = dbgr_obj.intf[-1] # Evaluation routines like "exec" don't show useful location # info. In these cases, we will use the position before that in # the stack. Hence the looping below which in practices loops # once and sometimes twice. remapped_file = None while i_stack >= 0: frame_lineno = proc_obj.stack[i_stack] i_stack -= 1 frame, lineno = frame_lineno # # Next check to see that local variable breadcrumb exists and # # has the magic dynamic value. # # If so, it's us and we don't normally show this.a # if 'breadcrumb' in frame.f_locals: # if self.run == frame.f_locals['breadcrumb']: # break filename = Mstack.frame2file(core_obj, frame) if '<string>' == filename and dbgr_obj.eval_string: remapped_file = filename filename = pyficache.unmap_file(filename) if '<string>' == filename: fd = tempfile.NamedTemporaryFile(suffix='.py', prefix='eval_string', delete=False) fd.write(dbgr_obj.eval_string) fd.close() pyficache.remap_file(fd.name, '<string>') filename = fd.name pass pass fn_name = frame.f_code.co_name print_source_location_info(intf_obj.msg, filename, lineno, fn_name, remapped_file = remapped_file) # proc_obj.curframe.f_lasti) opts = { 'reload_on_change' : proc_obj.settings('reload'), 'output' : proc_obj.settings('highlight') } line = pyficache.getline(filename, lineno, opts) if not line: if sys.version_info[1] <= 4: # Python 2.4 and before doesn't have 3-arg getline line = linecache.getline(filename, lineno) else: line = linecache.getline(filename, lineno, proc_obj.curframe.f_globals) pass pass if line and len(line.strip()) != 0: if proc_obj.event: print_source_line(intf_obj.msg, lineno, line, proc_obj.event2short[proc_obj.event]) pass if '<string>' != filename: break pass if proc_obj.event in ['return', 'exception']: val = proc_obj.event_arg intf_obj.msg('R=> %s' % proc_obj._saferepr(val)) pass return True
def run(self, args): """Get file information""" if len(args) == 0: if not self.proc.curframe: self.errmsg("No frame - no default file.") return False filename = self.proc.curframe.f_code.co_filename else: filename = args[0] pass m = filename + ' is' filename_cache = self.core.filename_cache if filename in filename_cache: m += " cached in debugger" if filename_cache[filename] != filename: m += ' as:' m = Mmisc.wrapped_lines(m, filename_cache[filename] + '.', self.settings['width']) else: m += '.' pass self.msg(m) else: matches = [ file for file in self.file_list() if file.endswith(filename) ] if (len(matches) > 1): self.msg("Multiple files found ending filename string:") for match_file in matches: self.msg("\t%s" % match_file) pass elif len(matches) == 1: canonic_name = pyficache.unmap_file(matches[0]) m += " matched debugger cache file:\n " + canonic_name self.msg(m) else: self.msg(m + ' not cached in debugger.') pass canonic_name = self.core.canonic(filename) self.msg( Mmisc.wrapped_lines('Canonic name:', canonic_name, self.settings['width'])) for name in (canonic_name, filename): if name in sys.modules: for key in [ k for k, v in list(sys.modules.items()) if name == v ]: self.msg("module: %s", key) pass pass pass for arg in args[1:]: processed_arg = False if arg in ['all', 'size']: if pyficache.size(canonic_name): self.msg("File has %d lines." % pyficache.size(canonic_name)) pass processed_arg = True pass if arg in ['all', 'sha1']: self.msg("SHA1 is %s." % pyficache.sha1(canonic_name)) processed_arg = True pass if arg in ['all', 'brkpts']: lines = pyficache.trace_line_numbers(canonic_name) if lines: self.section("Possible breakpoint line numbers:") fmt_lines = columnize.columnize(lines, ljust=False, arrange_vertical=False, lineprefix=' ') self.msg(fmt_lines) pass processed_arg = True pass if not processed_arg: self.errmsg("Don't understand sub-option %s." % arg) pass pass return
def print_location(proc_obj): """Show where we are. GUI's and front-end interfaces often use this to update displays. So it is helpful to make sure we give at least some place that's located in a file. """ i_stack = proc_obj.curindex if i_stack is None or proc_obj.stack is None: return False core_obj = proc_obj.core dbgr_obj = proc_obj.debugger intf_obj = dbgr_obj.intf[-1] # Evaluation routines like "exec" don't show useful location # info. In these cases, we will use the position before that in # the stack. Hence the looping below which in practices loops # once and sometimes twice. remapped_file = None source_text = None while i_stack >= 0: frame_lineno = proc_obj.stack[i_stack] i_stack -= 1 frame, lineno = frame_lineno # # Next check to see that local variable breadcrumb exists and # # has the magic dynamic value. # # If so, it's us and we don't normally show this.a # if 'breadcrumb' in frame.f_locals: # if self.run == frame.f_locals['breadcrumb']: # break filename = Mstack.frame2file(core_obj, frame, canonic=False) if '<string>' == filename and dbgr_obj.eval_string: remapped_file = filename filename = pyficache.unmap_file(filename) if '<string>' == filename: remapped = cmdfns.source_tempfile_remap( 'eval_string', dbgr_obj.eval_string) pyficache.remap_file(filename, remapped) filename = remapped lineno = pyficache.unmap_file_line(filename, lineno) pass pass elif '<string>' == filename: source_text = deparse_fn(frame.f_code) filename = "<string: '%s'>" % source_text pass else: m = re.search('^<frozen (.*)>', filename) if m and m.group(1) in pyficache.file2file_remap: remapped_file = pyficache.file2file_remap[m.group(1)] pass elif filename in pyficache.file2file_remap: remapped_file = pyficache.unmap_file(filename) # FIXME: a remapped_file shouldn't be the same as its unmapped version if remapped_file == filename: remapped_file = None pass pass elif m and m.group(1) in sys.modules: remapped_file = m.group(1) pyficache.remap_file(filename, remapped_file) pass opts = { 'reload_on_change': proc_obj.settings('reload'), 'output': proc_obj.settings('highlight') } if 'style' in proc_obj.debugger.settings: opts['style'] = proc_obj.settings('style') pyficache.update_cache(filename) line = pyficache.getline(filename, lineno, opts) if not line: if (not source_text and filename.startswith("<string: ") and proc_obj.curframe.f_code): # Deparse the code object into a temp file and remap the line from code # into the corresponding line of the tempfile co = proc_obj.curframe.f_code temp_filename, name_for_code = deparse_and_cache( co, proc_obj.errmsg) lineno = 1 # _, lineno = pyficache.unmap_file_line(temp_filename, lineno, True) if temp_filename: filename = temp_filename pass else: # FIXME: if source_text: lines = source_text.split("\n") temp_name = 'string-' else: # try with good ol linecache and consider fixing pyficache lines = linecache.getlines(filename) temp_name = filename if lines: # FIXME: DRY code with version in cmdproc.py print_location prefix = os.path.basename(temp_name).split('.')[0] fd = tempfile.NamedTemporaryFile(suffix='.py', prefix=prefix, delete=False) with fd: fd.write(''.join(lines)) remapped_file = fd.name pyficache.remap_file(remapped_file, filename) fd.close() pass line = linecache.getline(filename, lineno, proc_obj.curframe.f_globals) if not line: m = re.search('^<frozen (.*)>', filename) if m and m.group(1): remapped_file = m.group(1) try_module = sys.modules.get(remapped_file) if (try_module and inspect.ismodule(try_module) and hasattr(try_module, '__file__')): remapped_file = sys.modules[remapped_file].__file__ pyficache.remap_file(filename, remapped_file) line = linecache.getline(remapped_file, lineno, proc_obj.curframe.f_globals) else: remapped_file = m.group(1) code = proc_obj.curframe.f_code filename, line = cmdfns.deparse_getline( code, remapped_file, lineno, opts) pass pass try: match, reason = Mstack.check_path_with_frame(frame, filename) if not match: if filename not in warned_file_mismatches: proc_obj.errmsg(reason) warned_file_mismatches.add(filename) except: pass fn_name = frame.f_code.co_name last_i = frame.f_lasti print_source_location_info(intf_obj.msg, filename, lineno, fn_name, remapped_file=remapped_file, f_lasti=last_i) if line and len(line.strip()) != 0: if proc_obj.event: print_source_line(intf_obj.msg, lineno, line, proc_obj.event2short[proc_obj.event]) pass if '<string>' != filename: break pass if proc_obj.event in ['return', 'exception']: val = proc_obj.event_arg intf_obj.msg('R=> %s' % proc_obj._saferepr(val)) pass return True
def run(self, args): proc = self.proc dbg_obj = self.core.debugger listsize = dbg_obj.settings['listsize'] filename, first, last = parse_list_cmd(proc, args, listsize) curframe = proc.curframe if filename is None: return # Sometimes such as due to decompilation we might not really # have an idea based on the listing where we really are. # Setting "show_marks" to false will disable marking breakpoint # and current line numbers. show_marks = True filename = pyficache.unmap_file(pyficache.pyc2py(filename)) if filename == "<string>" and proc.curframe.f_code: # Deparse the code object into a temp file and remap the line from code # into the corresponding line of the tempfile co = proc.curframe.f_code temp_filename, name_for_code = deparse_and_cache(co, proc.errmsg) if temp_filename: filename = temp_filename show_marks = False pass # We now have range information. Do the listing. max_line = pyficache.size(filename) if max_line is None: self.errmsg('No file %s found; using "deparse" command instead to show source' % filename) proc.commands['deparse'].run(['deparse']) return canonic_filename = os.path.realpath(os.path.normcase(filename)) if first > max_line: self.errmsg('Bad start line %d - file "%s" has only %d lines' % (first, filename, max_line)) return if last > max_line: self.msg('End position changed to last line %d ' % max_line) last = max_line bplist = self.core.bpmgr.bplist opts = { 'reload_on_change' : self.settings['reload'], 'output' : self.settings['highlight'], 'strip_nl' : False, } if 'style' in self.settings: opts['style'] = self.settings['style'] if first <= 0: first = 1 try: for lineno in range(first, last+1): line = pyficache.getline(filename, lineno, opts) if line is None: line = linecache.getline(filename, lineno, proc.frame.f_globals) pass if line is None: self.msg('[EOF]') break else: line = line.rstrip('\n') s = proc._saferepr(lineno).rjust(3) if len(s) < 5: s += ' ' if (show_marks and (canonic_filename, lineno,) in list(bplist.keys())): bp = bplist[(canonic_filename, lineno,)][0] a_pad = '%02d' % bp.number s += bp.icon_char() else: s += ' ' a_pad = ' ' pass if (curframe and lineno == inspect.getlineno(curframe) and show_marks): s += '->' if 'plain' != self.settings['highlight']: s = colorize('bold', s) else: s += a_pad pass self.msg(s + '\t' + line) proc.list_lineno = lineno pass pass pass except KeyboardInterrupt: pass return False
def run(self, args): proc = self.proc dbg_obj = self.core.debugger listsize = dbg_obj.settings['listsize'] filename, first, last = parse_list_cmd(proc, args, listsize) curframe = proc.curframe if filename is None: return filename = pyficache.unmap_file(pyficache.pyc2py(filename)) # We now have range information. Do the listing. max_line = pyficache.size(filename) if max_line is None: self.errmsg( 'No file %s found; using "deparse" command instead to show source' % filename) proc.commands['deparse'].run(['deparse']) return canonic_filename = os.path.realpath(os.path.normcase(filename)) if first > max_line: self.errmsg('Bad start line %d - file "%s" has only %d lines' % (first, filename, max_line)) return if last > max_line: self.msg('End position changed to last line %d ' % max_line) last = max_line bplist = self.core.bpmgr.bplist opts = { 'reload_on_change': self.settings['reload'], 'output': self.settings['highlight'], 'strip_nl': False, } if 'style' in self.settings: opts['style'] = self.settings['style'] if first <= 0: first = 1 try: for lineno in range(first, last + 1): line = pyficache.getline(filename, lineno, opts) if line is None: line = linecache.getline(filename, lineno, proc.frame.f_globals) pass if line is None: self.msg('[EOF]') break else: line = line.rstrip('\n') s = proc._saferepr(lineno).rjust(3) if len(s) < 5: s += ' ' if ( canonic_filename, lineno, ) in list(bplist.keys()): bp = bplist[( canonic_filename, lineno, )][0] a_pad = '%02d' % bp.number s += bp.icon_char() else: s += ' ' a_pad = ' ' pass if curframe and lineno == inspect.getlineno(curframe): s += '->' if 'plain' != self.settings['highlight']: s = colorize('bold', s) else: s += a_pad pass self.msg(s + '\t' + line) proc.list_lineno = lineno pass pass pass except KeyboardInterrupt: pass return False
def print_location(proc_obj): """Show where we are. GUI's and front-end interfaces often use this to update displays. So it is helpful to make sure we give at least some place that's located in a file. """ i_stack = proc_obj.curindex if i_stack is None or proc_obj.stack is None: return False core_obj = proc_obj.core dbgr_obj = proc_obj.debugger intf_obj = dbgr_obj.intf[-1] # Evaluation routines like "exec" don't show useful location # info. In these cases, we will use the position before that in # the stack. Hence the looping below which in practices loops # once and sometimes twice. remapped_file = None while i_stack >= 0: frame_lineno = proc_obj.stack[i_stack] i_stack -= 1 frame, lineno = frame_lineno # # Next check to see that local variable breadcrumb exists and # # has the magic dynamic value. # # If so, it's us and we don't normally show this.a # if 'breadcrumb' in frame.f_locals: # if self.run == frame.f_locals['breadcrumb']: # break filename = Mstack.frame2file(core_obj, frame, canonic=False) if '<string>' == filename and dbgr_obj.eval_string: remapped_file = filename filename = pyficache.unmap_file(filename) if '<string>' == filename: fd = tempfile.NamedTemporaryFile(suffix='.py', prefix='eval_string', delete=False) with fd: fd.write(dbgr_obj.eval_string) fd.close() pass pyficache.remap_file(fd.name, '<string>') filename = fd.name pass pass else: if filename in pyficache.file2file_remap: remapped_file = pyficache.unmap_file(filename) # FIXME: a remapped_file shouldn't be the same as its unmapped version if remapped_file == filename: remapped_file = None pass pass pass opts = { 'reload_on_change': proc_obj.settings('reload'), 'output': proc_obj.settings('highlight') } if 'style' in proc_obj.debugger.settings: opts['style'] = proc_obj.settings('style') pyficache.update_cache(filename) line = pyficache.getline(filename, lineno, opts) if not line: # FIXME: # try with good ol linecache and consider fixing pyficache lines = linecache.getlines(filename) if lines: # FIXME: DRY code with version in cmdproc.py print_location prefix = os.path.basename(filename).split('.')[0] fd = tempfile.NamedTemporaryFile(suffix='.py', prefix=prefix, delete=False) with fd: fd.write(''.join(lines)) remapped_file = fd.name pyficache.remap_file(remapped_file, filename) fd.close() pass line = linecache.getline(filename, lineno, proc_obj.curframe.f_globals) pass fn_name = frame.f_code.co_name last_i = frame.f_lasti print_source_location_info(intf_obj.msg, filename, lineno, fn_name, remapped_file=remapped_file, f_lasti=last_i) if line and len(line.strip()) != 0: if proc_obj.event: print_source_line(intf_obj.msg, lineno, line, proc_obj.event2short[proc_obj.event]) pass if '<string>' != filename: break pass if proc_obj.event in ['return', 'exception']: val = proc_obj.event_arg intf_obj.msg('R=> %s' % proc_obj._saferepr(val)) pass return True
def print_location(proc_obj): """Show where we are. GUI's and front-end interfaces often use this to update displays. So it is helpful to make sure we give at least some place that's located in a file. """ i_stack = proc_obj.curindex if i_stack is None or proc_obj.stack is None: return False core_obj = proc_obj.core dbgr_obj = proc_obj.debugger intf_obj = dbgr_obj.intf[-1] # Evaluation routines like "exec" don't show useful location # info. In these cases, we will use the position before that in # the stack. Hence the looping below which in practices loops # once and sometimes twice. remapped_file = None while i_stack >= 0: frame_lineno = proc_obj.stack[i_stack] i_stack -= 1 frame, lineno = frame_lineno # # Next check to see that local variable breadcrumb exists and # # has the magic dynamic value. # # If so, it's us and we don't normally show this.a # if 'breadcrumb' in frame.f_locals: # if self.run == frame.f_locals['breadcrumb']: # break filename = Mstack.frame2file(core_obj, frame) if '<string>' == filename and dbgr_obj.eval_string: remapped_file = filename filename = pyficache.unmap_file(filename) if '<string>' == filename: fd = tempfile.NamedTemporaryFile(suffix='.py', prefix='eval_string', delete=False) fd.write(dbgr_obj.eval_string) fd.close() pyficache.remap_file(fd.name, '<string>') filename = fd.name pass pass fn_name = frame.f_code.co_name print_source_location_info(intf_obj.msg, filename, lineno, fn_name, remapped_file=remapped_file) # proc_obj.curframe.f_lasti) opts = { 'reload_on_change': proc_obj.settings('reload'), 'output': proc_obj.settings('highlight') } line = pyficache.getline(filename, lineno, opts) if not line: if sys.version_info[1] <= 4: # Python 2.4 and before doesn't have 3-arg getline line = linecache.getline(filename, lineno) else: line = linecache.getline(filename, lineno, proc_obj.curframe.f_globals) pass pass if line and len(line.strip()) != 0: if proc_obj.event: print_source_line(intf_obj.msg, lineno, line, proc_obj.event2short[proc_obj.event]) pass if '<string>' != filename: break pass if proc_obj.event in ['return', 'exception']: val = proc_obj.event_arg intf_obj.msg('R=> %s' % proc_obj._saferepr(val)) pass return True