OLD | NEW |
1 /* Code dealing with dummy stack frames, for GDB, the GNU debugger. | 1 /* Code dealing with dummy stack frames, for GDB, the GNU debugger. |
2 | 2 |
3 Copyright (C) 1986-2004, 2007-2012 Free Software Foundation, Inc. | 3 Copyright (C) 1986-2004, 2007-2012 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of GDB. | 5 This file is part of GDB. |
6 | 6 |
7 This program is free software; you can redistribute it and/or modify | 7 This program is free software; you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation; either version 3 of the License, or | 9 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "dummy-frame.h" | 22 #include "dummy-frame.h" |
23 #include "regcache.h" | 23 #include "regcache.h" |
24 #include "frame.h" | 24 #include "frame.h" |
25 #include "inferior.h" | 25 #include "inferior.h" |
26 #include "gdb_assert.h" | 26 #include "gdb_assert.h" |
27 #include "frame-unwind.h" | 27 #include "frame-unwind.h" |
28 #include "command.h" | 28 #include "command.h" |
29 #include "gdbcmd.h" | 29 #include "gdbcmd.h" |
30 #include "gdb_string.h" | 30 #include "gdb_string.h" |
31 #include "observer.h" | 31 #include "observer.h" |
| 32 #include "gdbthread.h" |
32 | 33 |
33 /* Dummy frame. This saves the processor state just prior to setting | 34 /* Dummy frame. This saves the processor state just prior to setting |
34 up the inferior function call. Older targets save the registers | 35 up the inferior function call. Older targets save the registers |
35 on the target stack (but that really slows down function calls). */ | 36 on the target stack (but that really slows down function calls). */ |
36 | 37 |
37 struct dummy_frame | 38 struct dummy_frame |
38 { | 39 { |
39 struct dummy_frame *next; | 40 struct dummy_frame *next; |
40 /* This frame's ID. Must match the value returned by | 41 /* This frame's ID. Must match the value returned by |
41 gdbarch_dummy_id. */ | 42 gdbarch_dummy_id. */ |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 static void | 102 static void |
102 remove_dummy_frame (struct dummy_frame **dummy_ptr) | 103 remove_dummy_frame (struct dummy_frame **dummy_ptr) |
103 { | 104 { |
104 struct dummy_frame *dummy = *dummy_ptr; | 105 struct dummy_frame *dummy = *dummy_ptr; |
105 | 106 |
106 *dummy_ptr = dummy->next; | 107 *dummy_ptr = dummy->next; |
107 discard_infcall_suspend_state (dummy->caller_state); | 108 discard_infcall_suspend_state (dummy->caller_state); |
108 xfree (dummy); | 109 xfree (dummy); |
109 } | 110 } |
110 | 111 |
| 112 /* Delete any breakpoint B which is a momentary breakpoint for return from |
| 113 inferior call matching DUMMY_VOIDP. */ |
| 114 |
| 115 static int |
| 116 pop_dummy_frame_bpt (struct breakpoint *b, void *dummy_voidp) |
| 117 { |
| 118 struct dummy_frame *dummy = dummy_voidp; |
| 119 |
| 120 if (b->thread == pid_to_thread_id (inferior_ptid) |
| 121 && b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id)) |
| 122 { |
| 123 while (b->related_breakpoint != b) |
| 124 delete_breakpoint (b->related_breakpoint); |
| 125 |
| 126 delete_breakpoint (b); |
| 127 |
| 128 /* Stop the traversal. */ |
| 129 return 1; |
| 130 } |
| 131 |
| 132 /* Continue the traversal. */ |
| 133 return 0; |
| 134 } |
| 135 |
111 /* Pop *DUMMY_PTR, restoring program state to that before the | 136 /* Pop *DUMMY_PTR, restoring program state to that before the |
112 frame was created. */ | 137 frame was created. */ |
113 | 138 |
114 static void | 139 static void |
115 pop_dummy_frame (struct dummy_frame **dummy_ptr) | 140 pop_dummy_frame (struct dummy_frame **dummy_ptr) |
116 { | 141 { |
117 struct dummy_frame *dummy; | 142 struct dummy_frame *dummy = *dummy_ptr; |
118 | 143 |
119 restore_infcall_suspend_state ((*dummy_ptr)->caller_state); | 144 restore_infcall_suspend_state (dummy->caller_state); |
| 145 |
| 146 iterate_over_breakpoints (pop_dummy_frame_bpt, dummy); |
120 | 147 |
121 /* restore_infcall_control_state frees inf_state, | 148 /* restore_infcall_control_state frees inf_state, |
122 all that remains is to pop *dummy_ptr. */ | 149 all that remains is to pop *dummy_ptr. */ |
123 dummy = *dummy_ptr; | |
124 *dummy_ptr = dummy->next; | 150 *dummy_ptr = dummy->next; |
125 xfree (dummy); | 151 xfree (dummy); |
126 | 152 |
127 /* We've made right mess of GDB's local state, just discard | 153 /* We've made right mess of GDB's local state, just discard |
128 everything. */ | 154 everything. */ |
129 reinit_frame_cache (); | 155 reinit_frame_cache (); |
130 } | 156 } |
131 | 157 |
132 /* Look up DUMMY_ID. | 158 /* Look up DUMMY_ID. |
133 Return NULL if not found. */ | 159 Return NULL if not found. */ |
(...skipping 25 matching lines...) Expand all Loading... |
159 dummy_frame_pop (struct frame_id dummy_id) | 185 dummy_frame_pop (struct frame_id dummy_id) |
160 { | 186 { |
161 struct dummy_frame **dp; | 187 struct dummy_frame **dp; |
162 | 188 |
163 dp = lookup_dummy_frame (dummy_id); | 189 dp = lookup_dummy_frame (dummy_id); |
164 gdb_assert (dp != NULL); | 190 gdb_assert (dp != NULL); |
165 | 191 |
166 pop_dummy_frame (dp); | 192 pop_dummy_frame (dp); |
167 } | 193 } |
168 | 194 |
169 /* There may be stale dummy frames, perhaps left over from when a longjump took | 195 /* Drop dummy frame DUMMY_ID. Do nothing if it is not found. Do not restore |
170 us out of a function that was called by the debugger. Clean them up at | 196 its state into inferior, just free its memory. */ |
171 least once whenever we start a new inferior. */ | 197 |
| 198 void |
| 199 dummy_frame_discard (struct frame_id dummy_id) |
| 200 { |
| 201 struct dummy_frame **dp; |
| 202 |
| 203 dp = lookup_dummy_frame (dummy_id); |
| 204 if (dp) |
| 205 remove_dummy_frame (dp); |
| 206 } |
| 207 |
| 208 /* There may be stale dummy frames, perhaps left over from when an uncaught |
| 209 longjmp took us out of a function that was called by the debugger. Clean |
| 210 them up at least once whenever we start a new inferior. */ |
172 | 211 |
173 static void | 212 static void |
174 cleanup_dummy_frames (struct target_ops *target, int from_tty) | 213 cleanup_dummy_frames (struct target_ops *target, int from_tty) |
175 { | 214 { |
176 while (dummy_frame_stack != NULL) | 215 while (dummy_frame_stack != NULL) |
177 remove_dummy_frame (&dummy_frame_stack); | 216 remove_dummy_frame (&dummy_frame_stack); |
178 } | 217 } |
179 | 218 |
180 /* Return the dummy frame cache, it contains both the ID, and a | 219 /* Return the dummy frame cache, it contains both the ID, and a |
181 pointer to the regcache. */ | 220 pointer to the regcache. */ |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 | 359 |
321 void | 360 void |
322 _initialize_dummy_frame (void) | 361 _initialize_dummy_frame (void) |
323 { | 362 { |
324 add_cmd ("dummy-frames", class_maintenance, maintenance_print_dummy_frames, | 363 add_cmd ("dummy-frames", class_maintenance, maintenance_print_dummy_frames, |
325 _("Print the contents of the internal dummy-frame stack."), | 364 _("Print the contents of the internal dummy-frame stack."), |
326 &maintenanceprintlist); | 365 &maintenanceprintlist); |
327 | 366 |
328 observer_attach_inferior_created (cleanup_dummy_frames); | 367 observer_attach_inferior_created (cleanup_dummy_frames); |
329 } | 368 } |
OLD | NEW |