From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8565 invoked by alias); 24 Dec 2013 18:49:34 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 8520 invoked by uid 89); 24 Dec 2013 18:49:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_00,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,MSGID_FROM_MTA_HEADER,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pb0-f51.google.com Received: from mail-pb0-f51.google.com (HELO mail-pb0-f51.google.com) (209.85.160.51) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 24 Dec 2013 18:49:32 +0000 Received: by mail-pb0-f51.google.com with SMTP id up15so6732971pbc.38 for ; Tue, 24 Dec 2013 10:49:30 -0800 (PST) X-Received: by 10.68.204.4 with SMTP id ku4mr34320987pbc.66.1387910970404; Tue, 24 Dec 2013 10:49:30 -0800 (PST) Received: from sspiff.org (173-13-178-53-sfba.hfc.comcastbusiness.net. [173.13.178.53]) by mx.google.com with ESMTPSA id wp8sm43405736pbc.26.2013.12.24.10.49.27 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Dec 2013 10:49:29 -0800 (PST) Message-ID: <52b9d739.68f2440a.1c82.ffff925a@mx.google.com> Received: by sspiff.org (sSMTP sendmail emulation); Tue, 24 Dec 2013 10:49:04 -0800 Date: Tue, 24 Dec 2013 18:49:00 -0000 From: Doug Evans To: gdb-patches@sourceware.org Subject: [PATCH v3 05/15] extension language API for GDB: breakpoint changes X-IsSubscribed: yes X-SW-Source: 2013-12/txt/msg00916.txt.bz2 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 2013-12-24 Doug Evans * 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 6a11ddf..8013189 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -80,7 +80,7 @@ #undef savestring #include "mi/mi-common.h" -#include "python/python.h" +#include "extension.h" /* Enums for exception-handling support. */ enum exception_event_kind @@ -1048,14 +1048,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)) @@ -5140,9 +5144,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 1085588..1d11e84 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 107b026..c86695e 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