Author: Armin Rigo <[email protected]>
Branch: reverse-debugger
Changeset: r85169:5527e8d6a710
Date: 2016-06-14 22:32 +0200
http://bitbucket.org/pypy/pypy/changeset/5527e8d6a710/
Log: finish and test object tracking in detail
diff --git a/rpython/rlib/revdb.py b/rpython/rlib/revdb.py
--- a/rpython/rlib/revdb.py
+++ b/rpython/rlib/revdb.py
@@ -81,14 +81,15 @@
"""
return llop.revdb_get_unique_id(lltype.SignedLongLong, x)
-def track_objects(unique_id):
+def track_object(unique_id):
"""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.
"""
- return llop.revdb_track_object(lltype.Bool, x)
+ llop.revdb_track_object(lltype.Void, unique_id)
@specialize.arg(0)
def get_tracked_object(Class=llmemory.GCREF): # or an RPython class
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
@@ -370,13 +370,15 @@
static void enable_io(rpy_revdb_t *dinfo)
{
- uint64_t v;
+ uint64_t v1, v2;
flag_io_disabled = 0;
- /* restore the complete struct, with the exception of 'stop_point_break' */
- v = rpy_revdb.stop_point_break;
+ /* restore the complete struct, with the exception of '*_break' */
+ v1 = rpy_revdb.stop_point_break;
+ v2 = rpy_revdb.unique_id_break;
rpy_revdb = *dinfo;
- rpy_revdb.stop_point_break = v;
+ rpy_revdb.stop_point_break = v1;
+ rpy_revdb.unique_id_break = v2;
}
/* generated by RPython */
@@ -880,12 +882,40 @@
}
}
+static void *tracked_object;
+
RPY_EXTERN
uint64_t rpy_reverse_db_unique_id_break(void *new_object)
{
- fprintf(stderr, "PING\n");
- abort();
+ tracked_object = new_object;
+ rpy_revdb.stop_point_break = rpy_revdb.stop_point_seen + 1;
+ return rpy_revdb.unique_id_seen;
}
+RPY_EXTERN
+void rpy_reverse_db_track_object(long long unique_id)
+{
+ if (stopped_uid <= 0) {
+ fprintf(stderr, "stopped_uid should not be <= 0\n");
+ exit(1);
+ }
+ if (unique_id <= 0) {
+ printf("cannot track a prebuilt or debugger-created object\n");
+ return;
+ }
+ if (unique_id < stopped_uid) {
+ printf("cannot track the creation of an object already created\n");
+ return;
+ }
+ 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,6 +96,12 @@
#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()
+
RPY_EXTERN void rpy_reverse_db_flush(void);
RPY_EXTERN char *rpy_reverse_db_fetch(int expected_size,
const char *file, int line);
@@ -107,6 +113,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);
/* ------------------------------------------------------------ */
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
@@ -339,13 +339,17 @@
if cmdline == 'set-break-after-0':
dbstate.break_after = 0
if cmdline == 'print-id':
- revdb.send_output('%d %d\n' % (
+ revdb.send_output('obj.x=%d %d %d\n' % (
+ dbstate.stuff.x,
revdb.get_unique_id(dbstate.stuff),
revdb.currently_created_objects()))
- #if cmdline.startswith('check-id '):
- # obj_id = int(cmdline[len('check-id '):])
- # revdb.send_output("%d\n" %
- # int(revdb.id_to_object(Stuff, obj_id) is dbstate.stuff))
+ if cmdline.startswith('track-object '):
+ uid = int(cmdline[len('track-object '):])
+ revdb.track_object(uid)
+ 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))
revdb.send_output('blipped\n')
lambda_blip = lambda: blip
#
@@ -466,24 +470,96 @@
child.expectx('breakpoint!\r\n'
'(2)$ ')
- def test_get_unique_id(self):
+ def test_get_unique_id_and_track_object(self):
child = self.replay()
child.expectx('(3)$ ')
child.sendline('r print-id')
child.expect(re.escape('<<<print-id>>>\r\n')
- + r'(\d+) (\d+)'
+ + r'obj.x=1002 (\d+) (\d+)'
+ re.escape('\r\n'
'blipped\r\n'
'(3)$ '))
- object_id = int(child.match.group(1))
- currenty_created_objects = int(child.match.group(2))
- assert 0 < object_id < currenty_created_objects
- XXX
- for at_time in [1, 2, 3]:
- child.sendline('__go %d' % at_time)
- child.expectx('(%d)$ ' % at_time)
- child.sendline('r check-id ' + object_id)
- child.expectx('<<<check-id %s>>>\r\n' % (object_id,) +
- '1\r\n' +
- 'blipped\r\n' +
- '(%d)$ ' % at_time)
+ object_id_3rd = int(child.match.group(1))
+ created_objects_3rd = int(child.match.group(2))
+ assert 0 < object_id_3rd < created_objects_3rd
+ #
+ child.sendline('__go 1')
+ child.expectx('(1)$ ')
+ child.sendline('r print-id')
+ child.expect(re.escape('<<<print-id>>>\r\n')
+ + r'obj.x=1000 (\d+) (\d+)'
+ + re.escape('\r\n'
+ 'blipped\r\n'
+ '(1)$ '))
+ object_id_1st = int(child.match.group(1))
+ created_objects_1st = int(child.match.group(2))
+ assert 0 < object_id_1st < created_objects_1st
+ assert created_objects_1st <= object_id_3rd # only created afterwards
+ #
+ child.sendline('r track-object %d' % object_id_3rd)
+ child.expectx('<<<track-object %d>>>\r\n' % object_id_3rd +
+ 'blipped\r\n'
+ '(1)$ ')
+ prev_time = 1
+ for i in [1, 2, 3]:
+ child.sendline('r get-tracked-object')
+ child.expectx('<<<get-tracked-object>>>\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))
+ child.sendline('r get-tracked-object')
+ child.expectx('<<<get-tracked-object>>>\r\n'
+ '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'
+ 'blipped\r\n'
+ '(3)$ ')
+ #
+ child.sendline('__go 2')
+ child.expectx('(2)$ ')
+ child.sendline('r print-id')
+ child.expect(re.escape('<<<print-id>>>\r\n')
+ + r'obj.x=1001 (\d+) (\d+)'
+ + re.escape('\r\n'
+ 'blipped\r\n'
+ '(2)$ '))
+ object_id_2nd = int(child.match.group(1))
+ created_objects_2nd = int(child.match.group(2))
+ #
+ child.sendline('r track-object %d' % object_id_2nd)
+ child.expectx('<<<track-object %d>>>\r\n' % object_id_2nd +
+ 'cannot track the creation of an object already
created\r\n'
+ 'blipped\r\n'
+ '(2)$ ')
+ child.sendline('r track-object 0')
+ child.expectx('<<<track-object 0>>>\r\n'
+ 'cannot track a prebuilt or debugger-created object\r\n'
+ 'blipped\r\n'
+ '(2)$ ')
+ child.sendline('__go 1')
+ child.expectx('(1)$ ')
+ child.sendline('r track-object %d' % object_id_2nd)
+ child.expectx('<<<track-object %d>>>\r\n' % object_id_2nd +
+ 'blipped\r\n'
+ '(1)$ ')
+ child.sendline('__forward 5')
+ child.expectx('(2)$ ')
+ child.sendline('r get-tracked-object')
+ child.expectx('<<<get-tracked-object>>>\r\n'
+ 'obj.x=1001\r\n'
+ 'blipped\r\n'
+ '(2)$ ')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit