From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29123 invoked by alias); 25 Oct 2012 17:42:56 -0000 Received: (qmail 29071 invoked by uid 22791); 25 Oct 2012 17:42:55 -0000 X-SWARE-Spam-Status: No, hits=-8.0 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 25 Oct 2012 17:42:49 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q9PHgn8P025999 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 25 Oct 2012 13:42:49 -0400 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q9PHgl69016017 for ; Thu, 25 Oct 2012 13:42:48 -0400 Subject: [PATCH 8/8] Fix PR gdb/14766 - vfork child exit with "set follow-fork-mode child" broken. To: gdb-patches@sourceware.org From: Pedro Alves Date: Thu, 25 Oct 2012 17:42:00 -0000 Message-ID: <20121025174247.13324.20062.stgit@brno.lan> In-Reply-To: <20121025174002.13324.8164.stgit@brno.lan> References: <20121025174002.13324.8164.stgit@brno.lan> User-Agent: StGit/0.16 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit 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: 2012-10/txt/msg00512.txt.bz2 If "set detach-on-fork" is off (which it is by default), and we follow the vfork child, we don't actually detach from the parent at vfork time, but instead hold on to it until the child is done with the shared memory region. IOW, until the child execs or exits. There's a single function that handles all that work for both child execs and exits, handle_vfork_child_exec_or_exit. When that function goes about detaching the parent, it tries to preserve the selected inferior (the child), but while doing so, it is also trying to restore the selected thread (as pointed at by inferior_ptid). That makes sense for execs, but not so for exits. For exits, inferior_ptid, which has been switched to the event ptid, does not point at a valid thread anymore. Instead it just points at the process's pid. The result is: (gdb) r Starting program: /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.base/foll-vfork-exit [New process 4673] I'm the child! I'm the proud parent of child #4673! Couldn't get registers: No such process. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Couldn't get registers: No such process. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Couldn't get registers: No such process. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (gdb) The fix is not try to restore the thread, but just the inferior. The bit in tcatch_vfork_then_child_follow_exit that kfails this PR is just removed, as there's a specific test for this bug in the file. It was put there originally as this bug masked the gdb/14762 bug, and thus the related gdb/14762 kfail in tcatch_vfork_then_child_follow_exit was not reached. gdb/ 2012-10-25 Pedro Alves PR gdb/14766 * infrun.c (handle_inferior_event) : Switch to null_ptid before handling a vfork child exec or exit. Switch to the event ptid afterwards. gdb/testsuite/ 2012-10-25 Pedro Alves PR gdb/14766 * gdb.base/foll-vfork.exp (vfork_child_follow_to_exit): Remove setup_kfail. (tcatch_vfork_then_child_follow_exit): No longer expect "Couldn't get registers". --- gdb/testsuite/gdb.base/foll-vfork.exp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index 0caa1ac..de9b137 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -663,7 +663,16 @@ handle_vfork_child_exec_or_exit (int exec) /* follow-fork child, detach-on-fork on. */ - old_chain = make_cleanup_restore_current_thread (); + if (!exec) + { + /* If we're handling a child exit, then inferior_ptid + points at the inferior's pid, not to a thread. */ + old_chain = save_inferior_ptid (); + save_current_program_space (); + save_current_inferior (); + } + else + old_chain = save_current_space_and_thread (); /* We're letting loose of the parent. */ tp = any_live_thread_of_process (inf->vfork_parent->pid); diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp index ca04cdc..12f7ec7 100644 --- a/gdb/testsuite/gdb.base/foll-vfork.exp +++ b/gdb/testsuite/gdb.base/foll-vfork.exp @@ -162,7 +162,7 @@ proc vfork_child_follow_to_exit {} { set test "continue to child exit" gdb_test_multiple "continue" $test { -re "Couldn't get registers.*$gdb_prompt " { - setup_kfail "gdb/14766" *-*-* + # PR gdb/14766 fail "$test" } -re "Attaching after.* vfork to.*Detaching vfork parent .* after child exit.*$gdb_prompt " { @@ -367,10 +367,6 @@ proc tcatch_vfork_then_child_follow_exit {} { set test "finish" gdb_test_multiple "finish" $test { - -re "Couldn't get registers.*$gdb_prompt " { - setup_kfail "gdb/14766" *-*-* - fail "$test " - } -re "Run till exit from.*vfork.*exited normally.*$gdb_prompt " { setup_kfail "gdb/14762" *-*-* fail $test