Author: Armin Rigo <[email protected]>
Branch: reverse-debugger
Changeset: r85443:2564a81ce049
Date: 2016-06-29 10:12 +0200
http://bitbucket.org/pypy/pypy/changeset/2564a81ce049/
Log: in-progress
diff --git a/pypy/interpreter/reverse_debugging.py
b/pypy/interpreter/reverse_debugging.py
--- a/pypy/interpreter/reverse_debugging.py
+++ b/pypy/interpreter/reverse_debugging.py
@@ -1,6 +1,8 @@
import sys
from rpython.rlib import revdb
from rpython.rlib.debug import make_sure_not_resized
+from rpython.rlib.objectmodel import specialize
+from rpython.rtyper.annlowlevel import cast_gcref_to_instance
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter import gateway, typedef
@@ -8,40 +10,63 @@
class DBState:
extend_syntax_with_dollar_num = False
+ breakpoint_funcnames = []
+ printed_objects = {}
metavars = []
+ watch_progs = []
+ watch_futures = {}
dbstate = DBState()
def setup_revdb(space):
+ """Called at run-time, before the space is set up.
+
+ The various register_debug_command() lines attach functions
+ to some commands that 'revdb.py' can call, if we are running
+ in replay mode.
+ """
assert space.config.translation.reverse_debugger
dbstate.space = space
- #make_sure_not_resized(dbstate.breakpoint_funcnames)
- #make_sure_not_resized(dbstate.watch_progs)
+ dbstate.w_future = space.w_Ellipsis # a random prebuilt object
+
+ make_sure_not_resized(dbstate.breakpoint_funcnames)
+ make_sure_not_resized(dbstate.watch_progs)
make_sure_not_resized(dbstate.metavars)
+
revdb.register_debug_command(revdb.CMD_PRINT, lambda_print)
revdb.register_debug_command(revdb.CMD_BACKTRACE, lambda_backtrace)
#revdb.register_debug_command(revdb.CMD_LOCALS, lambda_locals)
#revdb.register_debug_command(revdb.CMD_BREAKPOINTS, lambda_breakpoints)
#revdb.register_debug_command(revdb.CMD_MOREINFO, lambda_moreinfo)
- #revdb.register_debug_command("ALLOCATING", lambda_allocating)
- #revdb.register_debug_command(revdb.CMD_ATTACHID, lambda_attachid)
+ revdb.register_debug_command("ALLOCATING", lambda_allocating)
+ revdb.register_debug_command(revdb.CMD_ATTACHID, lambda_attachid)
#revdb.register_debug_command(revdb.CMD_CHECKWATCH, lambda_checkwatch)
#revdb.register_debug_command(revdb.CMD_WATCHVALUES, lambda_watchvalues)
-def load_metavar(oparg):
+
+def load_metavar(index):
+ assert index >= 0
space = dbstate.space
metavars = dbstate.metavars
- w_var = metavars[oparg] if oparg < len(metavars) else None
+ w_var = metavars[index] if index < len(metavars) else None
if w_var is None:
raise oefmt(space.w_NameError, "no constant object '$%d'",
- oparg)
- if w_var is space.w_Ellipsis:
+ index)
+ if w_var is dbstate.w_future:
raise oefmt(space.w_RuntimeError,
"'$%d' refers to an object created later in time",
- oparg)
+ index)
return w_var
+def set_metavar(index, w_obj):
+ assert index >= 0
+ if index >= len(dbstate.metavars):
+ missing = index + 1 - len(dbstate.metavars)
+ dbstate.metavars = dbstate.metavars + [None] * missing
+ dbstate.metavars[index] = w_obj
+
+
def fetch_cur_frame():
ec = dbstate.space.getexecutioncontext()
frame = ec.topframeref()
@@ -76,6 +101,25 @@
softspace = typedef.interp_attrproperty("softspace", W_RevDBOutput),
)
+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'.
+ """
+ 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.wrap('_'), w_obj)
+ revdb.send_output(space.str_w(space.repr(w_obj)))
+ revdb.send_output("\n")
+
[email protected]()
+def get_revdb_displayhook(space):
+ return space.wrap(gateway.interp2app(revdb_displayhook))
+
def command_print(cmd, expression):
frame = fetch_cur_frame()
@@ -85,8 +129,10 @@
try:
code = compile(expression, 'exec')
w_revdb_output = space.wrap(W_RevDBOutput(space))
+ w_displayhook = get_revdb_displayhook(space)
space.sys.setdictvalue(space, 'stdout', w_revdb_output)
space.sys.setdictvalue(space, 'stderr', w_revdb_output)
+ space.sys.setdictvalue(space, 'displayhook', w_displayhook)
try:
code.exec_code(space,
frame.get_w_globals(),
@@ -141,3 +187,29 @@
while len(frames) > 0:
show_frame(frames.pop(), indent=' ')
lambda_backtrace = lambda: command_backtrace
+
+
+def command_allocating(uid, gcref):
+ w_obj = cast_gcref_to_instance(W_Root, gcref)
+ dbstate.printed_objects[uid] = w_obj
+ try:
+ index_metavar = dbstate.watch_futures.pop(uid)
+ except KeyError:
+ pass
+ else:
+ set_metavar(index_metavar, w_obj)
+lambda_allocating = lambda: command_allocating
+
+
+def command_attachid(cmd, extra):
+ space = dbstate.space
+ index_metavar = cmd.c_arg1
+ uid = cmd.c_arg2
+ try:
+ w_obj = dbstate.printed_objects[uid]
+ except KeyError:
+ # uid not found, probably a future object
+ dbstate.watch_futures[uid] = index_metavar
+ w_obj = dbstate.w_future
+ set_metavar(index_metavar, w_obj)
+lambda_attachid = lambda: command_attachid
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit