diff options
author | Yao Qi <yao@codesourcery.com> | 2011-09-17 13:34:01 +0000 |
---|---|---|
committer | Yao Qi <yao@codesourcery.com> | 2011-09-17 13:34:01 +0000 |
commit | 9c317b7184e38324d5b564387cd48201b0541958 (patch) | |
tree | 9abe21077362c55ed37d29bfe4e45151506d1982 /gdb/testsuite/gdb.base/disp-step-syscall.exp | |
parent | e2d966398c7963a6448f0d3d4451438efeda66e7 (diff) | |
download | gdb-9c317b7184e38324d5b564387cd48201b0541958.zip gdb-9c317b7184e38324d5b564387cd48201b0541958.tar.gz gdb-9c317b7184e38324d5b564387cd48201b0541958.tar.bz2 |
gdb/testsuite/
* gdb.base/disp-step-fork.c: New.
* gdb.base/disp-step-syscall.exp: New.
* gdb.base/disp-step-vfork.c: New.
Diffstat (limited to 'gdb/testsuite/gdb.base/disp-step-syscall.exp')
-rw-r--r-- | gdb/testsuite/gdb.base/disp-step-syscall.exp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp new file mode 100644 index 0000000..a84ca29 --- /dev/null +++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp @@ -0,0 +1,138 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +if { ![support_displaced_stepping] } { + unsupported "displaced stepping" + return -1 +} + +set syscall_insn "" + +# Define the syscall instruction for each target. + +if { [istarget "i\[34567\]86-*-linux*"] || [istarget "x86_64-*-linux*"] } { + set syscall_insn "(int|syscall|sysenter)" +} else { + return -1 +} + +proc disp_step_cross_syscall { syscall } { + global syscall_insn + global gdb_prompt + global pf_prefix + + set testfile "disp-step-$syscall" + + if [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c {debug}] { + untested ${testfile}.exp + return -1 + } + + if { ![runto main] } then { + fail "run to main ($syscall)" + return + } + + set old_pf_prefix $pf_prefix + lappend pf_prefix "$syscall:" + + # Delete the breakpoint on main. + gdb_test_no_output "delete break 1" + + gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*" + gdb_test_no_output "set displaced-stepping off" + + set syscall_bp 0 + gdb_test_multiple "break $syscall" "break $syscall" { + -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" { + set syscall_bp $expect_out(1,string) + pass "break $syscall" + } + } + + gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .* in $syscall ().*" \ + "continue to $syscall (1st time)" + # Hit the breakpoint on $syscall for the first time. In this time, we will let PLT + # resolution done, and the number single steps we will do later will be + # reduced. + + gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .* in $syscall ().*" \ + "continue to $syscall (2nd time)" + # Hit the breakpoint on $syscall for the second time. In this time, the address + # of syscall insn and next insn of syscall are recorded. + + gdb_test "display/i \$pc" ".*" + + + # Single step until we see sysall insn or we reach the upper bound of loop + # iterations. + set see_syscall_insn 0 + + for {set i 0} {$i < 1000 && $see_syscall_insn == 0} {incr i} { + send_gdb "stepi\n" + gdb_expect { + -re ".*$syscall_insn.*$gdb_prompt $" { + set see_syscall_insn 1 + } + -re ".*$gdb_prompt $" {} + } + } + + if {$see_syscall_insn == 0} then { + fail "find syscall insn in $syscall" + set pf_prefix $old_pf_prefix + return -1 + } + + set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"] + gdb_test "stepi" ".*" "stepi $syscall insn" + set syscall_insn_next_addr [get_hexadecimal_valueof "\$pc" "0"] + + gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .* in $syscall ().*" \ + "continue to $syscall (3rd time)" + + # Hit the breakpoint on $syscall for the third time. In this time, we'll set + # breakpoint on the syscall insn we recorded previously, and single step over it. + + set syscall_insn_bp 0 + gdb_test_multiple "break \*$syscall_insn_addr" "break on syscall insn" { + -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" { + set syscall_insn_bp $expect_out(1,string) + pass "break on syscall insns" + } + } + gdb_test_no_output "delete $syscall_bp" "delete break $syscall" + + gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \ + "continue to syscall insn $syscall" + + gdb_test_no_output "set displaced-stepping on" + + # Check the address of next instruction of syscall. + gdb_test "stepi" ".*$syscall_insn_next_addr.*" "single step over $syscall" + + # Delete breakpoint syscall insns to avoid interference to other syscalls. + gdb_test_no_output "delete $syscall_insn_bp" "delete break $syscall insn" + + gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \ + "continue to marker ($syscall)" + + set pf_prefix $old_pf_prefix +} + +disp_step_cross_syscall "fork" +disp_step_cross_syscall "vfork" |