From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 83383 invoked by alias); 2 Jun 2016 09:31:15 -0000 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 Received: (qmail 83307 invoked by uid 89); 2 Jun 2016 09:31:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=nof, resumes, HX-Received:10.98.49.135 X-HELO: mail-pf0-f196.google.com Received: from mail-pf0-f196.google.com (HELO mail-pf0-f196.google.com) (209.85.192.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 02 Jun 2016 09:31:00 +0000 Received: by mail-pf0-f196.google.com with SMTP id f144so7398835pfa.2 for ; Thu, 02 Jun 2016 02:31:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=5nYpOfdYh1+SL+wMojXXCWBpQbaI4CGaaI1gHqUP6Kg=; b=ksCalfFQwfTGnFYUHcd+5JOFoQMyaAbPyTaCn8hb3MGT6/SxXoJ+Aym6HkOSjJLQ6x XyYJjAzLStXzy2YCzynLDDYFHsMn0Vc/bD0sGm1+ouhsQEjDP48ie6dBj0BMlFErVWPL uRdRjhLRFW4+KYL87bVDJcSSMyYWpMAgi8dVGthv2kqIpuh/5WHZGyXaTNsuV5nbD7bQ RaKkhMdM29zpa0WiPjN2+4d53SZI3z34Z8r5/P6XpmQOO4nZ/d3bhHCThepOu4la96ky MWKYNsBjdG5X9UOFDMKniihFud27alEQOgUz7fJ5YIBcoQ4hXV3VhH8ZRAhfN89ixMbu yfGA== X-Gm-Message-State: ALyK8tJL0myCl+WfuilC0AM09HcWZPFnyHeUyl1AH+OocY2X5ditOK0a1Al7x7GYnlZiUg== X-Received: by 10.98.49.135 with SMTP id x129mr836329pfx.35.1464859858168; Thu, 02 Jun 2016 02:30:58 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc113.osuosl.org. [140.211.9.71]) by smtp.gmail.com with ESMTPSA id hw10sm68656218pac.15.2016.06.02.02.30.56 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 02 Jun 2016 02:30:57 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 04/12] Delete reinsert breakpoints from forked child Date: Thu, 02 Jun 2016 09:31:00 -0000 Message-Id: <1464859846-15619-5-git-send-email-yao.qi@linaro.org> In-Reply-To: <1464859846-15619-1-git-send-email-yao.qi@linaro.org> References: <1464859846-15619-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes X-SW-Source: 2016-06/txt/msg00034.txt.bz2 When a thread is stepping over a syscall instruction with software single step, GDBserver inserts reinsert breakpoints at the next pcs. If the syscall call is fork, the forked child has reinsert breakpoint in its space, and GDBserver clones parent's breakpoint list to child's. When GDBserver resumes the child, its bp_reinsert is zero, but has reinsert breakpoints, so the following assert is triggered. gdb/gdbserver/linux-low.c:4292: A problem internal to GDBserver has been detected.^M void linux_resume_one_lwp_throw(lwp_info*, int, int, siginfo_t*): Assertion `!has_reinsert_breakpoints (proc)' failed. gdb/gdbserver: 2016-05-20 Yao Qi * linux-low.c (handle_extended_wait): If the parent is doing step-over, remove the reinsert breakpoints from the forked child. gdb/testsuite: 2016-05-26 Yao Qi * gdb.base/step-over-fork-1.c: New file. * gdb.base/step-over-fork-1.exp: New file. --- gdb/gdbserver/linux-low.c | 21 ++++++ gdb/testsuite/gdb.base/step-over-fork-1.c | 51 +++++++++++++ gdb/testsuite/gdb.base/step-over-fork-1.exp | 106 ++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 gdb/testsuite/gdb.base/step-over-fork-1.c create mode 100644 gdb/testsuite/gdb.base/step-over-fork-1.exp diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 95104d2..3f2d08e 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -569,6 +569,27 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) event_lwp->status_pending_p = 1; event_lwp->status_pending = wstat; + /* If the parent thread is doing step-over with reinsert + breakpoints, the reinsert breakpoints are still in forked + child's process space and cloned to its breakpoint list + from the parent's. Remove them from the child process. */ + if (event_lwp->bp_reinsert != 0 + && can_software_single_step () + && event == PTRACE_EVENT_FORK) + { + struct thread_info *saved_thread = current_thread; + + /* The child process is forked and stopped, so it is safe + to access its memory without stopping all other threads + from other processes. */ + current_thread = child_thr; + delete_reinsert_breakpoints (); + current_thread = saved_thread; + + gdb_assert (has_reinsert_breakpoints (parent_proc)); + gdb_assert (!has_reinsert_breakpoints (child_proc)); + } + /* Report the event. */ return 0; } diff --git a/gdb/testsuite/gdb.base/step-over-fork-1.c b/gdb/testsuite/gdb.base/step-over-fork-1.c new file mode 100644 index 0000000..2ca145b --- /dev/null +++ b/gdb/testsuite/gdb.base/step-over-fork-1.c @@ -0,0 +1,51 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2011-2016 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 +#include + +static void +marker (void) +{} + +int +main (void) +{ + int pid; + + pid = FUNC (); + if (pid == 0) /* child */ + { + exit (0); + } + else + { + } + + marker (); + + pid = FUNC (); + if (pid == 0) /* child */ + { + marker (); + exit (0); + } + else + { + marker (); + } +} diff --git a/gdb/testsuite/gdb.base/step-over-fork-1.exp b/gdb/testsuite/gdb.base/step-over-fork-1.exp new file mode 100644 index 0000000..4a34e61 --- /dev/null +++ b/gdb/testsuite/gdb.base/step-over-fork-1.exp @@ -0,0 +1,106 @@ +# Copyright 2016 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 . + +# Test a thread is stepping over a syscall instruction which does +# fork, and GDB (or GDBserver) can update its state on both parent +# process and child process correctly. + +standard_testfile + +proc test { syscall } { + global testfile srcfile + global gdb_prompt + global decimal hex + + if {[prepare_for_testing $testfile.exp $testfile $srcfile "debug additional_flags=-DFUNC=$syscall"]} { + untested $testfile.exp + return -1 + } + + # Start with a fresh gdb. + clean_restart ${testfile} + if ![runto_main] { + fail "Can't run to main" + return -1 + } + + # Step 1, find the syscall instruction address by "catch $syscall". + # Verify that the system supports "catch $syscall". + gdb_test "catch $syscall" "Catchpoint \[0-9\]* \\($syscall\\)" \ + "insert first catchpoint" + set test "continue to first catchpoint" + gdb_test_multiple "continue" $test { + -re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt $" { + unsupported "catchpoint $syscall" + return + } + -re ".*Catchpoint.*$gdb_prompt $" { + pass $test + } + } + + set syscall_insn_addr "" + set test "get syscall_insn_addr" + gdb_test_multiple "disassemble \$pc - 20,+30" $test { + -re " ($hex)\[^\r\n\]+\r\n=> .*$gdb_prompt $" { + set syscall_insn_addr $expect_out(1,string) + pass $test + } + } + + if { $syscall_insn_addr == "" } { + fail $test + return + } + + delete_breakpoints + + gdb_test "break marker" + + gdb_test "continue" "Continuing\\..*Breakpoint $decimal, .*" \ + "continue to marker (1)" + + gdb_test "set follow-fork-mode child" + gdb_test "set detach-on-fork off" + + set test "set breakpoint condition-evaluation target" + gdb_test_multiple $test $test { + -re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" { + # Target doesn't support breakpoint condition + # evaluation on its side. + } + -re "^$test\r\n$gdb_prompt $" { + } + } + + # Create a breakpoint which evaluates false. + gdb_test "break \*$syscall_insn_addr if main == 0" \ + "Breakpoint \[0-9\]* at .*" + + gdb_test "continue" "Continuing\\..*Breakpoint $decimal, marker \\(\\).*" \ + "continue to marker (2)" + + gdb_test "continue" "exited normally.*" "continue to end of inf 2" + + gdb_test "inferior 1" + gdb_test "continue" \ + "Continuing\\..*Breakpoint $decimal, marker \\(\\).*" \ + "continue to marker (3)" + gdb_exit +} + +foreach_with_prefix syscall { "fork" } { + test $syscall +} -- 1.9.1