def command_locals(cmd, extra): frame = fetch_cur_frame() if frame is None: return space = dbstate.space with non_standard_code: try: prepare_print_environment(space) space.appexec([space.sys, frame.getdictscope()], """(sys, locals): lst = sorted(locals.keys()) print('Locals:') for key in lst: try: print(' %s =' % key, end=' ', flush=True) s = '%r' % locals[key] if len(s) > 140: s = s[:100] + '...' + s[-30:] print(s) except: exc, val, tb = sys.exc_info() print('!<%s: %r>' % (exc, val)) """) except OperationError as e: revdb.send_print(e.errorstr(space, use_repr=True))
def display_function_part(frame, max_lines_before, max_lines_after): if frame is None: return code = frame.getcode() if code.co_filename.startswith('<builtin>'): return first_lineno = code.co_firstlineno current_lineno = frame.get_last_lineno() final_lineno = get_final_lineno(code) # ellipsis_after = False if first_lineno < current_lineno - max_lines_before - 1: first_lineno = current_lineno - max_lines_before revdb.send_print("...") if final_lineno > current_lineno + max_lines_after + 1: final_lineno = current_lineno + max_lines_after ellipsis_after = True # for i in range(first_lineno, final_lineno + 1): if i == current_lineno: if revdb.current_place() == -2: # <= this is the arg to stop_point() prompt = "<< " # return elif revdb.current_place() == -1: prompt = "!! " # exceptional return else: prompt = " > " # plain line revdb.send_output(prompt) else: revdb.send_output(" ") revdb.send_linecache(code.co_filename, i, strip=False) # if ellipsis_after: revdb.send_print("...")
def fetch_cur_frame(silent=False): ec = dbstate.space.threadlocals.get_ec() if ec is None: frame = None else: frame = ec.topframeref() if frame is None and not silent: revdb.send_print("No stack.") return frame
def revdb_displayhook(space, w_obj): """Modified sys.displayhook() that also outputs '$NUM = ', for non-prebuilt objects. Such objects are then recorded in 'printed_objects'. """ assert not dbstate.standard_code if space.is_w(w_obj, space.w_None): return uid = revdb.get_unique_id(w_obj) if uid > 0: dbstate.printed_objects[uid] = w_obj revdb.send_nextnid(uid) # outputs '$NUM = ' space.setitem(space.builtin.w_dict, space.newtext('_'), w_obj) # do repr() after setitem: if w_obj was produced successfully, # but its repr crashes because it tries to do I/O, then we already # have it recorded in '_' and in '$NUM ='. w_repr = space.repr(w_obj) if space.isinstance_w(w_repr, space.w_unicode): w_repr = space.call_method(w_repr, 'encode', space.newtext('utf-8')) # safe? revdb.send_print(space.bytes_w(w_repr))
def command_backtrace(cmd, extra): frame = fetch_cur_frame(silent=True) if cmd.c_arg1 == 0: if frame is not None: revdb.send_print("%s:" % ( file_and_lineno(frame, frame.get_last_lineno()),)) display_function_part(frame, max_lines_before=8, max_lines_after=5) elif cmd.c_arg1 == 2: display_function_part(frame, max_lines_before=1000,max_lines_after=1000) else: revdb.send_print("Current call stack (most recent call last):") if frame is None: revdb.send_print(" (empty)") frames = [] while frame is not None: frames.append(frame) if len(frames) == 200: revdb.send_print(" ...") break frame = frame.get_f_back() while len(frames) > 0: show_frame(frames.pop(), indent=' ')
def command_print(cmd, expression): frame = fetch_cur_frame() if frame is None: return space = dbstate.space with non_standard_code: try: prepare_print_environment(space) code = compile(expression, 'single') try: code.exec_code(space, frame.get_w_globals(), frame.getdictscope()) except OperationError as operationerr: # can't use sys.excepthook: it will likely try to do 'import # traceback', which might not be doable without using I/O tb = operationerr.get_traceback() if tb is not None: revdb.send_print("Traceback (most recent call last):") while tb is not None: if not isinstance(tb, pytraceback.PyTraceback): revdb.send_print(" ??? %s" % tb) break show_frame(tb.frame, tb.get_lineno(), indent=' ') tb = tb.next revdb.send_print(operationerr.errorstr(space)) # set the sys.last_xxx attributes w_type = operationerr.w_type w_value = operationerr.get_w_value(space) w_tb = operationerr.get_traceback() w_dict = space.sys.w_dict space.setitem(w_dict, space.newtext('last_type'), w_type) space.setitem(w_dict, space.newtext('last_value'), w_value) space.setitem(w_dict, space.newtext('last_traceback'), w_tb) except OperationError as e: revdb.send_print(e.errorstr(space, use_repr=True))
def add_breakpoint(name, i): # if it is empty, complain if not name: revdb.send_print("Empty breakpoint name") revdb.send_change_breakpoint(i) return # if it is surrounded by < >, it is the name of a code object if name.startswith('<') and name.endswith('>'): add_breakpoint_funcname(name, i) return # if it has no ':', it can be a valid identifier (which we # register as a function name), or a lineno original_name = name j = name.rfind(':') if j < 0: try: lineno = int(name) except ValueError: if name.endswith('()'): n = len(name) - 2 assert n >= 0 name = name[:n] if not valid_identifier(name): revdb.send_print( 'Note: "%s()" doesn''t look like a function name. ' 'Setting breakpoint anyway' % name) add_breakpoint_funcname(name, i) name += '()' if name != original_name: revdb.send_change_breakpoint(i, name) return # "number" does the same as ":number" filename = '' else: # if it has a ':', it must end in ':lineno' try: lineno = int(name[j+1:]) except ValueError: revdb.send_print('expected a line number after colon') revdb.send_change_breakpoint(i) return filename = name[:j] # the text before must be a pathname, possibly a relative one, # or be escaped by < >. if it isn't, make it absolute and normalized # and warn if it doesn't end in '.py'. if filename == '': frame = fetch_cur_frame() if frame is None: revdb.send_change_breakpoint(i) return filename = frame.getcode().co_filename elif filename.startswith('<') and filename.endswith('>'): pass # use unmodified elif not filename.lower().endswith('.py'): # use unmodified, but warn revdb.send_print( 'Note: "%s" doesn''t look like a Python filename. ' 'Setting breakpoint anyway' % (filename,)) add_breakpoint_fileline(filename, lineno, i) name = '%s:%d' % (filename, lineno) if name != original_name: revdb.send_change_breakpoint(i, name)