From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1601 invoked by alias); 8 Jun 2009 13:30:45 -0000 Received: (qmail 1573 invoked by uid 22791); 8 Jun 2009 13:30:43 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 08 Jun 2009 13:30:37 +0000 Received: (qmail 13552 invoked from network); 8 Jun 2009 13:30:35 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 8 Jun 2009 13:30:35 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: Refuse following the vfork parent if not letting the child run. Date: Mon, 08 Jun 2009 13:30:00 -0000 User-Agent: KMail/1.9.10 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200906081431.38913.pedro@codesourcery.com> 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: 2009-06/txt/msg00171.txt.bz2 If you try to follow a vfork parent, without letting the child run, GDB hangs. E.g., gdb 6.8 or head: >gdb-6.8 ./testsuite/gdb.base/foll-vfork : (gdb) set detach-on-fork off (gdb) start Breakpoint 1 at 0x4005c0: file ../../../src/gdb/testsuite/gdb.base/foll-vfork.c, line 12. Starting program: /home/pedro/gdb/sspaces/build/gdb/testsuite/gdb.base/foll-vfork main () at ../../../src/gdb/testsuite/gdb.base/foll-vfork.c:12 12 pid = vfork (); (gdb) c Continuing. No amount of ctrl-c will let you out of this. Only going to another terminal and killing gdb bails you out. I've been keeping the patch below locally to prevent getting myself in such situation. (GNU make uses vfork, and much of my multi-process testing involves running make. How convenient :-) ) The manual already mentions that you can't debug the vfork parent until the child execs in the forks section. Comments? (This applies on top the the patch that adds the option to resume all threads of all processes.) A patched GDB shows this: (gdb) set detach-on-fork off (gdb) start Temporary breakpoint 1 at 0x4005c0: file ../../../src/gdb/testsuite/gdb.base/foll-vfork.c, line 12. Starting program: /home/pedro/gdb/sspaces/build/gdb/testsuite/gdb.base/foll-vfork Temporary breakpoint 1, main () at ../../../src/gdb/testsuite/gdb.base/foll-vfork.c:12 12 pid = vfork (); (gdb) n warning: Can not debug the parent of a vfork in the foreground if not letting the child run until it execs or exits, as it would deadlock the terminal. 0x00007ffff789aee4 in vfork () from /lib/libc.so.6 (gdb) -- Pedro Alves 2009-06-08 Pedro Alves * linux-nat.c (linux_child_follow_fork): Refuse to follow a vfork parent in the foreground if not letting the child run. --- gdb/linux-nat.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) Index: src/gdb/linux-nat.c =================================================================== --- src.orig/gdb/linux-nat.c 2009-06-08 13:22:47.000000000 +0100 +++ src/gdb/linux-nat.c 2009-06-08 14:27:05.000000000 +0100 @@ -596,6 +596,21 @@ linux_child_follow_fork (struct target_o if (!detach_fork) linux_enable_event_reporting (pid_to_ptid (child_pid)); + if (has_vforked + && (!target_is_async_p () || sync_execution) + && !(follow_child || detach_fork || sched_multi)) + { + /* The parent stays blocked inside the vfork syscall until the + child execs or exits. If we don't let the child run, then + the parent stays blocked. If we're telling the parent to run + in the foreground, the user will not be able to ctrl-c to get + back the terminal, effectively hanging the debug session. */ + warning (_("\ +Can not debug the parent of a vfork in the foreground if not letting \ +the child run until it execs or exits, as it would deadlock the terminal.")); + return 1; + } + if (! follow_child) { /* We're already attached to the parent, by default. */