2013-11-07 Phil Muldoon <pmuldoon@redhat.com>

* python/py-breakpoint.c (bppy_get_temporary): New function.
	(bppy_init): New keyword: temporary. Parse it and set breakpoint
	to temporary if True.

2013-11-07  Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.python/py-breakpoint.exp: Add temporary breakpoint tests.

2013-11-07  Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.texinfo (Breakpoints In Python): Document temporary
	option in breakpoint constructor, and add documentation to the
	temporary attribute.
This commit is contained in:
Phil Muldoon
2013-11-07 12:04:45 +00:00
parent d52cd232cb
commit f76c27b5bd
7 changed files with 117 additions and 20 deletions

View File

@ -1,3 +1,10 @@
2013-11-07 Phil Muldoon <pmuldoon@redhat.com>
* NEWS: Document Python temporary breakpoint support.
* python/py-breakpoint.c (bppy_get_temporary): New function.
(bppy_init): New keyword: temporary. Parse it and set breakpoint
to temporary if True.
2013-11-07 Jose E. Marchesi <jose.marchesi@oracle.com> 2013-11-07 Jose E. Marchesi <jose.marchesi@oracle.com>
* sparc-tdep.c (sparc_analyze_control_transfer): Assertion * sparc-tdep.c (sparc_analyze_control_transfer): Assertion

View File

@ -35,6 +35,7 @@
* Python scripting * Python scripting
** Frame filters and frame decorators have been added. ** Frame filters and frame decorators have been added.
** Temporary breakpoints are now supported.
* New targets * New targets

View File

@ -1,3 +1,9 @@
2013-11-07 Phil Muldoon <pmuldoon@redhat.com>
* gdb.texinfo (Breakpoints In Python): Document temporary
option in breakpoint constructor, and add documentation to the
temporary attribute.
2013-11-07 Yao Qi <yao@codesourcery.com> 2013-11-07 Yao Qi <yao@codesourcery.com>
* gdb.texinfo (GDB/MI Variable Objects): Update doc about the * gdb.texinfo (GDB/MI Variable Objects): Update doc about the

View File

@ -27025,22 +27025,27 @@ Return the static block of the underlying symbol table.
Python code can manipulate breakpoints via the @code{gdb.Breakpoint} Python code can manipulate breakpoints via the @code{gdb.Breakpoint}
class. class.
@defun Breakpoint.__init__ (spec @r{[}, type @r{[}, wp_class @r{[},internal@r{]]]}) @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 Create a new breakpoint. @var{spec} is a string naming the location
location of the breakpoint, or an expression that defines a of the breakpoint, or an expression that defines a watchpoint. The
watchpoint. The contents can be any location recognized by the contents can be any location recognized by the @code{break} command,
@code{break} command, or in the case of a watchpoint, by the @code{watch} or in the case of a watchpoint, by the @code{watch} command. The
command. The optional @var{type} denotes the breakpoint to create optional @var{type} denotes the breakpoint to create from the types
from the types defined later in this chapter. This argument can be defined later in this chapter. This argument can be either:
either: @code{gdb.BP_BREAKPOINT} or @code{gdb.BP_WATCHPOINT}. @var{type} @code{gdb.BP_BREAKPOINT} or @code{gdb.BP_WATCHPOINT}. @var{type}
defaults to @code{gdb.BP_BREAKPOINT}. The optional @var{internal} argument defaults to @code{gdb.BP_BREAKPOINT}. The optional @var{internal}
allows the breakpoint to become invisible to the user. The breakpoint argument allows the breakpoint to become invisible to the user. The
will neither be reported when created, nor will it be listed in the breakpoint will neither be reported when created, nor will it be
output from @code{info breakpoints} (but will be listed with the listed in the output from @code{info breakpoints} (but will be listed
@code{maint info breakpoints} command). The optional @var{wp_class} with the @code{maint info breakpoints} command). The optional
argument defines the class of watchpoint to create, if @var{type} is @var{temporary} argument makes the breakpoint a temporary breakpoint.
@code{gdb.BP_WATCHPOINT}. If a watchpoint class is not provided, it is Temporary breakpoints are deleted after they have been hit. Any
assumed to be a @code{gdb.WP_WRITE} class. 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 @end defun
@defun Breakpoint.stop (self) @defun Breakpoint.stop (self)
@ -27161,6 +27166,16 @@ when set, or when the @samp{info breakpoints} command is run. This
attribute is not writable. attribute is not writable.
@end defvar @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} The available types are represented by constants defined in the @code{gdb}
module: module:

View File

@ -529,6 +529,23 @@ bppy_get_visibility (PyObject *self, void *closure)
Py_RETURN_TRUE; 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. */ /* Python function to get the breakpoint's number. */
static PyObject * static PyObject *
bppy_get_number (PyObject *self, void *closure) bppy_get_number (PyObject *self, void *closure)
@ -594,16 +611,20 @@ bppy_get_ignore_count (PyObject *self, void *closure)
static int static int
bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) 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; const char *spec;
int type = bp_breakpoint; int type = bp_breakpoint;
int access_type = hw_write; int access_type = hw_write;
PyObject *internal = NULL; PyObject *internal = NULL;
PyObject *temporary = NULL;
int internal_bp = 0; int internal_bp = 0;
int temporary_bp = 0;
volatile struct gdb_exception except; volatile struct gdb_exception except;
if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|iiO", keywords, if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|iiOO", keywords,
&spec, &type, &access_type, &internal)) &spec, &type, &access_type,
&internal, &temporary))
return -1; return -1;
if (internal) if (internal)
@ -613,6 +634,13 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
return -1; 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 = (breakpoint_object *) self;
bppy_pending_object->number = -1; bppy_pending_object->number = -1;
bppy_pending_object->bp = NULL; bppy_pending_object->bp = NULL;
@ -629,7 +657,7 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
create_breakpoint (python_gdbarch, create_breakpoint (python_gdbarch,
copy, NULL, -1, NULL, copy, NULL, -1, NULL,
0, 0,
0, bp_breakpoint, temporary_bp, bp_breakpoint,
0, 0,
AUTO_BOOLEAN_TRUE, AUTO_BOOLEAN_TRUE,
&bkpt_breakpoint_ops, &bkpt_breakpoint_ops,
@ -973,6 +1001,8 @@ or None if no condition set."},
"Type of breakpoint."}, "Type of breakpoint."},
{ "visible", bppy_get_visibility, NULL, { "visible", bppy_get_visibility, NULL,
"Whether the breakpoint is visible to the user."}, "Whether the breakpoint is visible to the user."},
{ "temporary", bppy_get_temporary, NULL,
"Whether this breakpoint is a temporary breakpoint."},
{ NULL } /* Sentinel. */ { NULL } /* Sentinel. */
}; };

View File

@ -1,3 +1,7 @@
2013-11-07 Phil Muldoon <pmuldoon@redhat.com>
* gdb.python/py-breakpoint.exp: Add temporary breakpoint tests.
2013-11-06 Doug Evans <dje@sebabeach.org> 2013-11-06 Doug Evans <dje@sebabeach.org>
* gdb.python/py-arch.exp: Tweak test name for bad memory access test. * gdb.python/py-arch.exp: Tweak test name for bad memory access test.

View File

@ -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 "continue" ".*\[Ww\]atchpoint.*result.*Old value =.*New value = 788.*" "Test watchpoint write"
gdb_test "python print (never_eval_bp1.count)" "0" \ gdb_test "python print (never_eval_bp1.count)" "0" \
"Check that this unrelated breakpoints eval function was never called." "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"