mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-05-31 18:20:12 +08:00
gdb/python: allow for catchpoint type breakpoints in python
This commit adds initial support for catchpoints to the python breakpoint API. This commit adds a BP_CATCHPOINT constant which corresponds to GDB's internal bp_catchpoint. The new constant is documented in the manual. The user can't create breakpoints with type BP_CATCHPOINT after this commit, but breakpoints that already exist, obtained with the `gdb.breakpoints` function, can now have this type. Additionally, when a stop event is reported for hitting a catchpoint, GDB will now report a BreakpointEvent with the attached breakpoint being of type BP_CATCHPOINT - previously GDB would report a generic StopEvent in this situation. gdb/ChangeLog: * NEWS: Mention Python BP_CATCHPOINT feature. * python/py-breakpoint.c (pybp_codes): Add bp_catchpoint support. (bppy_init): Likewise. (gdbpy_breakpoint_created): Likewise. gdb/doc/ChangeLog: * python.texinfo (Breakpoints In Python): Add BP_CATCHPOINT description. gdb/testsuite/ChangeLog: * gdb.python/py-breakpoint.c (do_throw): New function. (main): Call do_throw. * gdb.python/py-breakpoint.exp (test_catchpoints): New proc.
This commit is contained in:
@ -1,3 +1,10 @@
|
|||||||
|
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
|
* NEWS: Mention Python BP_CATCHPOINT feature.
|
||||||
|
* python/py-breakpoint.c (pybp_codes): Add bp_catchpoint support.
|
||||||
|
(bppy_init): Likewise.
|
||||||
|
(gdbpy_breakpoint_created): Likewise.
|
||||||
|
|
||||||
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
|
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* guile/scm-breakpoint.c (bpscm_type_to_string): Handle
|
* guile/scm-breakpoint.c (bpscm_type_to_string): Handle
|
||||||
|
4
gdb/NEWS
4
gdb/NEWS
@ -231,6 +231,10 @@ QMemTags
|
|||||||
** New method gdb.PendingFrame.level() which returns the stack level
|
** New method gdb.PendingFrame.level() which returns the stack level
|
||||||
of the frame object.
|
of the frame object.
|
||||||
|
|
||||||
|
** When hitting a catchpoint, the Python API will now emit a
|
||||||
|
gdb.BreakpointEvent rather than a gdb.StopEvent. The
|
||||||
|
gdb.Breakpoint attached to the event will have type BP_CATCHPOINT.
|
||||||
|
|
||||||
*** Changes in GDB 10
|
*** Changes in GDB 10
|
||||||
|
|
||||||
* There are new feature names for ARC targets: "org.gnu.gdb.arc.core"
|
* There are new feature names for ARC targets: "org.gnu.gdb.arc.core"
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
|
* python.texinfo (Breakpoints In Python): Add BP_CATCHPOINT
|
||||||
|
description.
|
||||||
|
|
||||||
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
|
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* guile.texinfo (Breakpoints In Guile): Add BP_CATCHPOINT
|
* guile.texinfo (Breakpoints In Guile): Add BP_CATCHPOINT
|
||||||
|
@ -5517,6 +5517,13 @@ Hardware assisted read watchpoint.
|
|||||||
@vindex BP_ACCESS_WATCHPOINT
|
@vindex BP_ACCESS_WATCHPOINT
|
||||||
@item gdb.BP_ACCESS_WATCHPOINT
|
@item gdb.BP_ACCESS_WATCHPOINT
|
||||||
Hardware assisted access watchpoint.
|
Hardware assisted access watchpoint.
|
||||||
|
|
||||||
|
@vindex BP_CATCHPOINT
|
||||||
|
@item gdb.BP_CATCHPOINT
|
||||||
|
Catchpoint. Currently, this type can't be used when creating
|
||||||
|
@code{gdb.Breakpoint} objects, but will be present in
|
||||||
|
@code{gdb.Breakpoint} objects reported from
|
||||||
|
@code{gdb.BreakpointEvent}s (@pxref{Events In Python}).
|
||||||
@end vtable
|
@end vtable
|
||||||
|
|
||||||
The available watchpoint types are represented by constants defined in the
|
The available watchpoint types are represented by constants defined in the
|
||||||
|
@ -86,6 +86,7 @@ static struct pybp_code pybp_codes[] =
|
|||||||
{ "BP_HARDWARE_WATCHPOINT", bp_hardware_watchpoint},
|
{ "BP_HARDWARE_WATCHPOINT", bp_hardware_watchpoint},
|
||||||
{ "BP_READ_WATCHPOINT", bp_read_watchpoint},
|
{ "BP_READ_WATCHPOINT", bp_read_watchpoint},
|
||||||
{ "BP_ACCESS_WATCHPOINT", bp_access_watchpoint},
|
{ "BP_ACCESS_WATCHPOINT", bp_access_watchpoint},
|
||||||
|
{ "BP_CATCHPOINT", bp_catchpoint},
|
||||||
{NULL} /* Sentinel. */
|
{NULL} /* Sentinel. */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -883,6 +884,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
|||||||
error(_("Cannot understand watchpoint access type."));
|
error(_("Cannot understand watchpoint access type."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case bp_catchpoint:
|
||||||
|
error (_("BP_CATCHPOINT not supported"));
|
||||||
default:
|
default:
|
||||||
error(_("Do not understand breakpoint type to set."));
|
error(_("Do not understand breakpoint type to set."));
|
||||||
}
|
}
|
||||||
@ -1038,7 +1041,8 @@ gdbpy_breakpoint_created (struct breakpoint *bp)
|
|||||||
&& bp->type != bp_watchpoint
|
&& bp->type != bp_watchpoint
|
||||||
&& bp->type != bp_hardware_watchpoint
|
&& bp->type != bp_hardware_watchpoint
|
||||||
&& bp->type != bp_read_watchpoint
|
&& bp->type != bp_read_watchpoint
|
||||||
&& bp->type != bp_access_watchpoint)
|
&& bp->type != bp_access_watchpoint
|
||||||
|
&& bp->type != bp_catchpoint)
|
||||||
{
|
{
|
||||||
pybp_debug_printf ("is not a breakpoint or watchpoint");
|
pybp_debug_printf ("is not a breakpoint or watchpoint");
|
||||||
return;
|
return;
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
|
* gdb.python/py-breakpoint.c (do_throw): New function.
|
||||||
|
(main): Call do_throw.
|
||||||
|
* gdb.python/py-breakpoint.exp (test_catchpoints): New proc.
|
||||||
|
|
||||||
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
|
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* gdb.guile/scm-breakpoint.exp (test_catchpoints): New proc.
|
* gdb.guile/scm-breakpoint.exp (test_catchpoints): New proc.
|
||||||
|
@ -39,6 +39,11 @@ int add (int i)
|
|||||||
return i + i; /* Break at function add. */
|
return i + i; /* Break at function add. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
do_throw ()
|
||||||
|
{
|
||||||
|
throw 123;
|
||||||
|
}
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -46,6 +51,15 @@ int main (int argc, char *argv[])
|
|||||||
int bar = 42;
|
int bar = 42;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
do_throw ();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
/* Nothing. */
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
result += multiply (foo); /* Break at multiply. */
|
result += multiply (foo); /* Break at multiply. */
|
||||||
|
@ -737,11 +737,71 @@ proc_with_prefix test_bkpt_probe {} {
|
|||||||
"-probe in spec string"
|
"-probe in spec string"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc_with_prefix test_catchpoints {} {
|
||||||
|
global srcfile testfile
|
||||||
|
global gdb_prompt decimal
|
||||||
|
|
||||||
|
# Start with a fresh gdb.
|
||||||
|
clean_restart ${testfile}
|
||||||
|
|
||||||
|
if ![runto_main] then {
|
||||||
|
fail "cannot run to main."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try to create a catchpoint, currently this isn't supported via
|
||||||
|
# the python api.
|
||||||
|
gdb_test "python gdb.Breakpoint (\"syscall\", type=gdb.BP_CATCHPOINT)" \
|
||||||
|
[multi_line \
|
||||||
|
"gdb.error: BP_CATCHPOINT not supported" \
|
||||||
|
"Error while executing Python code\\."] \
|
||||||
|
"create a catchpoint via the api"
|
||||||
|
|
||||||
|
# Setup a catchpoint.
|
||||||
|
set num "XXX"
|
||||||
|
gdb_test_multiple "catch throw" "" {
|
||||||
|
-re "The feature \'catch throw\' is not supported.*\r\n$gdb_prompt $" {
|
||||||
|
unsupported "catch syscall isn't supported"
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
-re "Catchpoint ($decimal) \\(throw\\)\r\n$gdb_prompt $" {
|
||||||
|
set num $expect_out(1,string)
|
||||||
|
pass $gdb_test_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Look for the catchpoint in the breakpoint list.
|
||||||
|
gdb_test_multiline "scan breakpoint list for BP_CATCHPOINT" \
|
||||||
|
"python" "" \
|
||||||
|
"def scan_bp_list ():" "" \
|
||||||
|
" for b in gdb.breakpoints():" "" \
|
||||||
|
" if b.type == gdb.BP_CATCHPOINT:" "" \
|
||||||
|
" print(\"breakpoint #%d, type BP_CATCHPOINT\" % b.number)" "" \
|
||||||
|
"end" ""
|
||||||
|
gdb_test "python scan_bp_list ()" \
|
||||||
|
"breakpoint #${num}, type BP_CATCHPOINT" \
|
||||||
|
"scan breakpoint for BP_CATCHPOINT"
|
||||||
|
|
||||||
|
# Arrange to print something when GDB stops, then continue to the
|
||||||
|
# catchpoint and check we get the expected event.
|
||||||
|
gdb_test_multiline "setup stop event handler" \
|
||||||
|
"python" "" \
|
||||||
|
"def stop_handler (event):" "" \
|
||||||
|
" if (isinstance (event, gdb.BreakpointEvent)" "" \
|
||||||
|
" and isinstance (event.breakpoint, gdb.Breakpoint)" "" \
|
||||||
|
" and event.breakpoint.type == gdb.BP_CATCHPOINT):" "" \
|
||||||
|
" print (\"Stopped at catchpoint event: %d\" % event.breakpoint.number)" "" \
|
||||||
|
"end" "" \
|
||||||
|
"python gdb.events.stop.connect (stop_handler)" ""
|
||||||
|
gdb_test "continue" "Stopped at catchpoint event: ${num}"
|
||||||
|
}
|
||||||
|
|
||||||
test_bkpt_basic
|
test_bkpt_basic
|
||||||
test_bkpt_deletion
|
test_bkpt_deletion
|
||||||
test_bkpt_cond_and_cmds
|
test_bkpt_cond_and_cmds
|
||||||
test_bkpt_invisible
|
test_bkpt_invisible
|
||||||
test_hardware_breakpoints
|
test_hardware_breakpoints
|
||||||
|
test_catchpoints
|
||||||
test_watchpoints
|
test_watchpoints
|
||||||
test_bkpt_internal
|
test_bkpt_internal
|
||||||
test_bkpt_eval_funcs
|
test_bkpt_eval_funcs
|
||||||
|
Reference in New Issue
Block a user