]>
Commit | Line | Data |
---|---|---|
618f726f | 1 | # Copyright 2008-2016 Free Software Foundation, Inc. |
edb3359d DJ |
2 | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 3 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
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 | ||
efc9d70a TT |
16 | standard_testfile .c inline-markers.c |
17 | ||
18 | if {[prepare_for_testing $testfile.exp $testfile \ | |
19 | [list $srcfile $srcfile2] {debug optimize=-O2}]} { | |
edb3359d DJ |
20 | return -1 |
21 | } | |
22 | ||
019ebafc | 23 | gdb_test_no_output "set listsize 1" |
edb3359d DJ |
24 | |
25 | runto_main | |
26 | ||
4c93b1db | 27 | get_compiler_info |
edb3359d DJ |
28 | get_debug_format |
29 | if { [skip_inline_frame_tests] } { | |
30 | untested inline-cmds.exp | |
31 | return | |
32 | } | |
33 | ||
34 | # First, check that the things we expected to be inlined really were, | |
35 | # and those that shouldn't be weren't. | |
36 | set line1 [gdb_get_line_number "set breakpoint 1 here" ${srcfile2}] | |
37 | gdb_breakpoint $srcfile2:$line1 | |
38 | set line2 [gdb_get_line_number "set breakpoint 2 here" ${srcfile2}] | |
39 | gdb_breakpoint $srcfile2:$line2 | |
40 | ||
41 | gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (1)" | |
42 | gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*main.*" \ | |
43 | "backtrace from bar (1)" | |
44 | gdb_test "up" "#1 .*func1.*" "up from bar (1)" | |
45 | gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (1)" | |
46 | ||
47 | gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (2)" | |
48 | gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*func2.*#3 .*main.*" \ | |
49 | "backtrace from bar (2)" | |
50 | gdb_test "up" "#1 .*func1.*" "up from bar (2)" | |
51 | gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (2)" | |
52 | gdb_test "up" "#2 .*func2.*" "up from func1 (2)" | |
53 | gdb_test "info frame" ".*inlined into frame.*" "func2 inlined (2)" | |
54 | ||
55 | gdb_test "continue" ".*set breakpoint 2 here.*" "continue to marker" | |
56 | gdb_test "backtrace" "#0 marker.*#1 .*main.*" "backtrace from marker" | |
57 | gdb_test "info frame" ".*called by frame.*" "marker not inlined" | |
58 | ||
59 | # Next, check that we can next over inlined functions. We should not end up | |
60 | # inside any of them. | |
61 | delete_breakpoints | |
62 | runto_main | |
63 | ||
64 | # The lines before the first inlined call. | |
65 | set first "x = 7|y = 8" | |
66 | ||
67 | # Some extra lines that end up in our stepping due to code motion. | |
68 | set opt "start of main|result = 0" | |
69 | ||
70 | # We start this test with a "list" instead of a "next", in case the | |
71 | # first non-prologue instruction in main comes from the inlined function. | |
72 | set msg "next over inlined functions" | |
73 | gdb_test_multiple "list" $msg { | |
74 | -re "($first|result = func1|result = func2|$opt).*$gdb_prompt $" { | |
75 | send_gdb "next\r" | |
76 | exp_continue | |
77 | } | |
78 | -re "marker \\\(\\\);\r\n$gdb_prompt $" { | |
79 | pass $msg | |
80 | } | |
81 | } | |
82 | ||
83 | # Check that when next shows the call of func1, it has not happened yet. | |
84 | runto_main | |
85 | ||
86 | # Like the return value of gdb_test: -1 something is wrong, 0 passed, 1 failed. | |
87 | set bt_test -1 | |
88 | set x_test -1 | |
89 | set func1_step -1 | |
90 | ||
91 | set last_was_func1_call 0 | |
92 | set msg "next past inlined func1" | |
93 | gdb_test_multiple "list" $msg { | |
94 | -re "($first|$opt).*$gdb_prompt $" { | |
95 | set last_was_func1_call 0 | |
96 | send_gdb "next\r" | |
97 | exp_continue | |
98 | } | |
99 | -re "result = func1 \\\(\\\);\r\n$gdb_prompt $" { | |
100 | # Check whether x has been set. If 0, we may be doing something | |
101 | # else associated with this line besides the inlined call - e.g. | |
102 | # loading the address of result. If 7, we may be at the call site. | |
103 | # If 15, though, we might be past the call and back at the store to | |
104 | # result - that's OK, as long as we weren't just here (see | |
105 | # func1_step above). | |
106 | set x_val -1 | |
107 | gdb_test_multiple "print x" "" { | |
108 | -re "\\\$$decimal = (\[0-9\]*)\r\n$gdb_prompt $" { | |
109 | set x_val $expect_out(1,string) | |
110 | } | |
111 | -re "$gdb_prompt $" { } | |
112 | } | |
113 | if { $x_val == 0 || $x_val == 7 } { | |
114 | if { $x_test != 1 } { | |
115 | set x_test 0 | |
116 | } | |
117 | } elseif { $x_val == 15 } { | |
118 | if { $func1_step == -1 } { | |
119 | # We passed func1 without stopping at the call site. | |
120 | set x_test 1 | |
121 | } | |
122 | } else { | |
123 | set x_test 1 | |
124 | } | |
125 | ||
126 | # func1 should not show up on backtraces if we are at its call | |
127 | # site. | |
128 | if { $bt_test != 1 } { | |
129 | set bt_test [gdb_test "backtrace" "#0 \[^#]*main.*" ""] | |
130 | } | |
131 | ||
132 | # When we next over func1, we should not return to the same | |
133 | # line. But we might go past the line, according to source | |
134 | # code order, and then come back. A valid but odd layout is | |
135 | # body of func1, load result's address into a register using | |
136 | # the source location of "result = 0" several lines down, and | |
137 | # then return to this line for the store. GCC 4.3 does that | |
138 | # on ARM. | |
139 | if { $last_was_func1_call } { | |
140 | set func1_step 1 | |
141 | } elseif { $func1_step == -1 } { | |
142 | set func1_step 0 | |
143 | } | |
144 | set last_was_func1_call 1 | |
145 | ||
146 | send_gdb "next\r" | |
147 | exp_continue | |
148 | } | |
149 | ||
150 | -re "result = func2 \\\(\\\);\r\n$gdb_prompt $" { | |
151 | pass $msg | |
152 | } | |
153 | } | |
154 | ||
155 | if { $x_test == 0 } { | |
156 | pass "print x before func1" | |
157 | } else { | |
158 | fail "print x before func1" | |
159 | } | |
160 | ||
161 | if { $bt_test == 0 } { | |
162 | pass "backtrace does not include func1" | |
163 | } else { | |
164 | fail "backtrace does not include func1" | |
165 | } | |
166 | ||
167 | if { $bt_test == 0 } { | |
168 | pass "stepped over call to func1" | |
169 | } else { | |
170 | fail "stepped over call to func1" | |
171 | } | |
172 | ||
173 | # Next, check that we can single step into inlined functions. We should always | |
174 | # "stop" at the call sites before entering them. | |
175 | runto_main | |
176 | ||
177 | set msg "step into func1" | |
178 | set saw_call_site 0 | |
179 | gdb_test_multiple "list" $msg { | |
180 | -re "($first|$opt).*$gdb_prompt $" { | |
181 | send_gdb "step\r" | |
182 | exp_continue | |
183 | } | |
184 | -re "result = func1.*$gdb_prompt $" { | |
185 | set saw_call_site 1 | |
186 | send_gdb "step\r" | |
187 | exp_continue | |
188 | } | |
189 | -re "func1 \\\(\\\) at .*\r\n$decimal.*bar \\\(\\\);\r\n$gdb_prompt $" { | |
190 | if { $saw_call_site } { | |
191 | pass $msg | |
192 | } else { | |
193 | fail $msg | |
194 | } | |
195 | } | |
196 | } | |
197 | ||
198 | # Check finish out of an inlined function. | |
199 | set msg "finish from func1" | |
200 | gdb_test_multiple "finish" $msg { | |
201 | -re "result = func1 \\\(\\\);\r\n$gdb_prompt $" { | |
202 | pass $msg | |
203 | } | |
204 | -re "($first|$opt).*$gdb_prompt $" { | |
205 | # Whoops. We finished, but ended up back at an earlier line. Keep | |
206 | # trying. | |
207 | send_gdb "step\r" | |
208 | exp_continue | |
209 | } | |
210 | -re "func1 \\\(\\\) at .*\r\n$decimal.*bar \\\(\\\);\r\n$gdb_prompt $" { | |
211 | send_gdb "finish\r" | |
212 | exp_continue | |
213 | } | |
214 | } | |
215 | ||
216 | # Test some corner cases involving consecutive inlined functions. | |
217 | set line3 [gdb_get_line_number "set breakpoint 3 here"] | |
218 | gdb_breakpoint $line3 | |
219 | gdb_continue_to_breakpoint "consecutive func1" | |
220 | ||
221 | gdb_test "next" ".*func1 .*first call.*" "next to first func1" | |
222 | set msg "next to second func1" | |
223 | gdb_test_multiple "next" $msg { | |
224 | -re ".*func1 .*second call.*$gdb_prompt $" { | |
225 | pass $msg | |
226 | } | |
227 | -re ".*marker .*$gdb_prompt $" { | |
228 | # This assembles to two consecutive call instructions. | |
229 | # Both appear to be at the same line, because they're | |
230 | # in the body of the same inlined function. This is | |
231 | # reasonable for the line table. GDB should take the | |
232 | # containing block and/or function into account when | |
233 | # deciding how far to step. The single line table entry | |
234 | # is actually two consecutive instances of the same line. | |
235 | kfail gdb/NNNN $msg | |
236 | } | |
237 | } | |
238 | ||
239 | # It is easier when the two inlined functions are not on the same line. | |
240 | set line4 [gdb_get_line_number "set breakpoint 4 here"] | |
241 | gdb_breakpoint $line4 | |
242 | gdb_continue_to_breakpoint "func1 then func3" | |
243 | ||
244 | gdb_test "next" ".*func1 \\\(\\\);" "next to func1 before func3" | |
245 | gdb_test "next" ".*func3 \\\(\\\);" "next to func3" | |
246 | ||
247 | # Test finishing out of one thing and into another. | |
248 | set line5 [gdb_get_line_number "set breakpoint 5 here"] | |
249 | gdb_breakpoint $line5 | |
250 | gdb_continue_to_breakpoint "finish into func1" | |
251 | ||
252 | gdb_test "next" ".*marker \\\(\\\);" "next to finish marker" | |
253 | gdb_test "step" ".*set breakpoint 2 here.*" "step into finish marker" | |
b4cbb4a3 EBM |
254 | |
255 | # Some architectures will have one or more instructions after | |
256 | # the call instruction which still are part of the call sequence, | |
257 | # so it should be expected to return to the caller line after issue | |
258 | # a 'finish' command. | |
259 | gdb_test_multiple "finish" "finish from marker" { | |
260 | -re "func1 \\\(\\\);.*\r\n$gdb_prompt $" { | |
261 | pass "finish from marker to func1" | |
262 | } | |
263 | -re "marker \\\(\\\);.*\r\n$gdb_prompt $" { | |
264 | pass "finish from marker" | |
265 | gdb_test "step" "func1 \\\(\\\);.*" "step after marker to reach func1" | |
266 | } | |
267 | } | |
edb3359d DJ |
268 | |
269 | gdb_test "step" "bar \\\(\\\);" "step into func1 for finish" | |
270 | gdb_test "finish" "func3 \\\(\\\);" "finish from func1 to func3" | |
271 | ||
272 | # Test a deeper call stack. | |
273 | set line6 [gdb_get_line_number "set breakpoint 6 here"] | |
274 | gdb_breakpoint $line6 | |
275 | gdb_continue_to_breakpoint "before the outer_inline call" | |
276 | gdb_test "step" "marker \\\(\\\) at .*" "reach 1 the outer_inline call" | |
b4cbb4a3 EBM |
277 | gdb_test_multiple "finish" "finish from marker" { |
278 | -re "main \\\(\\\) at .*outer_inline2 \\\(\\\);.*\r\n$gdb_prompt $" { | |
279 | pass "reach outer_inline2" | |
280 | } | |
281 | -re "main \\\(\\\) at .*marker \\\(\\\);.*\r\n$gdb_prompt $" { | |
282 | pass "finish from marker" | |
283 | gdb_test "step" "outer_inline2 \\\(\\\);.*" "step after marker to reach outer_inline2" | |
284 | } | |
285 | } | |
edb3359d DJ |
286 | gdb_test "bt" "#0 main.*" "backtrace at main of outer_inline" |
287 | gdb_test "step" "outer_inline2 \\\(\\\) at .*" "enter outer_inline2" | |
288 | gdb_test "bt" "#0 outer_inline2.*#1 main.*" "backtrace at outer_inline2" | |
289 | gdb_test "step" "outer_inline1 \\\(\\\) at .*" "enter outer_inline1 from outer_inline2" | |
290 | ||
291 | set msg "backtrace at outer_inline1" | |
292 | gdb_test_multiple "bt" $msg { | |
293 | -re "#0 outer_inline1.*#1 outer_inline2.*#2 main.*$gdb_prompt $" { | |
294 | pass $msg | |
295 | } | |
296 | -re "#0 $hex in outer_inline1.*#1 outer_inline2.*#2 main.*$gdb_prompt $" { | |
297 | # Binutils PR gas/6717. Gas moves .loc past .p2align and the | |
298 | # leading nop of the inlined call appears to be on the same line | |
299 | # as main's call to marker. | |
300 | xfail $msg | |
301 | gdb_test "step" "noinline \\\(\\\);" "step to call of noinline" | |
302 | } | |
303 | } | |
304 | ||
305 | gdb_test "step" "noinline \\\(\\\) at .*" "enter noinline from outer_inline1" | |
306 | gdb_test "bt" "#0 noinline.*#1 .*outer_inline1.*#2 .*outer_inline2.*#3 main.*" "backtrace at noinline from outer_inline1" | |
307 | gdb_test "step" "inlined_fn \\\(\\\) at .*" "enter inlined_fn from noinline" | |
308 | gdb_test "bt" "#0 inlined_fn.*#1 noinline.*#2 .*outer_inline1.*#3 .*outer_inline2.*#4 main.*" "backtrace at inlined_fn from noinline" | |
309 | gdb_test "info frame" ".*inlined into frame.*" "inlined_fn from noinline inlined" | |
310 | gdb_test "up" "#1 noinline.*" "up to noinline" | |
311 | gdb_test "info frame" ".*\n called by frame.*" "noinline from outer_inline1 not inlined" | |
312 | gdb_test "up" "#2 .*outer_inline1.*" "up to outer_inline1" | |
313 | gdb_test "info frame" ".*inlined into frame.*" "outer_inline1 inlined" | |
314 | gdb_test "up" "#3 .*outer_inline2.*" "up to outer_inline2" | |
315 | gdb_test "info frame" ".*inlined into frame.*" "outer_inline2 inlined" | |
316 | gdb_test "up" "#4 main.*" "up from outer_inline2" | |
317 | gdb_test "info frame" ".*\n caller of frame.*" "main not inlined" |