From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32367 invoked by alias); 11 Mar 2011 11:12:49 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 32337 invoked by uid 9514); 11 Mar 2011 11:12:48 -0000 Date: Fri, 11 Mar 2011 11:12:00 -0000 Message-ID: <20110311111247.32322.qmail@sourceware.org> From: pmuldoon@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-pmuldoon-python-breakpoints: Rename python method to 'stop'. Add cleanup to comments. Install dummy functions for non-Python support. Prepare for review. X-Git-Refname: refs/heads/archer-pmuldoon-python-breakpoints X-Git-Reftype: branch X-Git-Oldrev: 81d36efbe8718d9008bf4b1ea05838ff371c849e X-Git-Newrev: aa32708bbb3283f5816e25b5a05e347323d3ced3 X-SW-Source: 2011-q1/txt/msg00185.txt.bz2 List-Id: The branch, archer-pmuldoon-python-breakpoints has been updated via aa32708bbb3283f5816e25b5a05e347323d3ced3 (commit) from 81d36efbe8718d9008bf4b1ea05838ff371c849e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit aa32708bbb3283f5816e25b5a05e347323d3ced3 Author: Phil Muldoon Date: Fri Mar 11 11:12:02 2011 +0000 Rename python method to 'stop'. Add cleanup to comments. Install dummy functions for non-Python support. Prepare for review. ----------------------------------------------------------------------- Summary of changes: gdb/breakpoint.c | 11 +++++++-- gdb/doc/gdb.texinfo | 12 +++++----- gdb/python/py-breakpoint.c | 26 ++++++++++++++--------- gdb/python/python.c | 14 ++++++------ gdb/testsuite/gdb.python/py-breakpoint.exp | 31 +++++++++++++++++++++++++-- 5 files changed, 65 insertions(+), 29 deletions(-) First 500 lines of diff: diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index f728021..9736b12 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -644,8 +644,13 @@ condition_command (char *arg, int from_tty) ALL_BREAKPOINTS (b) if (b->number == bnum) { - if (gdbpy_breakpoint_has_py_cond (b->py_bp_object)) - error (_("Cannot set a condition where a Python 'should_stop' " \ + /* Check if this breakpoint has a Python object assigned to + it, and if it has a definition of the "stop" + method. This method and conditions entered into GDB from + the CLI are mutually exclusive. */ + if (b->py_bp_object + && gdbpy_breakpoint_has_py_cond (b->py_bp_object)) + error (_("Cannot set a condition where a Python 'stop' " \ "method has been defined in the breakpoint.")); set_breakpoint_condition (b, p, from_tty); return; @@ -4074,7 +4079,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid) int value_is_zero = 0; struct expression *cond; - /* Evaluate Python breakpoints that have a "condition" + /* Evaluate Python breakpoints that have a "stop" method implemented. */ if (b->py_bp_object) bs->stop = gdbpy_should_stop (b->py_bp_object); diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 6d87024..9ca6c09 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -23099,9 +23099,9 @@ argument defines the class of watchpoint to create, if @var{type} is assumed to be a @var{WP_WRITE} class. @end defmethod -@defop Operation {gdb.Breakpoint} stop_p (self) +@defop Operation {gdb.Breakpoint} stop (self) The @code{gdb.Breakpoint} class can be sub-classed and, in -particular, you may choose to implement the @code{stop_p} method. +particular, you may choose to implement the @code{stop} method. If this method is defined as a sub-class of @code{gdb.Breakpoint}, it will be called when the inferior stops at any location of a breakpoint which instantiates that sub-class. If the method returns @@ -23109,17 +23109,17 @@ breakpoint which instantiates that sub-class. If the method returns breakpoint, otherwise the inferior will continue. If there are multiple breakpoints at the same location with a -@code{stop_p} method, each one will be called regardless of the -return status of the previous. This ensures that all @code{stop_p} +@code{stop} method, each one will be called regardless of the +return status of the previous. This ensures that all @code{stop} methods have a chance to execute at that location. In this scenario if one of the methods returns @code{True} but the others return @code{False}, the inferior will still be stopped. -Example @code{stop_p} implementation: +Example @code{stop} implementation: @smallexample class MyBreakpoint (gdb.Breakpoint): - def stop_p (self): + def stop (self): inf_val = gdb.parse_and_eval("foo") if inf_val == 3: return True diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index 1069dd5..6e5db8f 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -41,7 +41,7 @@ static int bppy_live; static breakpoint_object *bppy_pending_object; /* Function that is called when a Python condition is evaluated. */ -char *stop_func = "should_stop"; +char *stop_func = "stop"; struct breakpoint_object { @@ -708,7 +708,7 @@ gdbpy_breakpoints (PyObject *self, PyObject *args) return PyList_AsTuple (list); } -/* Call the "should_stop" method (if implemented) in the breakpoint +/* Call the "stop" method (if implemented) in the breakpoint class. If the method returns True, the inferior will be stopped at the breakpoint. Otherwise the inferior will be allowed to continue. */ @@ -716,7 +716,7 @@ gdbpy_breakpoints (PyObject *self, PyObject *args) int gdbpy_should_stop (struct breakpoint_object *bp_obj) { - int should_stop = 1; + int stop = 1; PyObject *py_bp = (PyObject *) bp_obj; struct breakpoint *b = bp_obj->bp; @@ -734,10 +734,10 @@ gdbpy_should_stop (struct breakpoint_object *bp_obj) if (evaluate == -1) gdbpy_print_stack (); - /* If the "should_stop" function returns False that means + /* If the "stop" function returns False that means the Python breakpoint wants GDB to continue. */ if (! evaluate) - should_stop = 0; + stop = 0; Py_DECREF (result); } @@ -746,23 +746,29 @@ gdbpy_should_stop (struct breakpoint_object *bp_obj) } do_cleanups (cleanup); - return should_stop; + return stop; } -/* Checks if the "should_stop" method exists in this breakpoint. +/* Checks if the "stop" method exists in this breakpoint. Used by condition_command to ensure mutual exclusion of breakpoint conditions. */ int gdbpy_breakpoint_has_py_cond (struct breakpoint_object *bp_obj) { + int has_func = 0; PyObject *py_bp = (PyObject *) bp_obj; + struct gdbarch *garch = bp_obj->bp->gdbarch ? bp_obj->bp->gdbarch : + get_current_arch (); struct cleanup *cleanup = ensure_python_env (garch, current_language); if (py_bp == NULL) return 0; - return PyObject_HasAttrString (py_bp, stop_func); + has_func = PyObject_HasAttrString (py_bp, stop_func); + do_cleanups (cleanup); + + return has_func; } @@ -897,14 +903,14 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v) if (attr == NULL) return -1; - /* If the attribute trying to be set is the "should_stop" method, + /* If the attribute trying to be set is the "stop" method, but we already have a condition set in the CLI, disallow this operation. */ if (strcmp (attr, stop_func) == 0 && obj->bp->cond_string) { xfree (attr); PyErr_SetString (PyExc_RuntimeError, - _("Cannot set should_stop method. There is an " \ + _("Cannot set 'stop' method. There is an " \ "existing GDB condition attached to the " \ "breakpoint.")); return -1; diff --git a/gdb/python/python.c b/gdb/python/python.c index 9da1c19..2d7213a 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -30,6 +30,7 @@ #include "exceptions.h" #include "event-loop.h" #include "serial.h" +#include "python.h" #include @@ -39,7 +40,6 @@ static int gdbpy_should_print_stack = 1; #ifdef HAVE_PYTHON -#include "python.h" #include "libiberty.h" #include "cli/cli-decode.h" #include "charset.h" @@ -867,17 +867,17 @@ source_python_script (FILE *stream, const char *file) int gdbpy_should_stop (struct breakpoint_object *bp_obj) { - /* Just assume default breakpoint behavior if Python is not - installed. */ - return 1; + internal_error (__FILE__, __LINE__, + _("gdbpy_should_stop called when Python scripting is " \ + "not supported.")); } int gdbpy_breakpoint_has_py_cond (struct breakpoint_object *bp_obj) { - /* If Python is not installed, then neither can a Python - "should_stop" function. */ - return 0; + internal_error (__FILE__, __LINE__, + _("gdbpy_breakpoint_has_py_cond called when Python " \ + "scripting is not supported.")); } #endif /* HAVE_PYTHON */ diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp index 6bf90cb..f0a83f1 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint.exp @@ -212,7 +212,7 @@ gdb_py_test_multiple "Sub-class a breakpoint" \ "class bp_eval (gdb.Breakpoint):" "" \ " inf_i = 0" "" \ " count = 0" "" \ - " def should_stop (self):" "" \ + " def stop (self):" "" \ " self.count = self.count + 1" "" \ " self.inf_i = gdb.parse_and_eval(\"i\")" "" \ " if self.inf_i == 3:" "" \ @@ -224,13 +224,19 @@ gdb_py_test_multiple "Sub-class a second breakpoint" \ "python" "" \ "class bp_also_eval (gdb.Breakpoint):" "" \ " count = 0" "" \ - " def should_stop (self):" "" \ + " def stop (self):" "" \ " self.count = self.count + 1" "" \ " if self.count == 9:" "" \ " return True" "" \ " return False" "" \ "end" "" +gdb_py_test_multiple "Sub-class a third breakpoint" \ + "python" "" \ + "class basic (gdb.Breakpoint):" "" \ + " count = 0" "" \ + "end" "" + set bp_location2 [gdb_get_line_number "Break at multiply."] set end_location [gdb_get_line_number "Break at end."] gdb_py_test_silent_cmd "python eval_bp1 = bp_eval(\"$bp_location2\")" "Set breakpoint" 0 @@ -245,6 +251,25 @@ gdb_test "python print eval_bp1.count" "4" \ "Check non firing same-location breakpoint eval function was also called at each stop." delete_breakpoints +set cond_bp [gdb_get_line_number "Break at multiply."] +gdb_py_test_silent_cmd "python eval_bp1 = bp_eval(\"$cond_bp\")" "Set breakpoint" 0 +set test_cond {cond $bpnum} +gdb_test "$test_cond \"foo==3\"" "Cannot set a condition where a Python.*" \ + "Check you cannot add a CLI condition to a Python breakpoint that" \ + "has defined stop" +gdb_py_test_silent_cmd "python eval_bp2 = basic(\"$cond_bp\")" "Set breakpoint" 0 +gdb_py_test_silent_cmd "python eval_bp2.condition = \"1==1\"" "Set a condition" 0 +gdb_py_test_multiple "Construct an eval function" \ + "python" "" \ + "def stop_func ():" "" \ + " return True" "" \ + "end" "" + +gdb_test "python eval_bp2.stop = stop_func" \ + "RuntimeError: Cannot set 'stop' method.*" \ + "Assign stop function to a breakpoint that has a condition" + +delete_breakpoints gdb_breakpoint [gdb_get_line_number "Break at multiply."] gdb_py_test_silent_cmd "python check_eval = bp_eval(\"$bp_location2\")" "Set breakpoint" 0 gdb_test "python print check_eval.count" "0" \ @@ -256,7 +281,7 @@ gdb_test "python print check_eval.count" "1" \ gdb_py_test_multiple "Sub-class a watchpoint" \ "python" "" \ "class wp_eval (gdb.Breakpoint):" "" \ - " def should_stop (self):" "" \ + " def stop (self):" "" \ " self.result = gdb.parse_and_eval(\"result\")" "" \ " if self.result == 788:" "" \ " return True" "" \ hooks/post-receive -- Repository for Project Archer.