Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit