Author: Armin Rigo <[email protected]>
Branch: reverse-debugger
Changeset: r85212:4ab10ccbb305
Date: 2016-06-17 16:06 +0200
http://bitbucket.org/pypy/pypy/changeset/4ab10ccbb305/
Log: Update track_object() to allow tracking any number of objects
diff --git a/rpython/rlib/revdb.py b/rpython/rlib/revdb.py
--- a/rpython/rlib/revdb.py
+++ b/rpython/rlib/revdb.py
@@ -91,29 +91,20 @@
"""
return llop.revdb_get_unique_id(lltype.SignedLongLong, x)
-def track_object(unique_id):
+def track_object(unique_id, callback):
"""Track the creation of the object given by its unique_id, which must
be in the future (i.e. >= currently_created_objects()). Call this
before go_forward(). If go_forward() goes over the creation of this
- object, then afterwards, get_tracked_object() returns the object.
- Going forward is also interrupted at the following stop point.
- Object tracking is lost by jump_in_time(), like everything else.
+ object, then 'callback(gcref)' is called. Careful in callback(),
+ gcref is not fully initialized and should not be immediately read from,
+ only stored for later. The purpose of callback() is to possibly
+ call track_object() again to track the next object, and/or to call
+ breakpoint(). Note: object tracking remains activated until one of:
+ (1) we reach the creation time in go_forward(); (2) we call
+ track_object() to track a different object; (3) we call jump_in_time().
"""
- llop.revdb_track_object(lltype.Void, unique_id)
-
[email protected](0)
-def get_tracked_object(Class=llmemory.GCREF): # or an RPython class
- """Get the tracked object if it was created during the last go_forward().
- Otherwise, returns None. (Note: this API is minimal: to get an
- object from its unique id, you need first to search backward for a
- time where currently_created_objects() is lower than the unique_id,
- then use track_object() and go_forward() to come back. You can't
- really track several objects, only one.)
- """
- x = llop.revdb_get_tracked_object(llmemory.GCREF)
- if Class is llmemory.GCREF:
- return x
- return cast_gcref_to_instance(Class, x)
+ ll_callback = llhelper(_CALLBACK_GCREF_FNPTR, callback)
+ llop.revdb_track_object(lltype.Void, unique_id, ll_callback)
# ____________________________________________________________
@@ -132,6 +123,8 @@
return callback_wrapper
_CALLBACK_ARG_FNPTR = lltype.Ptr(lltype.FuncType([lltype.Ptr(rstr.STR)],
lltype.Void))
+_CALLBACK_GCREF_FNPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF],
+ lltype.Void))
class RegisterDebugCommand(ExtRegistryEntry):
diff --git a/rpython/rtyper/lltypesystem/lloperation.py
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -573,7 +573,6 @@
'revdb_identityhash': LLOp(),
'revdb_get_unique_id': LLOp(sideeffects=False),
'revdb_track_object': LLOp(),
- 'revdb_get_tracked_object': LLOp(sideeffects=False),
}
# ***** Run test_lloperation after changes. *****
diff --git a/rpython/translator/revdb/src-revdb/revdb.c
b/rpython/translator/revdb/src-revdb/revdb.c
--- a/rpython/translator/revdb/src-revdb/revdb.c
+++ b/rpython/translator/revdb/src-revdb/revdb.c
@@ -900,23 +900,22 @@
}
}
-static void *tracked_object;
+static void (*unique_id_callback)(void *);
RPY_EXTERN
uint64_t rpy_reverse_db_unique_id_break(void *new_object)
{
rpy_revdb.unique_id_break = 0;
- tracked_object = new_object;
- rpy_revdb.stop_point_break = rpy_revdb.stop_point_seen + 1;
+ unique_id_callback(new_object);
return rpy_revdb.unique_id_seen;
}
RPY_EXTERN
-void rpy_reverse_db_track_object(long long unique_id)
+void rpy_reverse_db_track_object(long long unique_id, void callback(void *))
{
if (stopped_uid <= 0) {
fprintf(stderr, "stopped_uid should not be <= 0\n");
- exit(1);
+ return;
}
if (unique_id <= 0) {
printf("cannot track a prebuilt or debugger-created object\n");
@@ -926,15 +925,10 @@
printf("cannot track the creation of an object already created\n");
return;
}
+ assert(callback != NULL);
+ unique_id_callback = callback;
rpy_revdb.unique_id_break = unique_id;
- tracked_object = NULL;
}
-RPY_EXTERN
-void *rpy_reverse_db_get_tracked_object(void)
-{
- return tracked_object;
-}
-
/* ------------------------------------------------------------ */
diff --git a/rpython/translator/revdb/src-revdb/revdb_include.h
b/rpython/translator/revdb/src-revdb/revdb_include.h
--- a/rpython/translator/revdb/src-revdb/revdb_include.h
+++ b/rpython/translator/revdb/src-revdb/revdb_include.h
@@ -96,11 +96,8 @@
#define OP_REVDB_GET_UNIQUE_ID(x, r) \
r = ((struct pypy_header0 *)x)->h_uid
-#define OP_REVDB_TRACK_OBJECT(uid, r) \
- rpy_reverse_db_track_object(uid)
-
-#define OP_REVDB_GET_TRACKED_OBJECT(r) \
- r = rpy_reverse_db_get_tracked_object()
+#define OP_REVDB_TRACK_OBJECT(uid, callback, r) \
+ rpy_reverse_db_track_object(uid, callback)
RPY_EXTERN void rpy_reverse_db_flush(void);
RPY_EXTERN char *rpy_reverse_db_fetch(int expected_size,
@@ -113,8 +110,8 @@
RPyString *arg);
RPY_EXTERN long long rpy_reverse_db_get_value(char value_id);
RPY_EXTERN uint64_t rpy_reverse_db_unique_id_break(void *new_object);
-RPY_EXTERN void rpy_reverse_db_track_object(long long unique_id);
-RPY_EXTERN void *rpy_reverse_db_get_tracked_object(void);
+RPY_EXTERN void rpy_reverse_db_track_object(long long unique_id,
+ void callback(void *));
/* ------------------------------------------------------------ */
diff --git a/rpython/translator/revdb/test/test_basic.py
b/rpython/translator/revdb/test/test_basic.py
--- a/rpython/translator/revdb/test/test_basic.py
+++ b/rpython/translator/revdb/test/test_basic.py
@@ -6,6 +6,8 @@
from rpython.rlib.rarithmetic import LONG_BIT
from rpython.rlib import objectmodel, revdb
from rpython.rlib.rarithmetic import intmask
+from rpython.rtyper.annlowlevel import cast_gcref_to_instance
+from rpython.rtyper.lltypesystem import lltype, llmemory
"""
These tests require pexpect (UNIX-only).
http://pexpect.sourceforge.net/
@@ -314,6 +316,10 @@
def _nothing(arg):
pass
#
+ def callback_track_obj(gcref):
+ revdb.send_output("callback_track_obj\n")
+ dbstate.gcref = gcref
+ #
def blip(cmdline):
revdb.send_output('<<<' + cmdline + '>>>\n')
if cmdline == 'oops':
@@ -345,11 +351,14 @@
revdb.currently_created_objects()))
if cmdline.startswith('track-object '):
uid = int(cmdline[len('track-object '):])
- revdb.track_object(uid)
+ dbstate.gcref = lltype.nullptr(llmemory.GCREF.TO)
+ revdb.track_object(uid, callback_track_obj)
if cmdline == 'get-tracked-object':
- obj = revdb.get_tracked_object(Stuff)
- revdb.send_output('None\n' if obj is None else
- ('obj.x=%d\n' % obj.x))
+ if dbstate.gcref:
+ revdb.send_output('got obj.x=%d\n' % (
+ cast_gcref_to_instance(Stuff, dbstate.gcref).x,))
+ else:
+ revdb.send_output('none\n')
if cmdline == 'first-created-uid':
revdb.send_output('first-created-uid=%d\n' % (
revdb.first_created_object_uid(),))
@@ -503,32 +512,24 @@
child.expectx('<<<track-object %d>>>\r\n' % object_id_3rd +
'blipped\r\n'
'(1)$ ')
- prev_time = 1
- for i in [1, 2, 3]:
+ for i in [1, 2]:
child.sendline('r get-tracked-object')
child.expectx('<<<get-tracked-object>>>\r\n'
- 'None\r\n'
+ 'none\r\n'
'blipped\r\n'
- '(%d)$ ' % prev_time)
- child.sendline('__forward %d' % (i - prev_time))
- child.expectx('(%d)$ ' % i)
- prev_time = i
- child.sendline('r print-id')
- child.expect(re.escape('<<<print-id>>>\r\n')
- + r'obj.x=%d (\d+) (\d+)' % (1000 + prev_time - 1)
- + re.escape('\r\n'
- 'blipped\r\n'
- '(%d)$ ' % prev_time))
+ '(%d)$ ' % i)
+ child.sendline('__forward 1')
+ child.expectx('(%d)$ ' % (i + 1))
child.sendline('r get-tracked-object')
child.expectx('<<<get-tracked-object>>>\r\n'
- 'obj.x=1002\r\n'
+ 'got obj.x=1002\r\n'
'blipped\r\n'
'(3)$ ')
child.sendline('__go 3')
child.expectx('(3)$ ')
child.sendline('r get-tracked-object')
child.expectx('<<<get-tracked-object>>>\r\n'
- 'None\r\n'
+ 'none\r\n'
'blipped\r\n'
'(3)$ ')
#
@@ -559,13 +560,21 @@
child.expectx('<<<track-object %d>>>\r\n' % object_id_2nd +
'blipped\r\n'
'(1)$ ')
- child.sendline('__forward 5')
- child.expectx('(2)$ ')
+ child.sendline('__forward 2')
+ child.expectx('(3)$ ')
child.sendline('r get-tracked-object')
child.expectx('<<<get-tracked-object>>>\r\n'
- 'obj.x=1001\r\n'
+ 'got obj.x=1001\r\n'
'blipped\r\n'
- '(2)$ ')
+ '(3)$ ')
+ child.sendline('__forward 1')
+ child.expectx('At end.\r\n'
+ '(3)$ ')
+ child.sendline('r get-tracked-object')
+ child.expectx('<<<get-tracked-object>>>\r\n'
+ 'none\r\n'
+ 'blipped\r\n'
+ '(3)$ ')
def test_first_created_uid(self):
child = self.replay()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit