]>
Commit | Line | Data |
---|---|---|
3a58abaf AM |
1 | infcall.c <unwind_on_signal_p>: |
2 | Revert the change of: gdb-6.8-inlining.patch | |
3 | causing: FAIL: gdb.base/unwindonsignal.exp: unwindonsignal, stack unwound | |
4 | ||
5 | resume() -> target_resume() move of clear_inline_frame_state() is for: | |
6 | gdb.mi/mi-nsmoribund.exp | |
7 | ||
7566401a | 8 | Index: gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-bt.c |
3a58abaf | 9 | =================================================================== |
7566401a ER |
10 | --- gdb-6.8.91.20090917.orig/gdb/testsuite/gdb.opt/inline-bt.c 2009-06-28 02:20:24.000000000 +0200 |
11 | +++ gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-bt.c 2009-09-17 12:49:01.000000000 +0200 | |
3a58abaf AM |
12 | @@ -13,10 +13,16 @@ |
13 | You should have received a copy of the GNU General Public License | |
14 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
15 | ||
16 | -int x, y; | |
17 | +/* VOLATILE forces all the inlining to happen as otherwise the whole program | |
18 | + gets optimized by CSE to just simple assignments of the results. */ | |
19 | +volatile int x, y; | |
20 | volatile int result; | |
21 | ||
22 | -void bar(void); | |
23 | +inline void bar(void) | |
24 | +{ | |
25 | + x += y; /* set breakpoint 1 here */ | |
26 | +} | |
27 | + | |
28 | ||
29 | inline int func1(void) | |
30 | { | |
7566401a | 31 | Index: gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-cmds.c |
3a58abaf | 32 | =================================================================== |
7566401a ER |
33 | --- gdb-6.8.91.20090917.orig/gdb/testsuite/gdb.opt/inline-cmds.c 2009-06-28 02:20:24.000000000 +0200 |
34 | +++ gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-cmds.c 2009-09-17 12:49:01.000000000 +0200 | |
3a58abaf AM |
35 | @@ -13,13 +13,19 @@ |
36 | You should have received a copy of the GNU General Public License | |
37 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
38 | ||
39 | -int x, y; | |
40 | +/* VOLATILE forces all the inlining to happen as otherwise the whole program | |
41 | + gets optimized by CSE to just simple assignments of the results. */ | |
42 | +volatile int x, y; | |
43 | volatile int result; | |
44 | ||
45 | -void bar(void); | |
46 | void marker(void); | |
47 | void noinline(void); | |
48 | ||
49 | +inline void bar(void) | |
50 | +{ | |
51 | + x += y; /* set breakpoint 1 here */ | |
52 | +} | |
53 | + | |
54 | inline int func1(void) | |
55 | { | |
56 | bar (); | |
7566401a | 57 | Index: gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-cmds.exp |
3a58abaf | 58 | =================================================================== |
7566401a ER |
59 | --- gdb-6.8.91.20090917.orig/gdb/testsuite/gdb.opt/inline-cmds.exp 2009-06-28 02:20:24.000000000 +0200 |
60 | +++ gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-cmds.exp 2009-09-17 12:49:01.000000000 +0200 | |
61 | @@ -230,7 +230,7 @@ set line3 [gdb_get_line_number "set brea | |
3a58abaf AM |
62 | gdb_breakpoint $line3 |
63 | gdb_continue_to_breakpoint "consecutive func1" | |
64 | ||
65 | -gdb_test "next" ".*func1 .*first call.*" "next to first func1" | |
66 | +gdb_test "next" "func1 .*first call.*" "next to first func1" | |
67 | set msg "next to second func1" | |
68 | gdb_test_multiple "next" $msg { | |
69 | -re ".*func1 .*second call.*$gdb_prompt $" { | |
7566401a | 70 | @@ -253,16 +253,16 @@ set line4 [gdb_get_line_number "set brea |
3a58abaf AM |
71 | gdb_breakpoint $line4 |
72 | gdb_continue_to_breakpoint "func1 then func3" | |
73 | ||
74 | -gdb_test "next" ".*func1 \\\(\\\);" "next to func1 before func3" | |
75 | -gdb_test "next" ".*func3 \\\(\\\);" "next to func3" | |
76 | +gdb_test "next" "func1 \\\(\\\);" "next to func1 before func3" | |
77 | +gdb_test "next" "func3 \\\(\\\);" "next to func3" | |
78 | ||
79 | # Test finishing out of one thing and into another. | |
80 | set line5 [gdb_get_line_number "set breakpoint 5 here"] | |
81 | gdb_breakpoint $line5 | |
82 | gdb_continue_to_breakpoint "finish into func1" | |
83 | ||
84 | -gdb_test "next" ".*marker \\\(\\\);" "next to finish marker" | |
85 | -gdb_test "step" ".*set breakpoint 2 here.*" "step into finish marker" | |
86 | +gdb_test "next" "marker \\\(\\\);" "next to finish marker" | |
87 | +gdb_test "step" "set breakpoint 2 here.*" "step into finish marker" | |
88 | gdb_test "finish" "func1 \\\(\\\);" "finish from marker to func1" | |
89 | ||
90 | gdb_test "step" "bar \\\(\\\);" "step into func1 for finish" | |
7566401a | 91 | @@ -297,12 +297,12 @@ gdb_test "step" "noinline \\\(\\\) at .* |
3a58abaf AM |
92 | gdb_test "bt" "#0 noinline.*#1 .*outer_inline1.*#2 .*outer_inline2.*#3 main.*" "backtrace at noinline from outer_inline1" |
93 | gdb_test "step" "inlined_fn \\\(\\\) at .*" "enter inlined_fn from noinline" | |
94 | gdb_test "bt" "#0 inlined_fn.*#1 noinline.*#2 .*outer_inline1.*#3 .*outer_inline2.*#4 main.*" "backtrace at inlined_fn from noinline" | |
95 | -gdb_test "info frame" ".*inlined into frame.*" "inlined_fn from noinline inlined" | |
96 | -gdb_test "up" "#1 noinline.*" "up to noinline" | |
97 | -gdb_test "info frame" ".*\n called by frame.*" "noinline from outer_inline1 not inlined" | |
98 | -gdb_test "up" "#2 .*outer_inline1.*" "up to outer_inline1" | |
99 | -gdb_test "info frame" ".*inlined into frame.*" "outer_inline1 inlined" | |
100 | -gdb_test "up" "#3 .*outer_inline2.*" "up to outer_inline2" | |
101 | -gdb_test "info frame" ".*inlined into frame.*" "outer_inline2 inlined" | |
102 | -gdb_test "up" "#4 main.*" "up from outer_inline2" | |
103 | -gdb_test "info frame" ".*\n caller of frame.*" "main not inlined" | |
104 | +gdb_test "info frame" "inlined into frame.*" "inlined_fn from noinline inlined" | |
105 | +gdb_test "fini" "" "up to noinline" | |
106 | +gdb_test "info frame" "\n called by frame.*" "noinline from outer_inline1 not inlined" | |
107 | +gdb_test "fini" "" "up to outer_inline1" | |
108 | +gdb_test "info frame" "inlined into frame.*" "outer_inline1 inlined" | |
109 | +gdb_test "fini" "" "up to outer_inline2" | |
110 | +gdb_test "info frame" "inlined into frame.*" "outer_inline2 inlined" | |
111 | +gdb_test "fini" "" "up from outer_inline2" | |
112 | +gdb_test "info frame" " in main \[^\n\]*\n source language.*" "main not inlined" | |
7566401a | 113 | Index: gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-locals.c |
3a58abaf | 114 | =================================================================== |
7566401a ER |
115 | --- gdb-6.8.91.20090917.orig/gdb/testsuite/gdb.opt/inline-locals.c 2009-06-28 02:20:24.000000000 +0200 |
116 | +++ gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-locals.c 2009-09-17 12:49:01.000000000 +0200 | |
3a58abaf AM |
117 | @@ -13,11 +13,16 @@ |
118 | You should have received a copy of the GNU General Public License | |
119 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
120 | ||
121 | -int x, y; | |
122 | +/* VOLATILE forces all the inlining to happen as otherwise the whole program | |
123 | + gets optimized by CSE to just simple assignments of the results. */ | |
124 | +volatile int x, y; | |
125 | volatile int result; | |
126 | volatile int *array_p; | |
127 | ||
128 | -void bar(void); | |
129 | +inline void bar(void) | |
130 | +{ | |
131 | + x += y; /* set breakpoint 1 here */ | |
132 | +} | |
133 | ||
134 | inline int func1(int arg1) | |
135 | { | |
7566401a | 136 | Index: gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-locals.exp |
3a58abaf | 137 | =================================================================== |
7566401a ER |
138 | --- gdb-6.8.91.20090917.orig/gdb/testsuite/gdb.opt/inline-locals.exp 2009-06-30 17:50:27.000000000 +0200 |
139 | +++ gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-locals.exp 2009-09-17 12:49:01.000000000 +0200 | |
3a58abaf AM |
140 | @@ -77,6 +77,9 @@ if { ! $no_frames } { |
141 | ||
142 | # Make sure that locals on the stack are found. This is an array to | |
143 | # prevent it from living in a register. | |
144 | +if [test_compiler_info "gcc-4-3-*"] { | |
145 | + setup_kfail *-*-* "gcc/debug.optimization" | |
146 | +} | |
147 | gdb_test "print array\[0\]" "\\\$$decimal = 0" "print local (2)" | |
148 | ||
149 | if { ! $no_frames } { | |
150 | @@ -115,4 +118,7 @@ if { ! $no_frames } { | |
151 | gdb_test "info locals" ".*arg2 = 184.*" "info locals above bar (3b)" | |
152 | } | |
153 | ||
154 | +if [test_compiler_info "gcc-4-3-*"] { | |
155 | + setup_kfail *-*-* "gcc/debug.optimization" | |
156 | +} | |
157 | gdb_test "print array\[0\]" "\\\$$decimal = 184" "print local (3)" | |
7566401a | 158 | Index: gdb-6.8.91.20090917/gdb/frame.c |
3a58abaf | 159 | =================================================================== |
7566401a ER |
160 | --- gdb-6.8.91.20090917.orig/gdb/frame.c 2009-09-17 12:48:49.000000000 +0200 |
161 | +++ gdb-6.8.91.20090917/gdb/frame.c 2009-09-17 12:49:01.000000000 +0200 | |
162 | @@ -310,7 +310,7 @@ fprint_frame (struct ui_file *file, stru | |
3a58abaf AM |
163 | static struct frame_info * |
164 | skip_inlined_frames (struct frame_info *frame) | |
165 | { | |
166 | - while (get_frame_type (frame) == INLINE_FRAME) | |
167 | + while (frame && get_frame_type (frame) == INLINE_FRAME) | |
168 | frame = get_prev_frame (frame); | |
169 | ||
170 | return frame; | |
7566401a | 171 | @@ -1778,6 +1778,7 @@ get_frame_address_in_block (struct frame |
3a58abaf AM |
172 | { |
173 | /* A draft address. */ | |
174 | CORE_ADDR pc = get_frame_pc (this_frame); | |
175 | + struct thread_info *tp = inferior_thread (); | |
176 | ||
177 | struct frame_info *next_frame = this_frame->next; | |
178 | ||
7566401a | 179 | @@ -1820,6 +1821,9 @@ get_frame_address_in_block (struct frame |
3a58abaf AM |
180 | while in an inlined function, then the code address of the |
181 | "calling" normal function should not be adjusted either. */ | |
182 | ||
183 | + if (tp->current_pc_is_notcurrent) | |
184 | + return pc - 1; | |
185 | + | |
186 | while (get_frame_type (next_frame) == INLINE_FRAME) | |
187 | next_frame = next_frame->next; | |
188 | ||
7566401a | 189 | @@ -1851,7 +1855,7 @@ find_frame_sal (struct frame_info *frame |
3a58abaf AM |
190 | sym = inline_skipped_symbol (inferior_ptid); |
191 | ||
192 | init_sal (sal); | |
193 | - if (SYMBOL_LINE (sym) != 0) | |
194 | + if (sym != NULL && SYMBOL_LINE (sym) != 0) | |
195 | { | |
196 | sal->symtab = SYMBOL_SYMTAB (sym); | |
197 | sal->line = SYMBOL_LINE (sym); | |
7566401a | 198 | Index: gdb-6.8.91.20090917/gdb/breakpoint.c |
3a58abaf | 199 | =================================================================== |
7566401a ER |
200 | --- gdb-6.8.91.20090917.orig/gdb/breakpoint.c 2009-09-17 12:48:51.000000000 +0200 |
201 | +++ gdb-6.8.91.20090917/gdb/breakpoint.c 2009-09-17 12:49:12.000000000 +0200 | |
202 | @@ -62,6 +62,7 @@ | |
203 | #include "jit.h" | |
204 | #include "xml-syscall.h" | |
205 | #include "parser-defs.h" | |
3a58abaf AM |
206 | +#include "inline-frame.h" |
207 | ||
7566401a ER |
208 | /* readline include files */ |
209 | #include "readline/readline.h" | |
210 | @@ -3220,10 +3221,24 @@ bpstat_check_breakpoint_conditions (bpst | |
3a58abaf AM |
211 | const struct bp_location *bl = bs->breakpoint_at; |
212 | struct breakpoint *b = bl->owner; | |
213 | ||
214 | - if (frame_id_p (b->frame_id) | |
215 | - && !frame_id_eq (b->frame_id, get_stack_frame_id (get_current_frame ()))) | |
216 | - bs->stop = 0; | |
217 | - else if (bs->stop) | |
218 | + if (frame_id_p (b->frame_id)) | |
219 | + { | |
220 | + struct frame_info *b_frame, *frame; | |
221 | + struct frame_id b_frame_id, current_frame_id; | |
222 | + | |
223 | + b_frame = frame_find_by_id (b->frame_id); | |
224 | + | |
225 | + /* get_stack_frame_id normalizes the id to the real non-inlined function | |
226 | + by skip_inlined_frames. */ | |
227 | + b_frame_id = get_stack_frame_id (b_frame); | |
228 | + current_frame_id = get_stack_frame_id (get_current_frame ()); | |
229 | + | |
230 | + /* Completely different (inlining notwithstanding) frames? */ | |
231 | + if (!frame_id_eq (b_frame_id, current_frame_id)) | |
232 | + bs->stop = 0; | |
233 | + } | |
234 | + | |
235 | + if (bs->stop) | |
236 | { | |
237 | int value_is_zero = 0; | |
238 | ||
7566401a | 239 | @@ -3383,6 +3398,12 @@ bpstat_stop_status (CORE_ADDR bp_addr, p |
3a58abaf AM |
240 | bs->print = 0; |
241 | } | |
242 | bs->commands = copy_command_lines (bs->commands); | |
243 | + | |
244 | + /* Display the innermost inlined frame at a breakpont as it gives to | |
245 | + most of the available information. */ | |
246 | + if (b->type != bp_until && b->type != bp_finish) | |
247 | + while (inline_skipped_frames (ptid)) | |
248 | + step_into_inline_frame (ptid); | |
249 | } | |
250 | ||
251 | /* Print nothing for this entry if we dont stop or if we dont print. */ | |
7566401a | 252 | @@ -5572,9 +5593,9 @@ set_momentary_breakpoint (struct gdbarch |
3a58abaf AM |
253 | { |
254 | struct breakpoint *b; | |
255 | ||
256 | - /* If FRAME_ID is valid, it should be a real frame, not an inlined | |
257 | - one. */ | |
258 | - gdb_assert (!frame_id_inlined_p (frame_id)); | |
259 | + /* We can be returning even into an inline frame. While finish_command will | |
260 | + shortcut the case of returning _from_ an inline frame we still may be | |
261 | + returning from non-inlined frame _to_ an inlined frame. */ | |
262 | ||
7566401a | 263 | b = set_raw_breakpoint (gdbarch, sal, type); |
3a58abaf | 264 | b->enable_state = bp_enabled; |
7566401a | 265 | Index: gdb-6.8.91.20090917/gdb/inline-frame.c |
3a58abaf | 266 | =================================================================== |
7566401a ER |
267 | --- gdb-6.8.91.20090917.orig/gdb/inline-frame.c 2009-09-13 18:28:28.000000000 +0200 |
268 | +++ gdb-6.8.91.20090917/gdb/inline-frame.c 2009-09-17 12:49:01.000000000 +0200 | |
269 | @@ -199,6 +199,12 @@ inline_frame_sniffer (const struct frame | |
3a58abaf AM |
270 | if (frame_block == NULL) |
271 | return 0; | |
272 | ||
273 | + /* For >=2 inlined functions SKIPPED_SYMBOL needs to be different after each | |
274 | + step_into_inline_frame call. But skip_inline_frames is called only once | |
275 | + and thus SKIPPED_SYMBOL needs to be calculated by INLINE_FRAME_SNIFFER. */ | |
276 | + if (state) | |
277 | + state->skipped_symbol = NULL; | |
278 | + | |
279 | /* Calculate DEPTH, the number of inlined functions at this | |
280 | location. */ | |
281 | depth = 0; | |
7566401a | 282 | @@ -208,6 +214,10 @@ inline_frame_sniffer (const struct frame |
3a58abaf AM |
283 | if (block_inlined_p (cur_block)) |
284 | depth++; | |
285 | ||
286 | + if (state && depth == state->skipped_frames | |
287 | + && state->skipped_symbol == NULL) | |
288 | + state->skipped_symbol = BLOCK_FUNCTION (cur_block); | |
289 | + | |
290 | cur_block = BLOCK_SUPERBLOCK (cur_block); | |
291 | } | |
292 | ||
7566401a | 293 | @@ -291,7 +301,6 @@ skip_inline_frames (ptid_t ptid) |
3a58abaf AM |
294 | { |
295 | CORE_ADDR this_pc; | |
296 | struct block *frame_block, *cur_block; | |
297 | - struct symbol *last_sym = NULL; | |
298 | int skip_count = 0; | |
299 | struct inline_state *state; | |
300 | ||
7566401a | 301 | @@ -312,10 +321,7 @@ skip_inline_frames (ptid_t ptid) |
3a58abaf AM |
302 | of BLOCK_START. */ |
303 | if (BLOCK_START (cur_block) == this_pc | |
304 | || block_starting_point_at (this_pc, cur_block)) | |
305 | - { | |
306 | - skip_count++; | |
307 | - last_sym = BLOCK_FUNCTION (cur_block); | |
308 | - } | |
309 | + skip_count++; | |
310 | else | |
311 | break; | |
312 | } | |
7566401a | 313 | @@ -327,7 +333,6 @@ skip_inline_frames (ptid_t ptid) |
3a58abaf AM |
314 | state = allocate_inline_frame_state (ptid); |
315 | state->skipped_frames = skip_count; | |
316 | state->saved_pc = this_pc; | |
317 | - state->skipped_symbol = last_sym; | |
318 | ||
319 | if (skip_count != 0) | |
320 | reinit_frame_cache (); | |
7566401a | 321 | @@ -345,6 +350,23 @@ step_into_inline_frame (ptid_t ptid) |
3a58abaf AM |
322 | reinit_frame_cache (); |
323 | } | |
324 | ||
325 | +/* Step out of an inlined function by hiding it. */ | |
326 | + | |
327 | +void | |
328 | +step_out_of_inline_frame (ptid_t ptid) | |
329 | +{ | |
330 | + struct inline_state *state = find_inline_frame_state (ptid); | |
331 | + | |
332 | + gdb_assert (state != NULL); | |
333 | + | |
334 | + /* Simulate the caller adjustment. */ | |
335 | + if (state->skipped_frames == 0) | |
336 | + state->saved_pc--; | |
337 | + | |
338 | + state->skipped_frames++; | |
339 | + reinit_frame_cache (); | |
340 | +} | |
341 | + | |
342 | /* Return the number of hidden functions inlined into the current | |
343 | frame. */ | |
344 | ||
7566401a | 345 | Index: gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-markers.c |
3a58abaf | 346 | =================================================================== |
7566401a ER |
347 | --- gdb-6.8.91.20090917.orig/gdb/testsuite/gdb.opt/inline-markers.c 2009-06-28 02:20:24.000000000 +0200 |
348 | +++ gdb-6.8.91.20090917/gdb/testsuite/gdb.opt/inline-markers.c 2009-09-17 12:49:01.000000000 +0200 | |
3a58abaf AM |
349 | @@ -15,11 +15,6 @@ |
350 | ||
351 | extern int x, y; | |
352 | ||
353 | -void bar(void) | |
354 | -{ | |
355 | - x += y; /* set breakpoint 1 here */ | |
356 | -} | |
357 | - | |
358 | void marker(void) | |
359 | { | |
360 | x += y; /* set breakpoint 2 here */ | |
7566401a | 361 | Index: gdb-6.8.91.20090917/gdb/gdbthread.h |
3a58abaf | 362 | =================================================================== |
7566401a ER |
363 | --- gdb-6.8.91.20090917.orig/gdb/gdbthread.h 2009-09-17 12:47:07.000000000 +0200 |
364 | +++ gdb-6.8.91.20090917/gdb/gdbthread.h 2009-09-17 12:49:01.000000000 +0200 | |
365 | @@ -191,6 +191,12 @@ struct thread_info | |
3a58abaf AM |
366 | |
367 | /* Private data used by the target vector implementation. */ | |
368 | struct private_thread_info *private; | |
369 | + | |
370 | + /* Nonzero if the current frame PC should be unwound as the caller. It is | |
371 | + used to keep the backtrace upper levels existing after finish_command into | |
372 | + an inlined frame if the current inlined function/block was ending at the | |
373 | + current PC. */ | |
374 | + int current_pc_is_notcurrent; | |
375 | }; | |
376 | ||
377 | /* Create an empty thread list, or empty the existing one. */ | |
7566401a | 378 | Index: gdb-6.8.91.20090917/gdb/infcmd.c |
3a58abaf | 379 | =================================================================== |
7566401a ER |
380 | --- gdb-6.8.91.20090917.orig/gdb/infcmd.c 2009-09-17 12:47:07.000000000 +0200 |
381 | +++ gdb-6.8.91.20090917/gdb/infcmd.c 2009-09-17 12:49:01.000000000 +0200 | |
382 | @@ -1434,11 +1434,11 @@ finish_command_continuation (void *arg) | |
3a58abaf AM |
383 | struct type *value_type; |
384 | ||
385 | value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function)); | |
386 | - if (!value_type) | |
387 | + if (!SYMBOL_INLINED (a->function) && !value_type) | |
388 | internal_error (__FILE__, __LINE__, | |
389 | _("finish_command: function has no target type")); | |
390 | ||
391 | - if (TYPE_CODE (value_type) != TYPE_CODE_VOID) | |
392 | + if (value_type && TYPE_CODE (value_type) != TYPE_CODE_VOID) | |
393 | print_return_value (SYMBOL_TYPE (a->function), value_type); | |
394 | } | |
395 | ||
7566401a ER |
396 | @@ -1546,6 +1546,16 @@ finish_forward (struct symbol *function, |
397 | tp->initiating_frame = get_frame_id (frame); | |
398 | make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); | |
3a58abaf AM |
399 | |
400 | + /* We should _always_ set CURRENT_PC_IS_NOTCURRENT here to always see the | |
401 | + calling line with the message `Value returned is ...'. Currently it is | |
402 | + seen only if at least one instruction is on that source line after the | |
403 | + call instruction. We would also need to hook step_once and only clear | |
404 | + CURRENT_PC_IS_NOTCURRENT on the first step. But it would be a change of | |
405 | + general non-inlining behavior against upstream. */ | |
406 | + | |
407 | + if (get_frame_type (frame) == INLINE_FRAME) | |
408 | + tp->current_pc_is_notcurrent = 1; | |
409 | + | |
410 | tp->proceed_to_finish = 1; /* We want stop_registers, please... */ | |
7566401a ER |
411 | proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); |
412 | ||
413 | @@ -1567,7 +1577,9 @@ finish_forward (struct symbol *function, | |
3a58abaf AM |
414 | static void |
415 | finish_command (char *arg, int from_tty) | |
416 | { | |
417 | - struct frame_info *frame; | |
418 | + /* FIXME: Rename `current_frame' to `frame' upon a merge. */ | |
419 | + struct frame_info *current_frame, *prev_frame; | |
420 | + CORE_ADDR frame_pc; | |
421 | struct symbol *function; | |
422 | ||
423 | int async_exec = 0; | |
7566401a | 424 | @@ -1598,45 +1610,63 @@ finish_command (char *arg, int from_tty) |
3a58abaf AM |
425 | if (!target_has_execution) |
426 | error (_("The program is not running.")); | |
427 | ||
428 | - frame = get_prev_frame (get_selected_frame (_("No selected frame."))); | |
429 | - if (frame == 0) | |
430 | + current_frame = get_selected_frame (_("No selected frame.")); | |
431 | + frame_pc = get_frame_pc (current_frame); | |
432 | + prev_frame = get_prev_frame (current_frame); | |
433 | + if (prev_frame == 0) | |
434 | error (_("\"finish\" not meaningful in the outermost frame.")); | |
435 | ||
436 | - clear_proceed_status (); | |
437 | - | |
438 | /* Finishing from an inline frame is completely different. We don't | |
439 | try to show the "return value" - no way to locate it. So we do | |
440 | not need a completion. */ | |
441 | - if (get_frame_type (get_selected_frame (_("No selected frame."))) | |
442 | - == INLINE_FRAME) | |
443 | + if (get_frame_type (current_frame) == INLINE_FRAME) | |
444 | { | |
3a58abaf AM |
445 | - /* Claim we are stepping in the calling frame. An empty step |
446 | - range means that we will stop once we aren't in a function | |
447 | - called by that frame. We don't use the magic "1" value for | |
448 | - step_range_end, because then infrun will think this is nexti, | |
449 | - and not step over the rest of this inlined function call. */ | |
7566401a | 450 | struct thread_info *tp = inferior_thread (); |
3a58abaf AM |
451 | struct symtab_and_line empty_sal; |
452 | - init_sal (&empty_sal); | |
7566401a | 453 | - set_step_info (frame, empty_sal); |
3a58abaf AM |
454 | - tp->step_range_start = tp->step_range_end = get_frame_pc (frame); |
455 | - tp->step_over_calls = STEP_OVER_ALL; | |
456 | + struct block *frame_block; | |
457 | ||
458 | /* Print info on the selected frame, including level number but not | |
459 | source. */ | |
460 | if (from_tty) | |
461 | { | |
462 | printf_filtered (_("Run till exit from ")); | |
463 | - print_stack_frame (get_selected_frame (NULL), 1, LOCATION); | |
464 | + print_stack_frame (current_frame, 1, LOCATION); | |
7566401a ER |
465 | + } |
466 | + | |
3a58abaf AM |
467 | + /* Even just a single stepi would get us out of the caller function PC |
468 | + range. */ | |
469 | + | |
470 | + frame_block = get_frame_block (current_frame, NULL); | |
471 | + | |
472 | + /* FRAME_BLOCK must be initialized and also the frame printing above must | |
473 | + be done still with the original CURRENT_PC_IS_NOTCURRENT setting. */ | |
474 | + clear_proceed_status (); | |
475 | + | |
476 | + if (frame_block && BLOCK_END (frame_block) == frame_pc) | |
477 | + { | |
478 | + step_out_of_inline_frame (tp->ptid); | |
479 | + tp->current_pc_is_notcurrent = 1; | |
480 | + normal_stop (); | |
481 | + return; | |
7566401a ER |
482 | } |
483 | ||
3a58abaf AM |
484 | + /* Claim we are stepping in the calling frame. An empty step |
485 | + range means that we will stop once we aren't in a function | |
486 | + called by that frame. We don't use the magic "1" value for | |
487 | + step_range_end, because then infrun will think this is nexti, | |
488 | + and not step over the rest of this inlined function call. */ | |
489 | + init_sal (&empty_sal); | |
7566401a | 490 | + set_step_info (prev_frame, empty_sal); |
3a58abaf AM |
491 | + tp->step_range_start = tp->step_range_end = get_frame_pc (prev_frame); |
492 | + tp->step_over_calls = STEP_OVER_ALL; | |
493 | + | |
494 | proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); | |
495 | return; | |
496 | } | |
497 | ||
498 | /* Find the function we will return from. */ | |
499 | ||
500 | - function = find_pc_function (get_frame_pc (get_selected_frame (NULL))); | |
501 | + function = find_pc_function (frame_pc); | |
502 | ||
503 | /* Print info on the selected frame, including level number but not | |
504 | source. */ | |
7566401a | 505 | @@ -1650,10 +1680,14 @@ finish_command (char *arg, int from_tty) |
3a58abaf AM |
506 | print_stack_frame (get_selected_frame (NULL), 1, LOCATION); |
507 | } | |
508 | ||
509 | + /* Frames printing above must be done still with the original | |
510 | + CURRENT_PC_IS_NOTCURRENT setting. */ | |
511 | + clear_proceed_status (); | |
512 | + | |
513 | if (execution_direction == EXEC_REVERSE) | |
514 | finish_backward (function); | |
515 | else | |
516 | - finish_forward (function, frame); | |
517 | + finish_forward (function, prev_frame); | |
518 | } | |
519 | \f | |
520 | ||
7566401a | 521 | Index: gdb-6.8.91.20090917/gdb/target.c |
3a58abaf | 522 | =================================================================== |
7566401a ER |
523 | --- gdb-6.8.91.20090917.orig/gdb/target.c 2009-09-17 12:48:49.000000000 +0200 |
524 | +++ gdb-6.8.91.20090917/gdb/target.c 2009-09-17 12:49:01.000000000 +0200 | |
525 | @@ -2187,6 +2187,7 @@ target_resume (ptid_t ptid, int step, en | |
3a58abaf AM |
526 | { |
527 | struct target_ops *t; | |
528 | ||
529 | + clear_inline_frame_state (ptid); | |
7566401a | 530 | target_dcache_invalidate (); |
3a58abaf AM |
531 | |
532 | for (t = current_target.beneath; t != NULL; t = t->beneath) | |
7566401a | 533 | Index: gdb-6.8.91.20090917/gdb/inline-frame.h |
3a58abaf | 534 | =================================================================== |
7566401a ER |
535 | --- gdb-6.8.91.20090917.orig/gdb/inline-frame.h 2009-06-28 02:20:22.000000000 +0200 |
536 | +++ gdb-6.8.91.20090917/gdb/inline-frame.h 2009-09-17 12:49:01.000000000 +0200 | |
3a58abaf AM |
537 | @@ -43,6 +43,10 @@ void clear_inline_frame_state (ptid_t pt |
538 | ||
539 | void step_into_inline_frame (ptid_t ptid); | |
540 | ||
541 | +/* Step out of an inlined function by hiding it. */ | |
542 | + | |
543 | +void step_out_of_inline_frame (ptid_t ptid); | |
544 | + | |
545 | /* Return the number of hidden functions inlined into the current | |
546 | frame. */ | |
547 | ||
7566401a | 548 | Index: gdb-6.8.91.20090917/gdb/dwarf2read.c |
3a58abaf | 549 | =================================================================== |
7566401a ER |
550 | --- gdb-6.8.91.20090917.orig/gdb/dwarf2read.c 2009-09-17 12:48:51.000000000 +0200 |
551 | +++ gdb-6.8.91.20090917/gdb/dwarf2read.c 2009-09-17 12:49:01.000000000 +0200 | |
552 | @@ -4128,6 +4128,7 @@ read_func_scope (struct die_info *die, s | |
553 | struct block *block; | |
3a58abaf | 554 | unsigned die_children = 0; |
3a58abaf AM |
555 | int inlined_func = (die->tag == DW_TAG_inlined_subroutine); |
556 | + struct type *type; | |
557 | ||
558 | if (inlined_func) | |
559 | { | |
7566401a | 560 | @@ -4169,7 +4170,10 @@ read_func_scope (struct die_info *die, s |
3a58abaf AM |
561 | add_to_cu_func_list (name, lowpc, highpc, cu); |
562 | ||
563 | new = push_context (0, lowpc); | |
564 | - new->name = new_symbol (die, read_type_die (die, cu), cu); | |
565 | + type = read_type_die (die, cu); | |
566 | + gdb_assert (type != NULL); | |
567 | + new->name = new_symbol (die, type, cu); | |
568 | + gdb_assert (TYPE_CODE (SYMBOL_TYPE (new->name)) == TYPE_CODE_FUNC); | |
569 | ||
570 | /* If there is a location expression for DW_AT_frame_base, record | |
571 | it. */ |