aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/dummy-frame.c41
-rw-r--r--gdb/dummy-frame.h13
3 files changed, 64 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0fc1035..d7f0c2d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2014-12-12 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * dummy-frame.c (struct dummy_frame) <dtor, dtor_data>: New
+ fields.
+ (pop_dummy_frame): Call the destructor if it exists.
+ (register_dummy_frame_dtor, find_dummy_frame_dtor): New
+ functions.
+ * dummy-frame.h (dummy_frame_dtor_ftype): New typedef.
+ (register_dummy_frame_dtor, find_dummy_frame_dtor): Declare.
+
2014-12-12 Tom Tromey <tromey@redhat.com>
* gdbtypes.h (make_unqualified_type): Declare.
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index a13601b..6ca8b19 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -61,6 +61,13 @@ struct dummy_frame
/* The caller's state prior to the call. */
struct infcall_suspend_state *caller_state;
+
+ /* If non-NULL, a destructor that is run when this dummy frame is
+ popped. */
+ void (*dtor) (void *data);
+
+ /* Arbitrary data that is passed to DTOR. */
+ void *dtor_data;
};
static struct dummy_frame *dummy_frame_stack = NULL;
@@ -127,6 +134,10 @@ pop_dummy_frame (struct dummy_frame **dummy_ptr)
struct dummy_frame *dummy = *dummy_ptr;
gdb_assert (ptid_equal (dummy->id.ptid, inferior_ptid));
+
+ if (dummy->dtor != NULL)
+ dummy->dtor (dummy->dtor_data);
+
restore_infcall_suspend_state (dummy->caller_state);
iterate_over_breakpoints (pop_dummy_frame_bpt, dummy);
@@ -190,6 +201,36 @@ dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid)
remove_dummy_frame (dp);
}
+/* See dummy-frame.h. */
+
+void
+register_dummy_frame_dtor (struct frame_id dummy_id, ptid_t ptid,
+ dummy_frame_dtor_ftype *dtor, void *dtor_data)
+{
+ struct dummy_frame_id id = { dummy_id, ptid };
+ struct dummy_frame **dp, *d;
+
+ dp = lookup_dummy_frame (&id);
+ gdb_assert (dp != NULL);
+ d = *dp;
+ gdb_assert (d->dtor == NULL);
+ d->dtor = dtor;
+ d->dtor_data = dtor_data;
+}
+
+/* See dummy-frame.h. */
+
+int
+find_dummy_frame_dtor (dummy_frame_dtor_ftype *dtor, void *dtor_data)
+{
+ struct dummy_frame *d;
+
+ for (d = dummy_frame_stack; d != NULL; d = d->next)
+ if (d->dtor == dtor && d->dtor_data == dtor_data)
+ return 1;
+ return 0;
+}
+
/* There may be stale dummy frames, perhaps left over from when an uncaught
longjmp took us out of a function that was called by the debugger. Clean
them up at least once whenever we start a new inferior. */
diff --git a/gdb/dummy-frame.h b/gdb/dummy-frame.h
index bac1aac..8c1a1d0 100644
--- a/gdb/dummy-frame.h
+++ b/gdb/dummy-frame.h
@@ -54,4 +54,17 @@ extern void dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid);
extern const struct frame_unwind dummy_frame_unwind;
+/* Call DTOR with DTOR_DATA when DUMMY_ID frame of thread PTID gets discarded.
+ Dummy frame with DUMMY_ID must exist. There must be no other call of
+ register_dummy_frame_dtor for that dummy frame. */
+typedef void (dummy_frame_dtor_ftype) (void *data);
+extern void register_dummy_frame_dtor (struct frame_id dummy_id, ptid_t ptid,
+ dummy_frame_dtor_ftype *dtor,
+ void *dtor_data);
+
+/* Return 1 if there exists dummy frame with registered DTOR and DTOR_DATA.
+ Return 0 otherwise. */
+extern int find_dummy_frame_dtor (dummy_frame_dtor_ftype *dtor,
+ void *dtor_data);
+
#endif /* !defined (DUMMY_FRAME_H) */