Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.base / step-over-syscall.exp
CommitLineData
9c317b71
YQ
1# This testcase is part of GDB, the GNU debugger.
2
88b9d363 3# Copyright 2011-2022 Free Software Foundation, Inc.
9c317b71
YQ
4
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17
9c317b71 18set syscall_insn ""
16b10d6e
LM
19set syscall_register ""
20array set syscall_number {}
9c317b71 21
16b10d6e 22# Define the syscall instructions, registers and numbers for each target.
9c317b71
YQ
23
24if { [istarget "i\[34567\]86-*-linux*"] || [istarget "x86_64-*-linux*"] } {
9a7f938f 25 set syscall_insn "\[ \t\](int|syscall|sysenter)\[ \t\]"
16b10d6e
LM
26 set syscall_register "eax"
27 array set syscall_number {fork "(56|120)" vfork "(58|190)" \
28 clone "(56|120)"}
99fd02d9 29} elseif { [istarget "aarch64*-*-linux*"] || [istarget "arm*-*-linux*"] } {
5d0a3b53 30 set syscall_insn "\[ \t\](swi|svc)\[ \t\]"
16b10d6e
LM
31
32 if { [istarget "aarch64*-*-linux*"] } {
33 set syscall_register "x8"
34 } else {
35 set syscall_register "r7"
36 }
37
38 array set syscall_number {fork "(120|220)" vfork "(190|220)" \
39 clone "(120|220)"}
9c317b71
YQ
40} else {
41 return -1
42}
43
2b74ba5a 44proc_with_prefix check_pc_after_cross_syscall { syscall syscall_insn_next_addr } {
0b47da9f
YQ
45 set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
46
16b10d6e
LM
47 gdb_assert {$syscall_insn_next_addr != 0 \
48 && $syscall_insn_next_addr == $syscall_insn_next_addr_found} \
49 "single step over $syscall final pc"
50}
51
52# Verify the syscall number is the correct one.
53
54proc syscall_number_matches { syscall } {
55 global syscall_register syscall_number
56
57 if {[gdb_test "p \$$syscall_register" ".*= $syscall_number($syscall)" \
58 "syscall number matches"] != 0} {
59 return 0
60 }
61
62 return 1
0b47da9f 63}
9c317b71 64
0b47da9f
YQ
65# Restart GDB and set up the test. Return a list in which the first one
66# is the address of syscall instruction and the second one is the address
67# of the next instruction address of syscall instruction. If anything
68# wrong, the two elements of list are -1.
9c317b71 69
0b47da9f
YQ
70proc setup { syscall } {
71 global gdb_prompt syscall_insn
9c317b71 72
16b10d6e
LM
73 global hex
74 set next_insn_addr -1
8fc8cbda 75 set testfile "step-over-$syscall"
9c317b71 76
0b47da9f 77 clean_restart $testfile
9c317b71 78
50441f0f 79 if { ![runto_main] } then {
0b47da9f
YQ
80 fail "run to main ($syscall)"
81 return -1
82 }
9c317b71 83
0b47da9f
YQ
84 # Delete the breakpoint on main.
85 gdb_test_no_output "delete break 1"
9c317b71 86
2b74ba5a
AB
87 gdb_test_no_output "set displaced-stepping off" \
88 "set displaced-stepping off during test setup"
9c317b71 89
16b10d6e 90 gdb_test "break \*$syscall" "Breakpoint \[0-9\]* at .*"
9c317b71 91
0b47da9f
YQ
92 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
93 "continue to $syscall (1st time)"
94 # Hit the breakpoint on $syscall for the first time. In this time,
95 # we will let PLT resolution done, and the number single steps we will
96 # do later will be reduced.
9c317b71 97
0b47da9f
YQ
98 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
99 "continue to $syscall (2nd time)"
100 # Hit the breakpoint on $syscall for the second time. In this time,
101 # the address of syscall insn and next insn of syscall are recorded.
9c317b71 102
16b10d6e
LM
103 # Check if the first instruction we stopped at is the syscall one.
104 set syscall_insn_addr -1
105 gdb_test_multiple "display/i \$pc" "fetch first stop pc" {
106 -re "display/i .*: x/i .*=> ($hex) .*:.*$syscall_insn.*$gdb_prompt $" {
107 set insn_addr $expect_out(1,string)
0b47da9f 108
16b10d6e
LM
109 # Is the syscall number the correct one?
110 if {[syscall_number_matches $syscall]} {
111 set syscall_insn_addr $insn_addr
112 }
113 pass $gdb_test_name
114 }
115 -re ".*$gdb_prompt $" {
116 pass $gdb_test_name
0b47da9f 117 }
16b10d6e
LM
118 }
119
120 # If we are not at the syscall instruction yet, keep looking for it with
121 # stepi commands.
122 if {$syscall_insn_addr == -1} {
123 # Single step until we see a syscall insn or we reach the
124 # upper bound of loop iterations.
125 set steps 0
126 set max_steps 1000
127 gdb_test_multiple "stepi" "find syscall insn in $syscall" {
128 -re ".*$syscall_insn.*$gdb_prompt $" {
129 # Is the syscall number the correct one?
130 if {[syscall_number_matches $syscall]} {
131 pass $gdb_test_name
132 } else {
133 exp_continue
134 }
9c317b71 135 }
16b10d6e
LM
136 -re "x/i .*=>.*\r\n$gdb_prompt $" {
137 incr steps
138 if {$steps == $max_steps} {
139 fail $gdb_test_name
140 } else {
141 send_gdb "stepi\n"
142 exp_continue
143 }
144 }
145 }
146
147 if {$steps == $max_steps} {
148 return { -1, -1 }
9c317b71 149 }
0b47da9f
YQ
150 }
151
16b10d6e
LM
152 # We have found the syscall instruction. Now record the next instruction.
153 # Use the X command instead of stepi since we can't guarantee
154 # stepi is working properly.
155 gdb_test_multiple "x/2i \$pc" "pc before/after syscall instruction" {
156 -re "x/2i .*=> ($hex) .*:.*$syscall_insn.* ($hex) .*:.*$gdb_prompt $" {
157 set syscall_insn_addr $expect_out(1,string)
14852123 158 set actual_syscall_insn $expect_out(2,string)
16b10d6e
LM
159 set next_insn_addr $expect_out(3,string)
160 pass $gdb_test_name
161 }
0b47da9f
YQ
162 }
163
14852123
TV
164 # If we encounter a sequence:
165 # 0xf7fd5155 <__kernel_vsyscall+5>: sysenter
166 # 0xf7fd5157 <__kernel_vsyscall+7>: int $0x80
167 # 0xf7fd5159 <__kernel_vsyscall+9>: pop %ebp
168 # then a stepi at sysenter will step over the int insn, so make sure
169 # next_insn_addr points after the int insn.
170 if { $actual_syscall_insn == "sysenter" } {
171 set test "pc after sysenter instruction"
172 set re_int_insn "\[ \t\]*int\[ \t\]\[^\r\n\]*"
173 set re [multi_line \
174 "x/2i $hex" \
175 "\[^\r\n\]* $hex \[^\r\n\]*:$re_int_insn" \
176 "\[^\r\n\]* ($hex) \[^\r\n\]*:\[^\r\n\]*"]
177 gdb_test_multiple "x/2i $next_insn_addr" $test {
178 -re -wrap $re {
179 set next_insn_addr $expect_out(1,string)
180 }
181 -re -wrap "" {
182 }
183 }
184 }
185
0b47da9f
YQ
186 if {[gdb_test "stepi" "x/i .*=>.*" "stepi $syscall insn"] != 0} {
187 return { -1, -1 }
188 }
16b10d6e
LM
189
190 set pc_after_stepi [get_hexadecimal_valueof "\$pc" "0" \
191 "pc after stepi"]
192
193 gdb_assert {$next_insn_addr == $pc_after_stepi} \
194 "pc after stepi matches insn addr after syscall"
195
196 return [list $syscall_insn_addr $pc_after_stepi]
0b47da9f 197}
9c317b71 198
8fc8cbda 199proc step_over_syscall { syscall } {
0b47da9f
YQ
200 with_test_prefix "$syscall" {
201 global syscall_insn
202 global gdb_prompt
203
8fc8cbda 204 set testfile "step-over-$syscall"
0b47da9f
YQ
205
206 if [build_executable ${testfile}.exp ${testfile} ${testfile}.c {debug}] {
5b362f04 207 untested "failed to compile"
0a251e08
YQ
208 return -1
209 }
9c317b71 210
e197ad3c
YQ
211 foreach_with_prefix displaced {"off" "on"} {
212 if {$displaced == "on" && ![support_displaced_stepping]} {
213 continue
214 }
215
4719d415
YQ
216 if { $displaced == "on" && $syscall == "clone" } {
217 # GDB doesn't support stepping over clone syscall with
218 # displaced stepping.
219 kfail "gdb/19675" "single step over clone"
220 continue
221 }
222
ea507862 223 set ret [setup $syscall]
0b47da9f 224
ea507862
YQ
225 set syscall_insn_addr [lindex $ret 0]
226 set syscall_insn_next_addr [lindex $ret 1]
227 if { $syscall_insn_addr == -1 } {
228 return -1
229 }
9c317b71 230
ea507862
YQ
231 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
232 "continue to $syscall (3rd time)"
9c317b71 233
ea507862
YQ
234 # Hit the breakpoint on $syscall for the third time. In this time, we'll set
235 # breakpoint on the syscall insn we recorded previously, and single step over it.
9c317b71 236
ea507862
YQ
237 set syscall_insn_bp 0
238 gdb_test_multiple "break \*$syscall_insn_addr" "break on syscall insn" {
239 -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
240 set syscall_insn_bp $expect_out(1,string)
241 pass "break on syscall insns"
242 }
0a251e08 243 }
9c317b71 244
16b10d6e
LM
245 # Check if the syscall breakpoint is at the syscall instruction
246 # address. If so, no need to continue, otherwise we will run the
247 # inferior to completion.
248 if {$syscall_insn_addr != [get_hexadecimal_valueof "\$pc" "0"]} {
249 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
250 "continue to syscall insn $syscall"
251 }
9c317b71 252
ea507862 253 gdb_test_no_output "set displaced-stepping $displaced"
9c317b71 254
ea507862
YQ
255 # Check the address of next instruction of syscall.
256 if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
257 return -1
258 }
259 check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
dfe2ac14 260
ea507862
YQ
261 # Delete breakpoint syscall insns to avoid interference to other syscalls.
262 delete_breakpoints
9a7f938f 263
ea507862
YQ
264 gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
265 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
266 "continue to marker ($syscall)"
e197ad3c 267 }
9a7f938f 268 }
0a251e08 269}
9c317b71 270
92fa70b0
YQ
271# Set a breakpoint with a condition that evals false on syscall
272# instruction. In fact, it tests GDBserver steps over syscall
21a77091
YQ
273# instruction. SYSCALL is the syscall the program calls.
274# FOLLOW_FORK is either "parent" or "child". DETACH_ON_FORK is
275# "on" or "off".
92fa70b0 276
21a77091 277proc break_cond_on_syscall { syscall follow_fork detach_on_fork } {
92fa70b0 278 with_test_prefix "break cond on target : $syscall" {
8fc8cbda 279 set testfile "step-over-$syscall"
92fa70b0
YQ
280
281 set ret [setup $syscall]
282
283 set syscall_insn_addr [lindex $ret 0]
284 set syscall_insn_next_addr [lindex $ret 1]
285 if { $syscall_insn_addr == -1 } {
286 return -1
287 }
288
289 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
290 "continue to $syscall"
291 # Delete breakpoint syscall insns to avoid interference with other syscalls.
292 delete_breakpoints
293
21a77091
YQ
294 gdb_test "set follow-fork-mode $follow_fork"
295 gdb_test "set detach-on-fork $detach_on_fork"
92fa70b0
YQ
296
297 # Create a breakpoint with a condition that evals false.
298 gdb_test "break \*$syscall_insn_addr if main == 0" \
299 "Breakpoint \[0-9\]* at .*"
300
4719d415
YQ
301 if { $syscall == "clone" } {
302 # Create a breakpoint in the child with the condition that
303 # evals false, so that GDBserver can get the event from the
304 # child but GDB doesn't see it. In this way, we don't have
305 # to adjust the test flow for "clone".
306 # This is a regression test for PR server/19736. In this way,
307 # we can test that GDBserver gets an event from the child and
308 # set suspend count correctly while the parent is stepping over
309 # the breakpoint.
310 gdb_test "break clone_fn if main == 0"
311 }
312
21a77091
YQ
313 if { $syscall == "clone" } {
314 # follow-fork and detach-on-fork only make sense to
315 # fork and vfork.
316 gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
317 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
318 "continue to marker"
319 } else {
320 if { $follow_fork == "child" } {
321 gdb_test "continue" "exited normally.*" "continue to end of inf 2"
322 if { $detach_on_fork == "off" } {
323 gdb_test "inferior 1"
324 gdb_test "break marker" "Breakpoint.*at.*"
325 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
326 "continue to marker"
327 }
328 } else {
329 gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
330 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
331 "continue to marker"
332 }
333 }
92fa70b0
YQ
334 }
335}
336
8fc8cbda
YQ
337step_over_syscall "fork"
338step_over_syscall "vfork"
4719d415 339step_over_syscall "clone"
92fa70b0 340
8fc8cbda 341set testfile "step-over-fork"
92fa70b0 342clean_restart $testfile
50441f0f 343if { ![runto_main] } then {
92fa70b0
YQ
344 fail "run to main"
345 return -1
346}
347
348set cond_bp_target 1
349
350set test "set breakpoint condition-evaluation target"
351gdb_test_multiple $test $test {
352 -re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" {
353 # Target doesn't support breakpoint condition
354 # evaluation on its side.
355 set cond_bp_target 0
356 }
357 -re "^$test\r\n$gdb_prompt $" {
358 }
359}
360
361if { $cond_bp_target } {
21a77091
YQ
362
363 foreach_with_prefix detach-on-fork {"on" "off"} {
364 foreach_with_prefix follow-fork {"parent" "child"} {
365 foreach syscall { "fork" "vfork" "clone" } {
366
367 if { $syscall == "vfork"
368 && ${follow-fork} == "parent"
369 && ${detach-on-fork} == "off" } {
370 # Both vforked child process and parent process are
371 # under GDB's control, but GDB follows the parent
372 # process only, which can't be run until vforked child
373 # finishes. Skip the test in this scenario.
374 continue
375 }
376 break_cond_on_syscall $syscall ${follow-fork} ${detach-on-fork}
377 }
378 }
379 }
92fa70b0 380}
This page took 1.650635 seconds and 4 git commands to generate.