[PATCH v4 05/16] extension language API for GDB: breakpoint changes
Doug Evans
xdje42@gmail.com
Wed Jan 15 19:25:00 GMT 2014
This patch updates breakpoint.c to call the API functions in extension.h.
It also updates py-breakpoint.c, the functions that implement the
extension_language_ops "methods" are all named ${lang}_${method_name}.
The script condition test function, gdbpy_breakpoint_cond_says_stop,
has an enum result instead of just a boolean so that the caller can
know if there is a condition. One could call the
get_breakpoint_cond_ext_lang "method" except that python "finish
breakpoints" are implemented on top of normal breakpoints and require
calling "breakpoint_cond_says_stop" even if there is no stop method.
I can imagine reworking this, but there's no need to at the moment.
Changes from v2:
- in breakpoint.c, replace #include "python/python.h" with "extension.h"
- in breakpoint.c:condition_command, print name of extension language with
existing stop condition
- in py-breakpoint.c:local_setattro, print name of extension language with
existing stop condition
- updated py-breakpoint.exp
Changes from v1:
- updates for scripting -> extension renaming
2014-01-15 Doug Evans <xdje42@gmail.com>
* breakpoint.c (condition_command): Replace call to
gdbpy_breakpoint_has_py_cond with call to get_breakpoint_cond_ext_lang.
(bpstat_check_breakpoint_conditions): Replace call to gdbpy_should_stop
with call to breakpoint_ext_lang_cond_says_stop.
* python/py-breakpoint.c (gdbpy_breakpoint_cond_says_stop): Renamed
from gdbpy_should_stop. Change result type to enum scr_bp_stop.
New arg slang. Return SCR_BP_STOP_UNSET if py_bp_object is NULL.
(gdbpy_breakpoint_has_cond): Renamed from gdbpy_breakpoint_has_py_cond.
New arg slang.
(local_setattro): Print name of extension language with existing
stop condition.
testsuite/
* gdb.python/py-breakpoint.exp (test_bkpt_eval_funcs): Update expected
output.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 642ffdf..837d825 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -79,7 +79,7 @@
#undef savestring
#include "mi/mi-common.h"
-#include "python/python.h"
+#include "extension.h"
/* Enums for exception-handling support. */
enum exception_event_kind
@@ -1047,14 +1047,18 @@ condition_command (char *arg, int from_tty)
ALL_BREAKPOINTS (b)
if (b->number == bnum)
{
- /* 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."));
+ /* Check if this breakpoint has a "stop" method implemented in an
+ extension language. This method and conditions entered into GDB
+ from the CLI are mutually exclusive. */
+ const struct extension_language_defn *extlang
+ = get_breakpoint_cond_ext_lang (b, EXT_LANG_NONE);
+
+ if (extlang != NULL)
+ {
+ error (_("Only one stop condition allowed. There is currently"
+ " a %s stop condition defined for this breakpoint."),
+ ext_lang_capitalized_name (extlang));
+ }
set_breakpoint_condition (b, p, from_tty);
if (is_breakpoint (b))
@@ -5188,9 +5192,9 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
return;
}
- /* Evaluate Python breakpoints that have a "stop" method implemented. */
- if (b->py_bp_object)
- bs->stop = gdbpy_should_stop (b->py_bp_object);
+ /* Evaluate extension language breakpoints that have a "stop" method
+ implemented. */
+ bs->stop = breakpoint_ext_lang_cond_says_stop (b);
if (is_watchpoint (b))
{
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index aa404b7..125c6fd 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -750,15 +750,22 @@ gdbpy_breakpoints (PyObject *self, PyObject *args)
stopped at the breakpoint. Otherwise the inferior will be
allowed to continue. */
-int
-gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
+enum ext_lang_bp_stop
+gdbpy_breakpoint_cond_says_stop (const struct extension_language_defn *extlang,
+ struct breakpoint *b)
{
- int stop = 1;
-
+ int stop;
+ struct gdbpy_breakpoint_object *bp_obj = b->py_bp_object;
PyObject *py_bp = (PyObject *) bp_obj;
- struct breakpoint *b = bp_obj->bp;
- struct gdbarch *garch = b->gdbarch ? b->gdbarch : get_current_arch ();
- struct cleanup *cleanup = ensure_python_env (garch, current_language);
+ struct gdbarch *garch;
+ struct cleanup *cleanup;
+
+ if (bp_obj == NULL)
+ return EXT_LANG_BP_STOP_UNSET;
+
+ stop = -1;
+ garch = b->gdbarch ? b->gdbarch : get_current_arch ();
+ cleanup = ensure_python_env (garch, current_language);
if (bp_obj->is_finish_bp)
bpfinishpy_pre_stop_hook (bp_obj);
@@ -767,6 +774,7 @@ gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
{
PyObject *result = PyObject_CallMethod (py_bp, stop_func, NULL);
+ stop = 1;
if (result)
{
int evaluate = PyObject_IsTrue (result);
@@ -790,7 +798,9 @@ gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
do_cleanups (cleanup);
- return stop;
+ if (stop < 0)
+ return EXT_LANG_BP_STOP_UNSET;
+ return stop ? EXT_LANG_BP_STOP_YES : EXT_LANG_BP_STOP_NO;
}
/* Checks if the "stop" method exists in this breakpoint.
@@ -798,17 +808,21 @@ gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
conditions. */
int
-gdbpy_breakpoint_has_py_cond (struct gdbpy_breakpoint_object *bp_obj)
+gdbpy_breakpoint_has_cond (const struct extension_language_defn *extlang,
+ struct breakpoint *b)
{
- 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)
- has_func = PyObject_HasAttrString (py_bp, stop_func);
-
+ int has_func;
+ PyObject *py_bp;
+ struct gdbarch *garch;
+ struct cleanup *cleanup;
+
+ if (b->py_bp_object == NULL)
+ return 0;
+
+ py_bp = (PyObject *) b->py_bp_object;
+ garch = b->gdbarch ? b->gdbarch : get_current_arch ();
+ cleanup = ensure_python_env (garch, current_language);
+ has_func = PyObject_HasAttrString (py_bp, stop_func);
do_cleanups (cleanup);
return has_func;
@@ -947,16 +961,30 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v)
return -1;
/* 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)
+ but we already have a condition set in the CLI or other extension
+ language, disallow this operation. */
+ if (strcmp (attr, stop_func) == 0)
{
- xfree (attr);
- PyErr_SetString (PyExc_RuntimeError,
- _("Cannot set 'stop' method. There is an " \
- "existing GDB condition attached to the " \
- "breakpoint."));
- return -1;
+ const struct extension_language_defn *extlang = NULL;
+
+ if (obj->bp->cond_string != NULL)
+ extlang = get_ext_lang_defn (EXT_LANG_GDB);
+ if (extlang == NULL)
+ extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON);
+ if (extlang != NULL)
+ {
+ char *error_text;
+
+ xfree (attr);
+ error_text
+ = xstrprintf (_("Only one stop condition allowed. There is"
+ " currently a %s stop condition defined for"
+ " this breakpoint."),
+ ext_lang_capitalized_name (extlang));
+ PyErr_SetString (PyExc_RuntimeError, error_text);
+ xfree (error_text);
+ return -1;
+ }
}
xfree (attr);
diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp
index 1ae8fe6..911d586 100644
--- a/gdb/testsuite/gdb.python/py-breakpoint.exp
+++ b/gdb/testsuite/gdb.python/py-breakpoint.exp
@@ -372,7 +372,7 @@ proc test_bkpt_eval_funcs { } {
"Set breakpoint" 0
set test_cond {cond $bpnum}
gdb_test "$test_cond \"foo==3\"" \
- "Cannot set a condition where a Python.*" \
+ "Only one stop condition allowed. There is currently 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
@@ -385,7 +385,7 @@ proc test_bkpt_eval_funcs { } {
"end" ""
gdb_test "python eval_bp2.stop = stop_func" \
- "RuntimeError: Cannot set 'stop' method.*" \
+ "RuntimeError: Only one stop condition allowed. There is currently a GDB.*" \
"Assign stop function to a breakpoint that has a condition"
delete_breakpoints
More information about the Gdb-patches
mailing list