From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21793 invoked by alias); 18 Sep 2013 09:09:29 -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 21780 invoked by uid 89); 18 Sep 2013 09:09:29 -0000 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 18 Sep 2013 09:09:29 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.3 required=5.0 tests=AWL,BAYES_00,KHOP_THREADED,RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r8I99P1M011971 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 18 Sep 2013 05:09:26 -0400 Received: from localhost.localdomain (ovpn-112-31.ams2.redhat.com [10.36.112.31]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r8I99NB2021495; Wed, 18 Sep 2013 05:09:24 -0400 Message-ID: <52396DC3.4090104@redhat.com> Date: Wed, 18 Sep 2013 09:09:00 -0000 From: Phil Muldoon MIME-Version: 1.0 To: Tom Tromey CC: gdb-patches@sourceware.org Subject: Re: [python][patch] Add temporary breakpoint features to Python breakpoints. References: <522D9D57.5030309@redhat.com> <87r4cxj0i3.fsf@fleche.redhat.com> In-Reply-To: <87r4cxj0i3.fsf@fleche.redhat.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2013-09/txt/msg00572.txt.bz2 On 09/09/13 19:47, Tom Tromey wrote: >>>>>> "Phil" == Phil Muldoon writes: > Phil> 2013-09-09 Phil Muldoon > > Phil> * python/py-breakpoint.c (bppy_get_temporary): New function. > Phil> (bppy_init): New keyword: temporary. Parse it and set breakpoint > Phil> to temporary if True. > > Is there a PR associated with this? > I thought there was, but I didn't check. I did a search and I could not find one. > In particular I was wondering how it interacts with the "stop" method. I added a test to make sure the "stop" method is executing before deletion. I think the docs are approved by both you and Eli? Other nits fixed up too. ChangeLog remains the same. OK? Cheers, Phil -- diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 21250fe..627d65e 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -26799,22 +26799,27 @@ Return the static block of the underlying symbol table. Python code can manipulate breakpoints via the @code{gdb.Breakpoint} class. -@defun Breakpoint.__init__ (spec @r{[}, type @r{[}, wp_class @r{[},internal@r{]]]}) -Create a new breakpoint. @var{spec} is a string naming the -location of the breakpoint, or an expression that defines a -watchpoint. The contents can be any location recognized by the -@code{break} command, or in the case of a watchpoint, by the @code{watch} -command. The optional @var{type} denotes the breakpoint to create -from the types defined later in this chapter. This argument can be -either: @code{gdb.BP_BREAKPOINT} or @code{gdb.BP_WATCHPOINT}. @var{type} -defaults to @code{gdb.BP_BREAKPOINT}. The optional @var{internal} argument -allows the breakpoint to become invisible to the user. The breakpoint -will neither be reported when created, nor will it be listed in the -output from @code{info breakpoints} (but will be listed with the -@code{maint info breakpoints} command). The optional @var{wp_class} -argument defines the class of watchpoint to create, if @var{type} is -@code{gdb.BP_WATCHPOINT}. If a watchpoint class is not provided, it is -assumed to be a @code{gdb.WP_WRITE} class. +@defun Breakpoint.__init__ (spec @r{[}, type @r{[}, wp_class @r{[},internal @r{[},temporary@r{]]]]}) +Create a new breakpoint. @var{spec} is a string naming the location +of the breakpoint, or an expression that defines a watchpoint. The +contents can be any location recognized by the @code{break} command, +or in the case of a watchpoint, by the @code{watch} command. The +optional @var{type} denotes the breakpoint to create from the types +defined later in this chapter. This argument can be either: +@code{gdb.BP_BREAKPOINT} or @code{gdb.BP_WATCHPOINT}. @var{type} +defaults to @code{gdb.BP_BREAKPOINT}. The optional @var{internal} +argument allows the breakpoint to become invisible to the user. The +breakpoint will neither be reported when created, nor will it be +listed in the output from @code{info breakpoints} (but will be listed +with the @code{maint info breakpoints} command). The optional +@var{temporary} argument makes the breakpoint a temporary breakpoint. +Temporary breakpoints are deleted after they have been hit. Any +further access to the Python breakpoint after it has been hit will +result in a runtime error (as that breakpoint has now been +automatically deleted). The optional @var{wp_class} argument defines +the class of watchpoint to create, if @var{type} is +@code{gdb.BP_WATCHPOINT}. If a watchpoint class is not provided, it +is assumed to be a @code{gdb.WP_WRITE} class. @end defun @defun Breakpoint.stop (self) @@ -26935,6 +26940,16 @@ when set, or when the @samp{info breakpoints} command is run. This attribute is not writable. @end defvar +@defvar Breakpoint.temporary +This attribute indicates whether the breakpoint was created as a +temporary breakpoint. Temporary breakpoints are automatically deleted +after that breakpoint has been hit. Access to this attribute, and all +other attributes and functions other than the @code{is_valid} +function, will result in an error after the breakpoint has been hit +(as it has been automatically deleted). This attribute is not +writable. +@end defvar + The available types are represented by constants defined in the @code{gdb} module: diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index 87f1fdc..e83471e 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -529,6 +529,23 @@ bppy_get_visibility (PyObject *self, void *closure) Py_RETURN_TRUE; } +/* Python function to determine if the breakpoint is a temporary + breakpoint. */ + +static PyObject * +bppy_get_temporary (PyObject *self, void *closure) +{ + breakpoint_object *self_bp = (breakpoint_object *) self; + + BPPY_REQUIRE_VALID (self_bp); + + if (self_bp->bp->disposition == disp_del + || self_bp->bp->disposition == disp_del_at_next_stop) + Py_RETURN_TRUE; + + Py_RETURN_FALSE; +} + /* Python function to get the breakpoint's number. */ static PyObject * bppy_get_number (PyObject *self, void *closure) @@ -594,16 +611,20 @@ bppy_get_ignore_count (PyObject *self, void *closure) static int bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) { - static char *keywords[] = { "spec", "type", "wp_class", "internal", NULL }; + static char *keywords[] = { "spec", "type", "wp_class", "internal", + "temporary", NULL }; const char *spec; int type = bp_breakpoint; int access_type = hw_write; PyObject *internal = NULL; + PyObject *temporary = NULL; int internal_bp = 0; + int temporary_bp = 0; volatile struct gdb_exception except; - if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|iiO", keywords, - &spec, &type, &access_type, &internal)) + if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|iiOO", keywords, + &spec, &type, &access_type, + &internal, &temporary)) return -1; if (internal) @@ -613,6 +634,13 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) return -1; } + if (temporary != NULL) + { + temporary_bp = PyObject_IsTrue (temporary); + if (temporary_bp == -1) + return -1; + } + bppy_pending_object = (breakpoint_object *) self; bppy_pending_object->number = -1; bppy_pending_object->bp = NULL; @@ -629,7 +657,7 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) create_breakpoint (python_gdbarch, copy, NULL, -1, NULL, 0, - 0, bp_breakpoint, + temporary_bp, bp_breakpoint, 0, AUTO_BOOLEAN_TRUE, &bkpt_breakpoint_ops, @@ -973,6 +1001,8 @@ or None if no condition set."}, "Type of breakpoint."}, { "visible", bppy_get_visibility, NULL, "Whether the breakpoint is visible to the user."}, + { "temporary", bppy_get_temporary, NULL, + "Whether this breakpoint is a temporary breakpoint."}, { NULL } /* Sentinel. */ }; diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp index 687182d..e2a169b 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint.exp @@ -300,3 +300,37 @@ gdb_py_test_silent_cmd "python wp1 = wp_eval (\"result\", type=gdb.BP_WATCHPOIN gdb_test "continue" ".*\[Ww\]atchpoint.*result.*Old value =.*New value = 788.*" "Test watchpoint write" gdb_test "python print (never_eval_bp1.count)" "0" \ "Check that this unrelated breakpoints eval function was never called." + +# Test temporary breakpoint + +# Start with a fresh gdb. +clean_restart ${testfile} + +if ![runto_main] then { + fail "Cannot run to main." + return 0 +} +delete_breakpoints +gdb_py_test_multiple "Sub-class and check temporary breakpoint" \ + "python" "" \ + "class temp_bp (gdb.Breakpoint):" "" \ + " count = 0" "" \ + " def stop (self):" "" \ + " self.count = self.count + 1" "" \ + " return True" "" \ + "end" "" +gdb_py_test_silent_cmd "python ibp = temp_bp(\"$ibp_location\", temporary=True)" \ + "Set temporary breakpoint" 0 +gdb_test "info breakpoints" "2.*breakpoint.*del.*py-breakpoint\.c:$ibp_location.*" \ + "Check info breakpoints shows breakpoint with temporary status" +gdb_test "python print (ibp.location)" "py-breakpoint\.c:$ibp_location*" \ + "Check temporary breakpoint location" +gdb_test "python print (ibp.temporary)" "True" \ + "Check breakpoint temporary status" +gdb_continue_to_breakpoint "Break at multiply." ".*/$srcfile:$ibp_location.*" +gdb_test "python print (ibp.count)" "1" \ + "Check temporary stop callback executed before deletion." +gdb_test "python print (ibp.temporary)" "RuntimeError: Breakpoint 2 is invalid.*" \ + "Check temporary breakpoint is deleted after being hit" +gdb_test "info breakpoints" "No breakpoints or watchpoints.*" \ + "Check info breakpoints shows temporary breakpoint is deleted"