This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch+rfc] Warn the user on forked-off child processes


Hi,

some programs fork(2)-off a child process for some part of its run.  It was
seen on the LMbench `bin/bw_mem' program.  User sets a breakpoint which is
silently missed and nobody notices there were multiple processes being run.

If you would set
  set debug lin-lwp 1
you would see a message
  Detaching after fork from child process 11741.
but it is clear nobody runs with `set debug lin-lwp 1' set as default.

I did put there at least a warning message giving advice there is a fork:
  [Detaching after fork from child process 20372. (Try `set detach-on-fork off'.)]


Regards,
Jan


Current version:
----------------
/tmp/lmbench-3.0-a9$ upstream-gdb --args bin/x86_64-linux-gnu/bw_mem 1000 rd
GNU gdb 6.7.50.20071205-cvs
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...
(gdb) b init_loop
Breakpoint 1 at 0x4028a1: file bw_mem.c, line 150.
(gdb) r
Starting program: /tmp/lmbench-3.0-a9/bin/x86_64-linux-gnu/bw_mem 1000 rd
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7fff1a1fc000
GETOPT ind=1 n=1 arg= av[1]='1000'
0.001000 56284.07

Program exited normally.
(gdb) _

Patched GDB at least giving a hint:
-----------------------------------
/tmp/lmbench-3.0-a9$ upstream-gdb --args bin/x86_64-linux-gnu/bw_mem 1000 rd
GNU gdb 6.7.50.20071205-cvs
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...
(gdb) b init_loop
Breakpoint 1 at 0x4028a1: file bw_mem.c, line 150.
(gdb) r
Starting program: /tmp/lmbench-3.0-a9/bin/x86_64-linux-gnu/bw_mem 1000 rd
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7fff19ffd000
GETOPT ind=1 n=1 arg= av[1]='1000'
[Detaching after fork from child process 20372. (Try `set detach-on-fork off'.)]
0.001000 56557.02

Program exited normally.
(gdb) _

How to catch the breakpoint the right way in this case:
-------------------------------------------------------
/tmp/lmbench-3.0-a9$ upstream-gdb --args bin/x86_64-linux-gnu/bw_mem 1000 rd
GNU gdb 6.7.50.20071205-cvs
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...
(gdb) set follow-fork-mode child
(gdb) b init_loop
Breakpoint 1 at 0x4028a1: file bw_mem.c, line 150.
(gdb) r
Starting program: /tmp/lmbench-3.0-a9/bin/x86_64-linux-gnu/bw_mem 1000 rd
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7fff57bfd000
GETOPT ind=1 n=1 arg= av[1]='1000'
[Switching to process 19531]

Breakpoint 1, init_loop (iterations=0, cookie=0x7fff57aa4600) at bw_mem.c:150
150     {
(gdb) _

How to catch the breakpoint the suggested way in this case:
-----------------------------------------------------------
/tmp/lmbench-3.0-a9$ upstream-gdb --args bin/x86_64-linux-gnu/bw_mem 1000 rd
GNU gdb 6.7.50.20071205-cvs
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...
(gdb) set detach-on-fork off
(gdb) b init_loop
Breakpoint 1 at 0x4028a1: file bw_mem.c, line 150.
(gdb) r
Starting program: /tmp/lmbench-3.0-a9/bin/x86_64-linux-gnu/bw_mem 1000 rd
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7fff329fc000
GETOPT ind=1 n=1 arg= av[1]='1000'

Program received signal SIGINT, Interrupt.
0x00000031668cdda3 in __select_nocancel () from /lib64/libc.so.6
(gdb) info forks 
  1 process 19596 at 0x316689ad22, file fork.c, line 127
* 0 process 19593 (main process) at 0x31668cdda3, <__select_nocancel>
(gdb) fork 1
Switching to process 19596
#0  0x000000316689ad22 in __libc_fork () at ../nptl/sysdeps/unix/sysv/linux/fork.c:127
127       pid = ARCH_FORK ();
(gdb) c
Continuing.

Program received signal SIGINT, Interrupt.
0x000000316689ad22 in __libc_fork () at ../nptl/sysdeps/unix/sysv/linux/fork.c:127
127       pid = ARCH_FORK ();
(gdb) c
Continuing.

Breakpoint 1, init_loop (iterations=0, cookie=0x7fff328613c0) at bw_mem.c:150
150     {
(gdb) _
2007-04-22  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* linux-nat.c (child_follow_fork): Print a user visible warning on a
	forked-off child process.

--- ./gdb/linux-nat.c	9 Feb 2007 20:52:16 -0000	1.56
+++ ./gdb/linux-nat.c	22 Apr 2007 17:20:25 -0000
@@ -378,9 +378,17 @@ child_follow_fork (struct target_ops *op
       /* Detach new forked process?  */
       if (detach_fork)
 	{
+	  static int advice_printed = 0;
+
+	  target_terminal_ours ();
+	  fprintf_filtered (gdb_stdlog,
+			 _("[Detaching after fork from child process %d.%s]\n"),
+			    child_pid, (advice_printed ? "" :
+					_(" (Try `set detach-on-fork off'.)")));
+	  advice_printed = 1;
+
 	  if (debug_linux_nat)
 	    {
-	      target_terminal_ours ();
 	      fprintf_filtered (gdb_stdlog,
 				"Detaching after fork from child process %d.\n",
 				child_pid);
2007-04-22  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/fork-detach.c, gdb.base/fork-detach.exp: New files.

--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/fork-detach.c	22 Apr 2007 17:20:25 -0000
@@ -0,0 +1,57 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdlib.h>
+
+static void func (void)
+{
+}
+
+int main (void)
+{
+  pid_t child;
+
+  child = fork ();
+  switch (child)
+    {
+      case -1:
+	abort ();
+      case 0:
+	func ();
+	break;
+      default:
+        {
+/* We do not test the switching to the other fork by GDB `fork 1'.  */
+#if 0
+	  pid_t got;
+
+	  got = waitpid (child, NULL, 0);
+	  assert (got == child);
+#endif
+	  break;
+	}
+    }
+  return 0;
+}
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/fork-detach.exp	22 Apr 2007 17:20:25 -0000
@@ -0,0 +1,43 @@
+# Copyright 2007 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile fork-detach
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_run_cmd
+# `Starting program: .*' prefix is available since gdb-6.7.
+gdb_test "" \
+         "\\\[Detaching after fork from child process.*Program exited normally\\..*" \
+         "Info message caught"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]