From: Andrew Burgess Date: Wed, 5 May 2021 14:26:28 +0000 (+0100) Subject: gdb/python: allow for catchpoint type breakpoints in python X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6b95f5ad9684530960eb828c76755a7b27a44e43;p=binutils-gdb.git 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b610f75d226..5045e713a64 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2021-06-25 Andrew Burgess + + * 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 * guile/scm-breakpoint.c (bpscm_type_to_string): Handle diff --git a/gdb/NEWS b/gdb/NEWS index 151c4f113fb..aae3b49b408 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -231,6 +231,10 @@ QMemTags ** New method gdb.PendingFrame.level() which returns the stack level 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 * There are new feature names for ARC targets: "org.gnu.gdb.arc.core" diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 1f197838a59..fc16fc5f2a7 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2021-06-25 Andrew Burgess + + * python.texinfo (Breakpoints In Python): Add BP_CATCHPOINT + description. + 2021-06-25 Andrew Burgess * guile.texinfo (Breakpoints In Guile): Add BP_CATCHPOINT diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 01a2e8b7974..f4865b3d6a6 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -5517,6 +5517,13 @@ Hardware assisted read watchpoint. @vindex BP_ACCESS_WATCHPOINT @item gdb.BP_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 The available watchpoint types are represented by constants defined in the diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index a2ce4cdd06f..edff03282a1 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -86,6 +86,7 @@ static struct pybp_code pybp_codes[] = { "BP_HARDWARE_WATCHPOINT", bp_hardware_watchpoint}, { "BP_READ_WATCHPOINT", bp_read_watchpoint}, { "BP_ACCESS_WATCHPOINT", bp_access_watchpoint}, + { "BP_CATCHPOINT", bp_catchpoint}, {NULL} /* Sentinel. */ }; @@ -883,6 +884,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) error(_("Cannot understand watchpoint access type.")); break; } + case bp_catchpoint: + error (_("BP_CATCHPOINT not supported")); default: 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_hardware_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"); return; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 30db2611d1e..567c1342870 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2021-06-25 Andrew Burgess + + * 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 * gdb.guile/scm-breakpoint.exp (test_catchpoints): New proc. diff --git a/gdb/testsuite/gdb.python/py-breakpoint.c b/gdb/testsuite/gdb.python/py-breakpoint.c index 830e4c29fae..dca668d6c22 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.c +++ b/gdb/testsuite/gdb.python/py-breakpoint.c @@ -39,6 +39,11 @@ int add (int i) return i + i; /* Break at function add. */ } +void +do_throw () +{ + throw 123; +} int main (int argc, char *argv[]) { @@ -46,6 +51,15 @@ int main (int argc, char *argv[]) int bar = 42; int i; + try + { + do_throw (); + } + catch (...) + { + /* Nothing. */ + } + for (i = 0; i < 10; i++) { result += multiply (foo); /* Break at multiply. */ diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp index 64a70abb126..d8fb85b784c 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint.exp @@ -737,11 +737,71 @@ proc_with_prefix test_bkpt_probe {} { "-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_deletion test_bkpt_cond_and_cmds test_bkpt_invisible test_hardware_breakpoints +test_catchpoints test_watchpoints test_bkpt_internal test_bkpt_eval_funcs