diff options
Diffstat (limited to 'gdb/dummy-frame.c')
-rw-r--r-- | gdb/dummy-frame.c | 72 |
1 files changed, 48 insertions, 24 deletions
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c index dd2ff12..35d78e9 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -31,6 +31,25 @@ #include "observer.h" #include "gdbthread.h" +struct dummy_frame_id +{ + /* This frame's ID. Must match the value returned by + gdbarch_dummy_id. */ + struct frame_id id; + + /* The thread this dummy_frame relates to. */ + ptid_t ptid; +}; + +/* Return whether dummy_frame_id *ID1 and *ID2 are equal. */ + +static int +dummy_frame_id_eq (struct dummy_frame_id *id1, + struct dummy_frame_id *id2) +{ + return frame_id_eq (id1->id, id2->id) && ptid_equal (id1->ptid, id2->ptid); +} + /* Dummy frame. This saves the processor state just prior to setting up the inferior function call. Older targets save the registers on the target stack (but that really slows down function calls). */ @@ -38,9 +57,10 @@ struct dummy_frame { struct dummy_frame *next; - /* This frame's ID. Must match the value returned by - gdbarch_dummy_id. */ - struct frame_id id; + + /* An id represents a dummy frame. */ + struct dummy_frame_id id; + /* The caller's state prior to the call. */ struct infcall_suspend_state *caller_state; }; @@ -52,13 +72,14 @@ static struct dummy_frame *dummy_frame_stack = NULL; void dummy_frame_push (struct infcall_suspend_state *caller_state, - const struct frame_id *dummy_id) + const struct frame_id *dummy_id, ptid_t ptid) { struct dummy_frame *dummy_frame; dummy_frame = XCNEW (struct dummy_frame); dummy_frame->caller_state = caller_state; - dummy_frame->id = (*dummy_id); + dummy_frame->id.id = (*dummy_id); + dummy_frame->id.ptid = ptid; dummy_frame->next = dummy_frame_stack; dummy_frame_stack = dummy_frame; } @@ -83,8 +104,8 @@ pop_dummy_frame_bpt (struct breakpoint *b, void *dummy_voidp) { struct dummy_frame *dummy = dummy_voidp; - if (b->thread == pid_to_thread_id (inferior_ptid) - && b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id)) + if (b->thread == pid_to_thread_id (dummy->id.ptid) + && b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id.id)) { while (b->related_breakpoint != b) delete_breakpoint (b->related_breakpoint); @@ -107,6 +128,7 @@ pop_dummy_frame (struct dummy_frame **dummy_ptr) { struct dummy_frame *dummy = *dummy_ptr; + gdb_assert (ptid_equal (dummy->id.ptid, inferior_ptid)); restore_infcall_suspend_state (dummy->caller_state); iterate_over_breakpoints (pop_dummy_frame_bpt, dummy); @@ -125,48 +147,47 @@ pop_dummy_frame (struct dummy_frame **dummy_ptr) Return NULL if not found. */ static struct dummy_frame ** -lookup_dummy_frame (struct frame_id dummy_id) +lookup_dummy_frame (struct dummy_frame_id *dummy_id) { struct dummy_frame **dp; for (dp = &dummy_frame_stack; *dp != NULL; dp = &(*dp)->next) { - if (frame_id_eq ((*dp)->id, dummy_id)) + if (dummy_frame_id_eq (&(*dp)->id, dummy_id)) return dp; } return NULL; } -/* Pop the dummy frame DUMMY_ID, restoring program state to that before the - frame was created. +/* Find the dummy frame by DUMMY_ID and PTID, and pop it, restoring + program state to that before the frame was created. On return reinit_frame_cache has been called. - If the frame isn't found, flag an internal error. - - NOTE: This can only pop the one frame, even if it is in the middle of the - stack, because the other frames may be for different threads, and there's - currently no way to tell which stack frame is for which thread. */ + If the frame isn't found, flag an internal error. */ void -dummy_frame_pop (struct frame_id dummy_id) +dummy_frame_pop (struct frame_id dummy_id, ptid_t ptid) { struct dummy_frame **dp; + struct dummy_frame_id id = { dummy_id, ptid }; - dp = lookup_dummy_frame (dummy_id); + dp = lookup_dummy_frame (&id); gdb_assert (dp != NULL); pop_dummy_frame (dp); } -/* Drop dummy frame DUMMY_ID. Do nothing if it is not found. Do not restore - its state into inferior, just free its memory. */ +/* Find the dummy frame by DUMMY_ID and PTID and drop it. Do nothing + if it is not found. Do not restore its state into inferior, just + free its memory. */ void -dummy_frame_discard (struct frame_id dummy_id) +dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid) { struct dummy_frame **dp; + struct dummy_frame_id id = { dummy_id, ptid }; - dp = lookup_dummy_frame (dummy_id); + dp = lookup_dummy_frame (&id); if (dp) remove_dummy_frame (dp); } @@ -211,13 +232,14 @@ dummy_frame_sniffer (const struct frame_unwind *self, dummy ID, assuming it is a dummy frame. */ struct frame_id this_id = gdbarch_dummy_id (get_frame_arch (this_frame), this_frame); + struct dummy_frame_id dummy_id = { this_id, inferior_ptid }; /* Use that ID to find the corresponding cache entry. */ for (dummyframe = dummy_frame_stack; dummyframe != NULL; dummyframe = dummyframe->next) { - if (frame_id_eq (dummyframe->id, this_id)) + if (dummy_frame_id_eq (&dummyframe->id, &dummy_id)) { struct dummy_frame_cache *cache; @@ -297,7 +319,9 @@ fprint_dummy_frames (struct ui_file *file) gdb_print_host_address (s, file); fprintf_unfiltered (file, ":"); fprintf_unfiltered (file, " id="); - fprint_frame_id (file, s->id); + fprint_frame_id (file, s->id.id); + fprintf_unfiltered (file, ", ptid=%s", + target_pid_to_str (s->id.ptid)); fprintf_unfiltered (file, "\n"); } } |