Commit | Line | Data |
---|---|---|
9c317b71 YQ |
1 | # This testcase is part of GDB, the GNU debugger. |
2 | ||
0b302171 | 3 | # Copyright 2011-2012 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*"] } { | |
28 | set syscall_insn "(int|syscall|sysenter)" | |
29 | } else { | |
30 | return -1 | |
31 | } | |
32 | ||
0f4d39d5 | 33 | proc disp_step_cross_syscall { syscall } { with_test_prefix "$syscall" { |
9c317b71 YQ |
34 | global syscall_insn |
35 | global gdb_prompt | |
9c317b71 YQ |
36 | |
37 | set testfile "disp-step-$syscall" | |
38 | ||
39 | if [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c {debug}] { | |
40 | untested ${testfile}.exp | |
41 | return -1 | |
42 | } | |
43 | ||
44 | if { ![runto main] } then { | |
45 | fail "run to main ($syscall)" | |
46 | return | |
47 | } | |
48 | ||
9c317b71 YQ |
49 | # Delete the breakpoint on main. |
50 | gdb_test_no_output "delete break 1" | |
51 | ||
52 | gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*" | |
53 | gdb_test_no_output "set displaced-stepping off" | |
54 | ||
55 | set syscall_bp 0 | |
56 | gdb_test_multiple "break $syscall" "break $syscall" { | |
57 | -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" { | |
58 | set syscall_bp $expect_out(1,string) | |
59 | pass "break $syscall" | |
60 | } | |
61 | } | |
62 | ||
20ec36d9 | 63 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \ |
9c317b71 YQ |
64 | "continue to $syscall (1st time)" |
65 | # Hit the breakpoint on $syscall for the first time. In this time, we will let PLT | |
66 | # resolution done, and the number single steps we will do later will be | |
67 | # reduced. | |
68 | ||
20ec36d9 | 69 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \ |
9c317b71 YQ |
70 | "continue to $syscall (2nd time)" |
71 | # Hit the breakpoint on $syscall for the second time. In this time, the address | |
72 | # of syscall insn and next insn of syscall are recorded. | |
73 | ||
74 | gdb_test "display/i \$pc" ".*" | |
75 | ||
76 | ||
77 | # Single step until we see sysall insn or we reach the upper bound of loop | |
78 | # iterations. | |
79 | set see_syscall_insn 0 | |
80 | ||
81 | for {set i 0} {$i < 1000 && $see_syscall_insn == 0} {incr i} { | |
82 | send_gdb "stepi\n" | |
83 | gdb_expect { | |
84 | -re ".*$syscall_insn.*$gdb_prompt $" { | |
85 | set see_syscall_insn 1 | |
86 | } | |
87 | -re ".*$gdb_prompt $" {} | |
88 | } | |
89 | } | |
90 | ||
91 | if {$see_syscall_insn == 0} then { | |
92 | fail "find syscall insn in $syscall" | |
9c317b71 YQ |
93 | return -1 |
94 | } | |
95 | ||
96 | set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"] | |
97 | gdb_test "stepi" ".*" "stepi $syscall insn" | |
98 | set syscall_insn_next_addr [get_hexadecimal_valueof "\$pc" "0"] | |
99 | ||
20ec36d9 | 100 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \ |
9c317b71 YQ |
101 | "continue to $syscall (3rd time)" |
102 | ||
103 | # Hit the breakpoint on $syscall for the third time. In this time, we'll set | |
104 | # breakpoint on the syscall insn we recorded previously, and single step over it. | |
105 | ||
106 | set syscall_insn_bp 0 | |
107 | gdb_test_multiple "break \*$syscall_insn_addr" "break on syscall insn" { | |
108 | -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" { | |
109 | set syscall_insn_bp $expect_out(1,string) | |
110 | pass "break on syscall insns" | |
111 | } | |
112 | } | |
113 | gdb_test_no_output "delete $syscall_bp" "delete break $syscall" | |
114 | ||
115 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \ | |
116 | "continue to syscall insn $syscall" | |
117 | ||
118 | gdb_test_no_output "set displaced-stepping on" | |
119 | ||
120 | # Check the address of next instruction of syscall. | |
121 | gdb_test "stepi" ".*$syscall_insn_next_addr.*" "single step over $syscall" | |
122 | ||
123 | # Delete breakpoint syscall insns to avoid interference to other syscalls. | |
124 | gdb_test_no_output "delete $syscall_insn_bp" "delete break $syscall insn" | |
125 | ||
126 | gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \ | |
127 | "continue to marker ($syscall)" | |
6a5870ce | 128 | }} |
9c317b71 YQ |
129 | |
130 | disp_step_cross_syscall "fork" | |
131 | disp_step_cross_syscall "vfork" |