Commit | Line | Data |
---|---|---|
9c317b71 YQ |
1 | # This testcase is part of GDB, the GNU debugger. |
2 | ||
28e7fd62 | 3 | # Copyright 2011-2013 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 | ||
18 | if { ![support_displaced_stepping] } { | |
19 | unsupported "displaced stepping" | |
20 | return -1 | |
21 | } | |
22 | ||
23 | set syscall_insn "" | |
24 | ||
25 | # Define the syscall instruction for each target. | |
26 | ||
27 | if { [istarget "i\[34567\]86-*-linux*"] || [istarget "x86_64-*-linux*"] } { | |
9a7f938f | 28 | set syscall_insn "\[ \t\](int|syscall|sysenter)\[ \t\]" |
9c317b71 YQ |
29 | } else { |
30 | return -1 | |
31 | } | |
32 | ||
0a251e08 YQ |
33 | proc disp_step_cross_syscall { syscall } { |
34 | with_test_prefix "$syscall" { | |
35 | global syscall_insn | |
36 | global gdb_prompt | |
9c317b71 | 37 | |
0a251e08 | 38 | set testfile "disp-step-$syscall" |
9c317b71 | 39 | |
0a251e08 YQ |
40 | if [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c {debug}] { |
41 | untested ${testfile}.exp | |
42 | return -1 | |
43 | } | |
9c317b71 | 44 | |
0a251e08 YQ |
45 | if { ![runto main] } then { |
46 | fail "run to main ($syscall)" | |
47 | return | |
48 | } | |
9c317b71 | 49 | |
0a251e08 YQ |
50 | # Delete the breakpoint on main. |
51 | gdb_test_no_output "delete break 1" | |
9c317b71 | 52 | |
0a251e08 YQ |
53 | gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*" |
54 | gdb_test_no_output "set displaced-stepping off" | |
9c317b71 | 55 | |
0a251e08 YQ |
56 | set syscall_bp 0 |
57 | gdb_test_multiple "break $syscall" "break $syscall" { | |
58 | -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" { | |
59 | set syscall_bp $expect_out(1,string) | |
60 | pass "break $syscall" | |
61 | } | |
9c317b71 | 62 | } |
9c317b71 | 63 | |
0a251e08 YQ |
64 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \ |
65 | "continue to $syscall (1st time)" | |
66 | # Hit the breakpoint on $syscall for the first time. In this time, we will let PLT | |
67 | # resolution done, and the number single steps we will do later will be | |
68 | # reduced. | |
9c317b71 | 69 | |
0a251e08 YQ |
70 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \ |
71 | "continue to $syscall (2nd time)" | |
72 | # Hit the breakpoint on $syscall for the second time. In this time, the address | |
73 | # of syscall insn and next insn of syscall are recorded. | |
9c317b71 | 74 | |
0a251e08 | 75 | gdb_test "display/i \$pc" ".*" |
9c317b71 YQ |
76 | |
77 | ||
0a251e08 YQ |
78 | # Single step until we see sysall insn or we reach the upper bound of loop |
79 | # iterations. | |
80 | set see_syscall_insn 0 | |
9c317b71 | 81 | |
0a251e08 YQ |
82 | for {set i 0} {$i < 1000 && $see_syscall_insn == 0} {incr i} { |
83 | send_gdb "stepi\n" | |
84 | gdb_expect { | |
85 | -re ".*$syscall_insn.*$gdb_prompt $" { | |
86 | set see_syscall_insn 1 | |
87 | } | |
88 | -re ".*$gdb_prompt $" {} | |
9c317b71 | 89 | } |
9c317b71 | 90 | } |
9c317b71 | 91 | |
0a251e08 YQ |
92 | if {$see_syscall_insn == 0} then { |
93 | fail "find syscall insn in $syscall" | |
94 | return -1 | |
95 | } | |
9c317b71 | 96 | |
0a251e08 YQ |
97 | set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"] |
98 | gdb_test "stepi" ".*" "stepi $syscall insn" | |
99 | set syscall_insn_next_addr [get_hexadecimal_valueof "\$pc" "0"] | |
9c317b71 | 100 | |
0a251e08 YQ |
101 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \ |
102 | "continue to $syscall (3rd time)" | |
9c317b71 | 103 | |
0a251e08 YQ |
104 | # Hit the breakpoint on $syscall for the third time. In this time, we'll set |
105 | # breakpoint on the syscall insn we recorded previously, and single step over it. | |
9c317b71 | 106 | |
0a251e08 YQ |
107 | set syscall_insn_bp 0 |
108 | gdb_test_multiple "break \*$syscall_insn_addr" "break on syscall insn" { | |
109 | -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" { | |
110 | set syscall_insn_bp $expect_out(1,string) | |
111 | pass "break on syscall insns" | |
112 | } | |
9c317b71 | 113 | } |
0a251e08 | 114 | gdb_test_no_output "delete $syscall_bp" "delete break $syscall" |
9c317b71 | 115 | |
0a251e08 YQ |
116 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \ |
117 | "continue to syscall insn $syscall" | |
9c317b71 | 118 | |
0a251e08 | 119 | gdb_test_no_output "set displaced-stepping on" |
9c317b71 | 120 | |
0a251e08 YQ |
121 | # Check the address of next instruction of syscall. |
122 | if {$syscall == "vfork" && [is_remote target]} { | |
123 | setup_kfail server/13796 "*-*-*" | |
dfe2ac14 | 124 | } |
0a251e08 YQ |
125 | set test "single step over $syscall" |
126 | gdb_test_multiple "stepi" $test { | |
127 | -re "Program terminated with signal SIGILL,.*\r\n$gdb_prompt $" { | |
128 | fail $test | |
129 | return | |
130 | } | |
131 | -re "\\\[Inferior .* exited normally\\\].*\r\n$gdb_prompt $" { | |
132 | fail $test | |
133 | return | |
134 | } | |
135 | -re "\r\n$gdb_prompt $" { | |
136 | pass $test | |
137 | } | |
69dc1c4d | 138 | } |
0a251e08 YQ |
139 | |
140 | set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"] | |
141 | ||
142 | set test "single step over $syscall final pc" | |
143 | if {$syscall_insn_next_addr != 0 | |
144 | && $syscall_insn_next_addr == $syscall_insn_next_addr_found} { | |
dfe2ac14 | 145 | pass $test |
0a251e08 YQ |
146 | } else { |
147 | fail $test | |
dfe2ac14 | 148 | } |
dfe2ac14 | 149 | |
0a251e08 YQ |
150 | # Delete breakpoint syscall insns to avoid interference to other syscalls. |
151 | gdb_test_no_output "delete $syscall_insn_bp" "delete break $syscall insn" | |
9a7f938f | 152 | |
0a251e08 YQ |
153 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \ |
154 | "continue to marker ($syscall)" | |
9a7f938f | 155 | } |
0a251e08 | 156 | } |
9c317b71 YQ |
157 | |
158 | disp_step_cross_syscall "fork" | |
159 | disp_step_cross_syscall "vfork" |