diff options
Diffstat (limited to 'gdb/python')
-rw-r--r-- | gdb/python/py-breakpoint.c | 3 | ||||
-rw-r--r-- | gdb/python/py-finishbreakpoint.c | 33 | ||||
-rw-r--r-- | gdb/python/python-internal.h | 1 |
3 files changed, 30 insertions, 7 deletions
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index ecf52a4..880f1b5 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -1199,6 +1199,9 @@ gdbpy_breakpoint_deleted (struct breakpoint *b) gdbpy_ref<gdbpy_breakpoint_object> bp_obj (bp->py_bp_object); if (bp_obj != NULL) { + if (bp_obj->is_finish_bp) + bpfinishpy_pre_delete_hook (bp_obj.get ()); + if (!evregpy_no_listeners_p (gdb_py_events.breakpoint_deleted)) { if (evpy_emit_event ((PyObject *) bp_obj.get (), diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c index 159164e..7122fa8 100644 --- a/gdb/python/py-finishbreakpoint.c +++ b/gdb/python/py-finishbreakpoint.c @@ -349,16 +349,19 @@ bpfinishpy_out_of_scope (struct finish_breakpoint_object *bpfinish_obj) if (meth_result == NULL) gdbpy_print_stack (); } - - delete_breakpoint (bpfinish_obj->py_bp.bp); } /* Callback for `bpfinishpy_detect_out_scope'. Triggers Python's - `B->out_of_scope' function if B is a FinishBreakpoint out of its scope. */ + `B->out_of_scope' function if B is a FinishBreakpoint out of its scope. + + When DELETE_BP is true then breakpoint B will be deleted if B is a + FinishBreakpoint and it is out of scope, otherwise B will not be + deleted. */ static void bpfinishpy_detect_out_scope_cb (struct breakpoint *b, - struct breakpoint *bp_stopped) + struct breakpoint *bp_stopped, + bool delete_bp) { PyObject *py_bp = (PyObject *) b->py_bp_object; @@ -379,7 +382,11 @@ bpfinishpy_detect_out_scope_cb (struct breakpoint *b, if (b->pspace == current_inferior ()->pspace && (!target_has_registers () || frame_find_by_id (initiating_frame) == NULL)) - bpfinishpy_out_of_scope (finish_bp); + { + bpfinishpy_out_of_scope (finish_bp); + if (delete_bp) + delete_breakpoint (finish_bp->py_bp.bp); + } } catch (const gdb_exception &except) { @@ -390,6 +397,17 @@ bpfinishpy_detect_out_scope_cb (struct breakpoint *b, } } +/* Called when gdbpy_breakpoint_deleted is about to delete a breakpoint. A + chance to trigger the out_of_scope callback (if appropriate) for the + associated Python object. */ + +void +bpfinishpy_pre_delete_hook (struct gdbpy_breakpoint_object *bp_obj) +{ + breakpoint *bp = bp_obj->bp; + bpfinishpy_detect_out_scope_cb (bp, nullptr, false); +} + /* Attached to `stop' notifications, check if the execution has run out of the scope of any FinishBreakpoint before it has been hit. */ @@ -399,7 +417,8 @@ bpfinishpy_handle_stop (struct bpstat *bs, int print_frame) gdbpy_enter enter_py; for (breakpoint *bp : all_breakpoints_safe ()) - bpfinishpy_detect_out_scope_cb (bp, bs == NULL ? NULL : bs->breakpoint_at); + bpfinishpy_detect_out_scope_cb + (bp, bs == NULL ? NULL : bs->breakpoint_at, true); } /* Attached to `exit' notifications, triggers all the necessary out of @@ -411,7 +430,7 @@ bpfinishpy_handle_exit (struct inferior *inf) gdbpy_enter enter_py (target_gdbarch ()); for (breakpoint *bp : all_breakpoints_safe ()) - bpfinishpy_detect_out_scope_cb (bp, nullptr); + bpfinishpy_detect_out_scope_cb (bp, nullptr, true); } /* Initialize the Python finish breakpoint code. */ diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 55bbe78..258f5c4 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -777,6 +777,7 @@ extern const struct value_print_options *gdbpy_current_print_options; void bpfinishpy_pre_stop_hook (struct gdbpy_breakpoint_object *bp_obj); void bpfinishpy_post_stop_hook (struct gdbpy_breakpoint_object *bp_obj); +void bpfinishpy_pre_delete_hook (struct gdbpy_breakpoint_object *bp_obj); extern PyObject *gdbpy_doc_cst; extern PyObject *gdbpy_children_cst; |