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