add dummy frame destructor
authorJan Kratochvil <jan.kratochvil@redhat.com>
Wed, 14 May 2014 20:01:24 +0000 (14:01 -0600)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 12 Dec 2014 21:25:15 +0000 (22:25 +0100)
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.

gdb/ChangeLog
gdb/dummy-frame.c
gdb/dummy-frame.h

index 0fc1035f3ba9392bb647665bdde0913a3cf13422..d7f0c2d16941f4380bf4e452a1928a47f826dbd5 100644 (file)
@@ -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.
index a13601bddb983fb6afb31678ebdba616a8033662..6ca8b19168c72aa9a04f856653b793aa642506ef 100644 (file)
@@ -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.  */
index bac1aac9b07be95f7627aa24f31acf648fa22c79..8c1a1d031543fce885c678dae55a99a1347f352e 100644 (file)
@@ -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)  */