aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-breakpoint.c3
-rw-r--r--gdb/python/py-finishbreakpoint.c33
-rw-r--r--gdb/python/python-internal.h1
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;