Author: Armin Rigo <ar...@tunes.org> Branch: reverse-debugger Changeset: r85094:44e6fa91e646 Date: 2016-06-11 10:48 +0200 http://bitbucket.org/pypy/pypy/changeset/44e6fa91e646/
Log: Can't do I/O in rpython commands diff --git a/rpython/translator/revdb/rdb-src/revdb.c b/rpython/translator/revdb/rdb-src/revdb.c --- a/rpython/translator/revdb/rdb-src/revdb.c +++ b/rpython/translator/revdb/rdb-src/revdb.c @@ -6,6 +6,7 @@ #include <fcntl.h> #include <unistd.h> #include <ctype.h> +#include <setjmp.h> #include "preimpl.h" #include "structdef.h" @@ -189,6 +190,8 @@ enum { PK_MAIN_PROCESS, PK_FROZEN_PROCESS, PK_DEBUG_PROCESS }; static unsigned char process_kind = PK_MAIN_PROCESS; static unsigned char flag_exit_run_debug_process; +static unsigned char flag_executing_rpython_code; +static jmp_buf jmp_buf_cancel_execution; static uint64_t latest_fork; static uint64_t total_stop_points; @@ -284,15 +287,39 @@ RPY_EXTERN char *rpy_reverse_db_fetch(int expected_size) { - ssize_t rsize, keep = rpy_revdb.buf_limit - rpy_revdb.buf_p; - assert(keep >= 0); - memmove(rpy_rev_buffer, rpy_revdb.buf_p, keep); - rsize = read_at_least(rpy_rev_buffer + keep, - expected_size - keep, - sizeof(rpy_rev_buffer) - keep); - rpy_revdb.buf_p = rpy_rev_buffer; - rpy_revdb.buf_limit = rpy_rev_buffer + keep + rsize; - return rpy_rev_buffer; + if (!flag_executing_rpython_code) { + ssize_t rsize, keep = rpy_revdb.buf_limit - rpy_revdb.buf_p; + assert(keep >= 0); + memmove(rpy_rev_buffer, rpy_revdb.buf_p, keep); + rsize = read_at_least(rpy_rev_buffer + keep, + expected_size - keep, + sizeof(rpy_rev_buffer) - keep); + rpy_revdb.buf_p = rpy_rev_buffer; + rpy_revdb.buf_limit = rpy_rev_buffer + keep + rsize; + return rpy_rev_buffer; + } + else { + /* this is called when we are in execute_rpy_command(): we are + running some custom code now, and we can't just perform I/O + or access raw memory---because there is no raw memory! + */ + printf("Attempted to do I/O or access raw memory\n"); + longjmp(jmp_buf_cancel_execution, 1); + } +} + +static void disable_io(rpy_revdb_t *dinfo) +{ + *dinfo = rpy_revdb; /* save the complete struct */ + rpy_revdb.buf_p = NULL; + rpy_revdb.buf_limit = NULL; + flag_executing_rpython_code = 1; +} + +static void enable_io(rpy_revdb_t *dinfo) +{ + flag_executing_rpython_code = 0; + rpy_revdb = *dinfo; } /* generated by RPython */ @@ -303,6 +330,7 @@ { size_t length = strlen(arguments); RPyString *s; + rpy_revdb_t dinfo; while (length > 0 && isspace(arguments[length - 1])) length--; @@ -316,7 +344,10 @@ RPyString_Size(s) = length; memcpy(_RPyString_AsString(s), arguments, length); - rpy_revdb_command_funcs[index](s); + disable_io(&dinfo); + if (setjmp(jmp_buf_cancel_execution) == 0) + rpy_revdb_command_funcs[index](s); + enable_io(&dinfo); } struct action_s { 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 @@ -189,6 +189,9 @@ # def blip(cmdline): revdb.send_output('<<<' + cmdline + '>>>\n') + if cmdline == 'oops': + for i in range(1000): + print 42 # I/O not permitted revdb.send_output('blipped\n') lambda_blip = lambda: blip # @@ -207,3 +210,22 @@ child.sendline('r foo bar baz ') child.expectx('<<<foo bar baz>>>\r\nblipped\r\n') child.expectx('(3)$ ') + + def test_io_not_permitted(self): + child = self.replay() + child.expectx('(3)$ ') + child.sendline('r oops') + child.expectx('<<<oops>>>\r\nAttempted to do I/O or access raw memory') + child.expectx('(3)$ ') + + def test_interaction_with_forward(self): + child = self.replay() + child.expectx('(3)$ ') + child.sendline('go 1') + child.expectx('(1)$ ') + child.sendline('r oops') + child.expectx('<<<oops>>>\r\nAttempted to do I/O or access raw memory') + child.expectx('(1)$ ') + child.sendline('forward 50') + child.expectx('At end.\r\n') + child.expectx('(3)$ ') _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit