]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.opt/inline-cmds.exp
Update copyright year range in all GDB files.
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.opt / inline-cmds.exp
CommitLineData
b811d2c2 1# Copyright 2008-2020 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
8980e177
PA
16load_lib mi-support.exp
17set MIFLAGS "-i=mi"
18
efc9d70a
TT
19standard_testfile .c inline-markers.c
20
5b362f04 21if {[prepare_for_testing "failed to prepare" $testfile \
1f960ced 22 [list $srcfile $srcfile2] {debug additional_flags=-Winline}]} {
edb3359d
DJ
23 return -1
24}
25
019ebafc 26gdb_test_no_output "set listsize 1"
edb3359d
DJ
27
28runto_main
29
4c93b1db 30get_compiler_info
edb3359d
DJ
31get_debug_format
32if { [skip_inline_frame_tests] } {
5b362f04 33 untested "skipping inline frame tests"
edb3359d
DJ
34 return
35}
36
37# First, check that the things we expected to be inlined really were,
38# and those that shouldn't be weren't.
39set line1 [gdb_get_line_number "set breakpoint 1 here" ${srcfile2}]
40gdb_breakpoint $srcfile2:$line1
41set line2 [gdb_get_line_number "set breakpoint 2 here" ${srcfile2}]
42gdb_breakpoint $srcfile2:$line2
43
44gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (1)"
45gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*main.*" \
46 "backtrace from bar (1)"
47gdb_test "up" "#1 .*func1.*" "up from bar (1)"
48gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (1)"
49
50gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (2)"
51gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*func2.*#3 .*main.*" \
52 "backtrace from bar (2)"
53gdb_test "up" "#1 .*func1.*" "up from bar (2)"
54gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (2)"
55gdb_test "up" "#2 .*func2.*" "up from func1 (2)"
56gdb_test "info frame" ".*inlined into frame.*" "func2 inlined (2)"
57
58gdb_test "continue" ".*set breakpoint 2 here.*" "continue to marker"
59gdb_test "backtrace" "#0 marker.*#1 .*main.*" "backtrace from marker"
60gdb_test "info frame" ".*called by frame.*" "marker not inlined"
61
62# Next, check that we can next over inlined functions. We should not end up
63# inside any of them.
64delete_breakpoints
65runto_main
66
67# The lines before the first inlined call.
68set first "x = 7|y = 8"
69
70# Some extra lines that end up in our stepping due to code motion.
71set opt "start of main|result = 0"
72
73# We start this test with a "list" instead of a "next", in case the
74# first non-prologue instruction in main comes from the inlined function.
75set msg "next over inlined functions"
76gdb_test_multiple "list" $msg {
77 -re "($first|result = func1|result = func2|$opt).*$gdb_prompt $" {
78 send_gdb "next\r"
79 exp_continue
80 }
81 -re "marker \\\(\\\);\r\n$gdb_prompt $" {
82 pass $msg
83 }
84}
85
86# Check that when next shows the call of func1, it has not happened yet.
87runto_main
88
89# Like the return value of gdb_test: -1 something is wrong, 0 passed, 1 failed.
90set bt_test -1
91set x_test -1
92set func1_step -1
93
94set last_was_func1_call 0
95set msg "next past inlined func1"
96gdb_test_multiple "list" $msg {
97 -re "($first|$opt).*$gdb_prompt $" {
98 set last_was_func1_call 0
99 send_gdb "next\r"
100 exp_continue
101 }
102 -re "result = func1 \\\(\\\);\r\n$gdb_prompt $" {
103 # Check whether x has been set. If 0, we may be doing something
104 # else associated with this line besides the inlined call - e.g.
105 # loading the address of result. If 7, we may be at the call site.
106 # If 15, though, we might be past the call and back at the store to
107 # result - that's OK, as long as we weren't just here (see
108 # func1_step above).
109 set x_val -1
110 gdb_test_multiple "print x" "" {
111 -re "\\\$$decimal = (\[0-9\]*)\r\n$gdb_prompt $" {
112 set x_val $expect_out(1,string)
113 }
114 -re "$gdb_prompt $" { }
115 }
116 if { $x_val == 0 || $x_val == 7 } {
117 if { $x_test != 1 } {
118 set x_test 0
119 }
120 } elseif { $x_val == 15 } {
121 if { $func1_step == -1 } {
122 # We passed func1 without stopping at the call site.
123 set x_test 1
124 }
125 } else {
126 set x_test 1
127 }
128
129 # func1 should not show up on backtraces if we are at its call
130 # site.
131 if { $bt_test != 1 } {
132 set bt_test [gdb_test "backtrace" "#0 \[^#]*main.*" ""]
133 }
134
135 # When we next over func1, we should not return to the same
136 # line. But we might go past the line, according to source
137 # code order, and then come back. A valid but odd layout is
138 # body of func1, load result's address into a register using
139 # the source location of "result = 0" several lines down, and
140 # then return to this line for the store. GCC 4.3 does that
141 # on ARM.
142 if { $last_was_func1_call } {
143 set func1_step 1
144 } elseif { $func1_step == -1 } {
145 set func1_step 0
146 }
147 set last_was_func1_call 1
148
149 send_gdb "next\r"
150 exp_continue
151 }
152
153 -re "result = func2 \\\(\\\);\r\n$gdb_prompt $" {
154 pass $msg
155 }
156}
157
158if { $x_test == 0 } {
159 pass "print x before func1"
160} else {
161 fail "print x before func1"
162}
163
164if { $bt_test == 0 } {
165 pass "backtrace does not include func1"
166} else {
167 fail "backtrace does not include func1"
168}
169
170if { $bt_test == 0 } {
171 pass "stepped over call to func1"
172} else {
173 fail "stepped over call to func1"
174}
175
176# Next, check that we can single step into inlined functions. We should always
177# "stop" at the call sites before entering them.
178runto_main
179
180set msg "step into func1"
181set saw_call_site 0
182gdb_test_multiple "list" $msg {
183 -re "($first|$opt).*$gdb_prompt $" {
184 send_gdb "step\r"
185 exp_continue
186 }
187 -re "result = func1.*$gdb_prompt $" {
188 set saw_call_site 1
189 send_gdb "step\r"
190 exp_continue
191 }
192 -re "func1 \\\(\\\) at .*\r\n$decimal.*bar \\\(\\\);\r\n$gdb_prompt $" {
193 if { $saw_call_site } {
194 pass $msg
195 } else {
196 fail $msg
197 }
198 }
199}
200
201# Check finish out of an inlined function.
202set msg "finish from func1"
203gdb_test_multiple "finish" $msg {
204 -re "result = func1 \\\(\\\);\r\n$gdb_prompt $" {
205 pass $msg
206 }
207 -re "($first|$opt).*$gdb_prompt $" {
208 # Whoops. We finished, but ended up back at an earlier line. Keep
209 # trying.
210 send_gdb "step\r"
211 exp_continue
212 }
213 -re "func1 \\\(\\\) at .*\r\n$decimal.*bar \\\(\\\);\r\n$gdb_prompt $" {
214 send_gdb "finish\r"
215 exp_continue
216 }
217}
218
219# Test some corner cases involving consecutive inlined functions.
220set line3 [gdb_get_line_number "set breakpoint 3 here"]
221gdb_breakpoint $line3
222gdb_continue_to_breakpoint "consecutive func1"
223
224gdb_test "next" ".*func1 .*first call.*" "next to first func1"
225set msg "next to second func1"
226gdb_test_multiple "next" $msg {
227 -re ".*func1 .*second call.*$gdb_prompt $" {
228 pass $msg
229 }
230 -re ".*marker .*$gdb_prompt $" {
231 # This assembles to two consecutive call instructions.
232 # Both appear to be at the same line, because they're
233 # in the body of the same inlined function. This is
234 # reasonable for the line table. GDB should take the
235 # containing block and/or function into account when
236 # deciding how far to step. The single line table entry
237 # is actually two consecutive instances of the same line.
238 kfail gdb/NNNN $msg
239 }
240}
241
242# It is easier when the two inlined functions are not on the same line.
243set line4 [gdb_get_line_number "set breakpoint 4 here"]
244gdb_breakpoint $line4
245gdb_continue_to_breakpoint "func1 then func3"
246
247gdb_test "next" ".*func1 \\\(\\\);" "next to func1 before func3"
248gdb_test "next" ".*func3 \\\(\\\);" "next to func3"
249
250# Test finishing out of one thing and into another.
251set line5 [gdb_get_line_number "set breakpoint 5 here"]
252gdb_breakpoint $line5
253gdb_continue_to_breakpoint "finish into func1"
254
255gdb_test "next" ".*marker \\\(\\\);" "next to finish marker"
256gdb_test "step" ".*set breakpoint 2 here.*" "step into finish marker"
b4cbb4a3
EBM
257
258# Some architectures will have one or more instructions after
259# the call instruction which still are part of the call sequence,
260# so it should be expected to return to the caller line after issue
261# a 'finish' command.
262gdb_test_multiple "finish" "finish from marker" {
263 -re "func1 \\\(\\\);.*\r\n$gdb_prompt $" {
264 pass "finish from marker to func1"
265 }
266 -re "marker \\\(\\\);.*\r\n$gdb_prompt $" {
267 pass "finish from marker"
268 gdb_test "step" "func1 \\\(\\\);.*" "step after marker to reach func1"
269 }
270}
edb3359d
DJ
271
272gdb_test "step" "bar \\\(\\\);" "step into func1 for finish"
273gdb_test "finish" "func3 \\\(\\\);" "finish from func1 to func3"
274
275# Test a deeper call stack.
276set line6 [gdb_get_line_number "set breakpoint 6 here"]
277gdb_breakpoint $line6
278gdb_continue_to_breakpoint "before the outer_inline call"
279gdb_test "step" "marker \\\(\\\) at .*" "reach 1 the outer_inline call"
b4cbb4a3
EBM
280gdb_test_multiple "finish" "finish from marker" {
281 -re "main \\\(\\\) at .*outer_inline2 \\\(\\\);.*\r\n$gdb_prompt $" {
282 pass "reach outer_inline2"
283 }
284 -re "main \\\(\\\) at .*marker \\\(\\\);.*\r\n$gdb_prompt $" {
285 pass "finish from marker"
286 gdb_test "step" "outer_inline2 \\\(\\\);.*" "step after marker to reach outer_inline2"
287 }
288}
edb3359d
DJ
289gdb_test "bt" "#0 main.*" "backtrace at main of outer_inline"
290gdb_test "step" "outer_inline2 \\\(\\\) at .*" "enter outer_inline2"
291gdb_test "bt" "#0 outer_inline2.*#1 main.*" "backtrace at outer_inline2"
292gdb_test "step" "outer_inline1 \\\(\\\) at .*" "enter outer_inline1 from outer_inline2"
293
294set msg "backtrace at outer_inline1"
295gdb_test_multiple "bt" $msg {
296 -re "#0 outer_inline1.*#1 outer_inline2.*#2 main.*$gdb_prompt $" {
297 pass $msg
298 }
299 -re "#0 $hex in outer_inline1.*#1 outer_inline2.*#2 main.*$gdb_prompt $" {
300 # Binutils PR gas/6717. Gas moves .loc past .p2align and the
301 # leading nop of the inlined call appears to be on the same line
302 # as main's call to marker.
303 xfail $msg
304 gdb_test "step" "noinline \\\(\\\);" "step to call of noinline"
305 }
306}
307
308gdb_test "step" "noinline \\\(\\\) at .*" "enter noinline from outer_inline1"
309gdb_test "bt" "#0 noinline.*#1 .*outer_inline1.*#2 .*outer_inline2.*#3 main.*" "backtrace at noinline from outer_inline1"
310gdb_test "step" "inlined_fn \\\(\\\) at .*" "enter inlined_fn from noinline"
311gdb_test "bt" "#0 inlined_fn.*#1 noinline.*#2 .*outer_inline1.*#3 .*outer_inline2.*#4 main.*" "backtrace at inlined_fn from noinline"
312gdb_test "info frame" ".*inlined into frame.*" "inlined_fn from noinline inlined"
313gdb_test "up" "#1 noinline.*" "up to noinline"
314gdb_test "info frame" ".*\n called by frame.*" "noinline from outer_inline1 not inlined"
315gdb_test "up" "#2 .*outer_inline1.*" "up to outer_inline1"
316gdb_test "info frame" ".*inlined into frame.*" "outer_inline1 inlined"
317gdb_test "up" "#3 .*outer_inline2.*" "up to outer_inline2"
318gdb_test "info frame" ".*inlined into frame.*" "outer_inline2 inlined"
319gdb_test "up" "#4 main.*" "up from outer_inline2"
320gdb_test "info frame" ".*\n caller of frame.*" "main not inlined"
8980e177
PA
321
322gdb_exit
323
324# Send a CLI "step" command over MI. CLI_OUTPUT_RE is a regexp that
325# matches the expected CLI output. MESSAGE is used as test message.
326
327proc mi_cli_step {cli_output_re message} {
328 global mi_gdb_prompt
329 global srcfile
330 global decimal
331
332 send_gdb "interpreter-exec console \"step\"\n"
333 gdb_expect {
334 -re "\\^running\r\n\\*running,thread-id=\"all\"\r\n${mi_gdb_prompt}${cli_output_re}" {
335 pass $message
336 }
337 timeout {
338 fail "$message (timeout)"
339 }
340 eof {
341 fail "$message (eof)"
342 }
343 }
344
345 # mi_expect_stop handles "set mi-async on/off" differences.
346 mi_expect_stop "end-stepping-range" "\[^\r\n\]*" "" ".*$srcfile" "$decimal" \
347 "" "got *stopped for $message"
348}
349
350# Test that stepping into an inlined function with the CLI "step"
351# command run while the top interpreter is MI results in the expected
352# CLI output sent to MI's console.
353with_test_prefix "mi" {
354 if [mi_gdb_start] {
355 continue
356 }
357 mi_gdb_load ${binfile}
358 mi_runto main
359
360 set line_number [gdb_get_line_number "set mi break here"]
361 mi_gdb_test "-break-insert ${srcfile}:${line_number}" \
362 {\^done,bkpt=.number="2",type="breakpoint".*\}} \
363 "set breakpoint"
364
365 mi_execute_to "exec-continue" "breakpoint-hit" "main" "" ".*" ".*" \
366 { "" "disp=\"keep\"" } "breakpoint hit"
367
368 incr line_number 2
369
370 # Step to the line that does an inline call.
371 set re "~\"$line_number\\\\t result = func1 \\(\\);\\\\n\"\r\n"
372 mi_cli_step "${re}" "step to inline call"
373
374 # Step into the inlined function.
375 set re [multi_line \
376 "~\"func1 \\(\\) at .*$srcfile:$decimal\\\\n\"" \
377 "~\"$decimal\\\\t bar \\(\\);\\\\n\"\r\n"]
378 mi_cli_step "${re}" "step into inline call"
379}