Add on_retract breakpoint callback
diff --git a/breakpoint.h b/breakpoint.h
index 50a1e14..0398072 100644
--- a/breakpoint.h
+++ b/breakpoint.h
@@ -48,6 +48,7 @@
struct bp_callbacks {
void (*on_hit)(struct breakpoint *bp, struct Process *proc);
void (*on_continue)(struct breakpoint *bp, struct Process *proc);
+ void (*on_retract)(struct breakpoint *bp, struct Process *proc);
};
struct breakpoint {
@@ -66,6 +67,15 @@
* continue_after_breakpoint. */
void breakpoint_on_continue(struct breakpoint *bp, struct Process *proc);
+/* Call on-retract handler of BP, if any is set. This should be
+ * called before the breakpoints are destroyed. The reason for a
+ * separate interface is that breakpoint_destroy has to be callable
+ * without PROC. ON_DISABLE might be useful as well, but that would
+ * be called every time we disable the breakpoint, which is too often
+ * (a breakpoint has to be disabled every time that we need to execute
+ * the instruction underneath it). */
+void breakpoint_on_retract(struct breakpoint *bp, struct Process *proc);
+
/* Initialize a breakpoint structure. That doesn't actually realize
* the breakpoint. The breakpoint is initially assumed to be
* disabled. orig_value has to be set separately. CBS may be
diff --git a/breakpoints.c b/breakpoints.c
index 1154011..85d228f 100644
--- a/breakpoints.c
+++ b/breakpoints.c
@@ -43,6 +43,14 @@
continue_after_breakpoint(proc, bp);
}
+void
+breakpoint_on_retract(struct breakpoint *bp, struct Process *proc)
+{
+ assert(bp != NULL);
+ if (bp->cbs != NULL && bp->cbs->on_retract != NULL)
+ (bp->cbs->on_retract)(bp, proc);
+}
+
/*****************************************************************************/
struct breakpoint *
diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c
index 809714f..5ad82cd 100644
--- a/sysdeps/linux-gnu/trace.c
+++ b/sysdeps/linux-gnu/trace.c
@@ -423,11 +423,19 @@
return CBS_CONT;
}
+static enum callback_status
+retract_breakpoint_cb(struct Process *proc, struct breakpoint *bp, void *data)
+{
+ breakpoint_on_retract(bp, proc);
+ return CBS_CONT;
+}
+
static void
detach_process(Process * leader)
{
each_qd_event(&undo_breakpoint, leader);
disable_all_breakpoints(leader);
+ proc_each_breakpoint(leader, NULL, retract_breakpoint_cb, NULL);
/* Now untrace the process, if it was attached to by -p. */
struct opt_p_t * it;