aboutsummaryrefslogtreecommitdiff
path: root/gdb/dummy-frame.c
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2014-05-14 14:01:24 -0600
committerJan Kratochvil <jan.kratochvil@redhat.com>2014-12-12 22:25:15 +0100
commit233a8fb382c88d7faa6da1cd93a7e21b77e36df4 (patch)
treea4a8a2bba3dafe8a4a964b7c342465dc1b69fb6a /gdb/dummy-frame.c
parentf1660027106d583c639c9f37096519944d5c20e9 (diff)
downloadfsf-binutils-gdb-233a8fb382c88d7faa6da1cd93a7e21b77e36df4.zip
fsf-binutils-gdb-233a8fb382c88d7faa6da1cd93a7e21b77e36df4.tar.gz
fsf-binutils-gdb-233a8fb382c88d7faa6da1cd93a7e21b77e36df4.tar.bz2
add dummy frame destructor
The compiler code needed a hook into dummy frame destruction, so that some state could be kept while the inferior call is made and then destroyed when the inferior call finishes. This patch adds an optional destructor to dummy frames and a new API to access it. gdb/ChangeLog 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.
Diffstat (limited to 'gdb/dummy-frame.c')
-rw-r--r--gdb/dummy-frame.c41
1 files changed, 41 insertions, 0 deletions
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. */