Author: Armin Rigo <[email protected]>
Branch: reverse-debugger
Changeset: r86167:c46e5f55f170
Date: 2016-08-12 11:34 +0200
http://bitbucket.org/pypy/pypy/changeset/c46e5f55f170/
Log: When entering debugger commands, make floating-point results
approximately work
diff --git a/rpython/rlib/rdtoa.py b/rpython/rlib/rdtoa.py
--- a/rpython/rlib/rdtoa.py
+++ b/rpython/rlib/rdtoa.py
@@ -3,7 +3,7 @@
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.translator import cdir
from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rlib import jit
+from rpython.rlib import jit, revdb
from rpython.rlib.rstring import StringBuilder
import py, sys
@@ -54,6 +54,8 @@
def strtod(input):
if len(input) > _INT_LIMIT:
raise MemoryError
+ if revdb.flag_io_disabled():
+ return revdb.emulate_strtod(input)
end_ptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
try:
ll_input = rffi.str2charp(input)
@@ -236,6 +238,8 @@
special_strings=lower_special_strings, upper=False):
if precision > _INT_LIMIT:
raise MemoryError
+ if revdb.flag_io_disabled():
+ return revdb.emulate_dtoa(value)
decpt_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
try:
sign_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
diff --git a/rpython/rlib/revdb.py b/rpython/rlib/revdb.py
--- a/rpython/rlib/revdb.py
+++ b/rpython/rlib/revdb.py
@@ -7,7 +7,7 @@
from rpython.rtyper.extregistry import ExtRegistryEntry
from rpython.rtyper.annlowlevel import llhelper, hlstr
from rpython.rtyper.annlowlevel import cast_gcref_to_instance
-from rpython.rtyper.lltypesystem import rffi
+from rpython.rtyper.lltypesystem import lltype, rffi
CMD_PRINT = 1
@@ -81,6 +81,14 @@
"""
return llop.revdb_get_value(lltype.Signed, 'p')
+def flag_io_disabled():
+ """Returns True if we're in the debugger typing commands."""
+ if we_are_translated():
+ if fetch_translated_config().translation.reverse_debugger:
+ flag = llop.revdb_get_value(lltype.Signed, 'i')
+ return flag != ord('R') # FID_REGULAR_MODE
+ return False
+
## @specialize.arg(1)
## def go_forward(time_delta, callback):
## """For RPython debug commands: tells that after this function finishes,
@@ -203,3 +211,22 @@
def specialize_call(self, hop):
hop.exception_cannot_occur()
+
+
+# ____________________________________________________________
+
+# Emulation for strtod() and dtoa() when running debugger commands
+# (we can't easily just call C code there). The emulation can return
+# a crude result. Hack hack hack.
+
+_INVALID_STRTOD = -3.46739514239368e+113
+
+def emulate_strtod(input):
+ d = llop.revdb_strtod(lltype.Float, input)
+ if d == _INVALID_STRTOD:
+ raise ValueError
+ return d
+
+def emulate_dtoa(value):
+ s = llop.revdb_dtoa(lltype.Ptr(rstr.STR), value)
+ return hlstr(s)
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
@@ -584,6 +584,8 @@
'revdb_weakref_deref': LLOp(),
'revdb_call_destructor': LLOp(),
'revdb_set_thread_breakpoint': LLOp(),
+ 'revdb_strtod': LLOp(sideeffects=False),
+ 'revdb_dtoa': 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
@@ -1523,6 +1523,8 @@
saved_state.unique_id_seen);
case 'p': /* current_place() */
return current_place;
+ case 'i': /* flag_io_disabled() */
+ return flag_io_disabled;
default:
return -1;
}
@@ -1734,6 +1736,39 @@
break_thread_num = (uint64_t)tnum;
}
+#define INVALID_STRTOD (-3.46739514239368e+113)
+
+RPY_EXTERN
+double rpy_reverse_db_strtod(RPyString *s)
+{
+ /* approximate hacks only */
+ double result;
+ char *endptr = NULL;
+ char buffer[8192];
+ size_t size = RPyString_Size(s);
+
+ if (size >= sizeof(buffer))
+ return INVALID_STRTOD;
+ memcpy(buffer, _RPyString_AsString(s), size);
+ buffer[size] = '\0';
+ result = strtod(buffer, &endptr);
+ if (endptr == NULL || *endptr != '\0')
+ return INVALID_STRTOD;
+ return result;
+}
+
+RPY_EXTERN RPyString *rpy_reverse_db_dtoa(double d)
+{
+ char buffer[128];
+ RPyString *result;
+ int size;
+ size = snprintf(buffer, sizeof(buffer), "%g", d);
+ if (size < 0) size = 0; /* XXX? */
+ result = make_rpy_string(size);
+ memcpy(_RPyString_AsString(result), buffer, size);
+ return result;
+}
+
/* ------------------------------------------------------------ */
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
@@ -230,6 +230,12 @@
#define OP_REVDB_SET_THREAD_BREAKPOINT(tnum, r) \
rpy_reverse_db_set_thread_breakpoint(tnum)
+#define OP_REVDB_STRTOD(s, r) \
+ r = rpy_reverse_db_strtod(s)
+
+#define OP_REVDB_DTOA(d, r) \
+ r = rpy_reverse_db_dtoa(d)
+
RPY_EXTERN void rpy_reverse_db_flush(void); /* must be called with the lock */
RPY_EXTERN void rpy_reverse_db_fetch(const char *file, int line);
@@ -253,5 +259,7 @@
RPY_EXTERN void rpy_reverse_db_lock_acquire(bool_t lock_contention);
RPY_EXTERN void rpy_reverse_db_bad_acquire_gil(void);
RPY_EXTERN void rpy_reverse_db_set_thread_breakpoint(int64_t tnum);
+RPY_EXTERN double rpy_reverse_db_strtod(RPyString *s);
+RPY_EXTERN RPyString *rpy_reverse_db_dtoa(double d);
/* ------------------------------------------------------------ */
diff --git a/rpython/translator/revdb/test/test_process.py
b/rpython/translator/revdb/test/test_process.py
--- a/rpython/translator/revdb/test/test_process.py
+++ b/rpython/translator/revdb/test/test_process.py
@@ -1,6 +1,6 @@
import py, sys
from cStringIO import StringIO
-from rpython.rlib import revdb
+from rpython.rlib import revdb, rdtoa
from rpython.rlib.debug import debug_print, ll_assert
from rpython.rtyper.annlowlevel import cast_gcref_to_instance
from rpython.translator.revdb.message import *
@@ -47,6 +47,10 @@
stuff = dbstate.stuff
elif extra == '$0':
stuff = dbstate.metavar
+ elif extra == '2.35':
+ val = rdtoa.strtod('2.35')
+ revdb.send_output(rdtoa.dtoa(val))
+ return
else:
assert False
uid = revdb.get_unique_id(stuff)
@@ -199,3 +203,9 @@
group = self.test_print_cmd()
group.jump_in_time(2)
self._check_watchpoint_expr(group, must_exist=1)
+
+ def test_rdtoa(self):
+ group = ReplayProcessGroup(str(self.exename), self.rdbname)
+ with stdout_capture() as buf:
+ group.print_cmd('2.35')
+ assert buf.getvalue() == "2.35"
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit