From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8743 invoked by alias); 16 Sep 2011 04:09:54 -0000 Received: (qmail 8724 invoked by uid 22791); 16 Sep 2011 04:09:50 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 16 Sep 2011 04:09:32 +0000 Received: from nat-jpt.mentorg.com ([192.94.33.2] helo=PR1-MAIL.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1R4Pk3-0007YA-N6 from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Thu, 15 Sep 2011 21:09:31 -0700 Received: from [172.30.8.113] ([172.30.8.113]) by PR1-MAIL.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.1830); Fri, 16 Sep 2011 13:09:30 +0900 Message-ID: <4E72CBF4.2020203@codesourcery.com> Date: Fri, 16 Sep 2011 06:49:00 -0000 From: Yao Qi User-Agent: Mozilla/5.0 (X11; Linux i686; rv:6.0.2) Gecko/20110906 Thunderbird/6.0.2 MIME-Version: 1.0 To: Pedro Alves CC: gdb-patches@sourceware.org Subject: Re: [patch 2/2] Displaced stepping across fork/vfork : test case References: <4E6C06E4.7010302@codesourcery.com> <201109141255.02766.pedro@codesourcery.com> <4E721948.5080407@codesourcery.com> <201109151652.57149.pedro@codesourcery.com> In-Reply-To: <201109151652.57149.pedro@codesourcery.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-09/txt/msg00283.txt.bz2 On 09/15/2011 11:52 PM, Pedro Alves wrote: >> > + 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" >> > + } >> > + -re "Cannot insert breakpoint .*${gdb_prompt} $" { >> > + # This syscall insn may be in vsyscall page, and we can't set a breakpoint >> > + # there on some systems. >> > + fail "break on syscall insns" > Please don't make this is a fail. It is not GDB's fault. "unsupported" > or "xfail" would be better. > "unsupported" is used here. >> > + set pf_prefix $old_pf_prefix >> > + return -1 >> > + } >> > + } > But this won't work as is. Breakpoints will only be inserted on the > next resume, not immediately. Unless you enable always-inserted mode, > that is. I can set breakpoint on vsyscall page of my system, so I have to imagine what will happen if I can't set breakpoint. As you said, breakpoints will be inserted on the next resume, so I check the "Cannot insert breakpoint" in next "continue" operation, like this, gdb_test_multiple "continue" "continue to syscall insn $syscall" { -re "Cannot insert breakpoint .*${gdb_prompt} $" { # This syscall insn may be in vsyscall page, and we can't set a breakpoint # there on some systems. unsupported "break on syscall insns" set pf_prefix $old_pf_prefix return -1 } -re "Continuing\\..*Breakpoint \[0-9\]+, .*${gdb_prompt} $" { pass "break on syscall insns" } } -- Yao (齐尧) gdb/testsuite/ * gdb.base/disp-step-fork.c: New. * gdb.base/disp-step-syscall.exp: New. * gdb.base/disp-step-vfork.c: New. --- gdb/testsuite/gdb.base/disp-step-fork.c | 57 ++++++++++ gdb/testsuite/gdb.base/disp-step-syscall.exp | 148 ++++++++++++++++++++++++++ gdb/testsuite/gdb.base/disp-step-vfork.c | 70 ++++++++++++ 3 files changed, 275 insertions(+), 0 deletions(-) create mode 100644 gdb/testsuite/gdb.base/disp-step-fork.c create mode 100644 gdb/testsuite/gdb.base/disp-step-syscall.exp create mode 100644 gdb/testsuite/gdb.base/disp-step-vfork.c diff --git a/gdb/testsuite/gdb.base/disp-step-fork.c b/gdb/testsuite/gdb.base/disp-step-fork.c new file mode 100644 index 0000000..ab4f3b4 --- /dev/null +++ b/gdb/testsuite/gdb.base/disp-step-fork.c @@ -0,0 +1,57 @@ +/* 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 . */ + +#include + +static void +marker () {} + +int +main (void) +{ + int pid; + + pid = fork (); + if (pid == 0) /* child */ + { + exit (0); /* at exit */ + } + else + { + } + + pid = fork (); + if (pid == 0) /* child */ + { + exit (0); /* at exit */ + } + else + { + } + + pid = fork (); + if (pid == 0) /* child */ + { + exit (0); /* at exit */ + } + else + { + } + + marker (); + +} 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..4860c48 --- /dev/null +++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp @@ -0,0 +1,148 @@ +# 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 . + +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_multiple "continue" "continue to syscall insn $syscall" { + -re "Cannot insert breakpoint .*${gdb_prompt} $" { + # This syscall insn may be in vsyscall page, and we can't set a breakpoint + # there on some systems. + unsupported "break on syscall insns" + set pf_prefix $old_pf_prefix + return -1 + } + -re "Continuing\\..*Breakpoint \[0-9\]+, .*${gdb_prompt} $" { + pass "break on syscall insns" + } + } + + 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" diff --git a/gdb/testsuite/gdb.base/disp-step-vfork.c b/gdb/testsuite/gdb.base/disp-step-vfork.c new file mode 100644 index 0000000..fdc7914 --- /dev/null +++ b/gdb/testsuite/gdb.base/disp-step-vfork.c @@ -0,0 +1,70 @@ +/* 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 . */ + +#include + +static void +marker () {} + +int +main (void) +{ + int pid; + + pid = vfork (); + if (pid == -1) + { + return 1; + } + else if (pid != 0) + { + } + else + { + _exit (0); + } + + pid = vfork (); + if (pid == -1) + { + return 1; + } + else if (pid != 0) + { + } + else + { + _exit (0); + } + + pid = vfork (); + if (pid == -1) + { + return 1; + } + else if (pid != 0) + { + } + else + { + _exit (0); + } + + marker (); + return 0; + +} -- 1.7.0.4