This is the mail archive of the gdb-patches@sources.redhat.com 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]

Re: PATCH: Detect support for fork tracing on Linux


On Wed, Mar 26, 2003 at 03:10:04PM -0500, Daniel Jacobowitz wrote:
> I got bogged down submitting the patches for fork event tracing.  This is an
> attempt to come back at the problem from another angle.
> 
> This patch adds runtime detection of fork event support.  Instead of always
> showing "not implemented yet", the code will select between "not implemented
> yet" and "not available on your system".  Pretty useless on its own, but it
> provides framework to move forward.
> 
> Unfortunately the error moves from when the catchpoint is requested to when
> it is inserted.  Fixing this will require more target methods, and it's
> purely cosmetic, so I left it off for now.  I have a good idea of what I'd
> want the new method to look like but I don't want to do it until we've
> cleaned up breakpoint/catchpoint handling a bit as discussed by Andrew.
> 
> Anyone have comments on this patch?  If not I'll probably check it in next
> week.  Then the other pieces can start to come in incrementally.

The astute reader will notice that I didn't check it in.  The reason
was that I wasn't happy with the gotcha above, so I wanted to keep
trying to fix it.  Unfortunately, it turned out to be from hard to
impossible to fix.  Ideally you'd query the target - but when the user
says "catch fork" the target may not be available yet.  And the
catchpoint might be left when we switch to another target.  It's more
than a theoretical problem; when we start a native session, target is
"exec", which obviously won't support catchpoints.

> 2003-03-26  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* Makefile.in (linux-nat.o): Add rule.
> 	* linux-nat.c: New file.
> 	* config/nm-linux.h (CHILD_INSERT_FORK_CATCHPOINT): Define.
> 	(CHILD_INSERT_VFORK_CATCHPOINT): Define.
> 	(CHILD_INSERT_EXEC_CATCHPOINT): Define.
> 	* config/alpha/alpha-linux.mh (NATDEPFILES): Add linux-nat.o.
> 	* config/arm/linux.mh (NATDEPFILES): Likewise.
> 	* config/i386/linux.mh (NATDEPFILES): Likewise.
> 	* config/i386/x86-64linux.mh (NATDEPFILES): Likewise.
> 	* config/ia64/linux.mh (NATDEPFILES): Likewise.
> 	* config/m68k/linux.mh (NATDEPFILES): Likewise.
> 	* config/mips/linux.mh (NATDEPFILES): Likewise.
> 	* config/powerpc/linux.mh (NATDEPFILES): Likewise.
> 	* config/s390/s390.mh (NATDEPFILES): Likewise.
> 	* config/sparc/linux.mh (NATDEPFILES): Likewise.

Commited.  Updated patch is below.  I'm going to get back to work on
_actually_ supporting fork catchpoints now; exec catchpoints and remote
fork catchpoints probably won't make GDB 6, but hopefully local
fork/vfork catchpoints will.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2003-06-15  Daniel Jacobowitz  <drow@mvista.com>

	* Makefile.in (linux-nat.o): Add rule.
	* linux-nat.c: New file.
	* config/nm-linux.h (CHILD_INSERT_FORK_CATCHPOINT): Define.
	(CHILD_INSERT_VFORK_CATCHPOINT): Define.
	(CHILD_INSERT_EXEC_CATCHPOINT): Define.
	* config/alpha/alpha-linux.mh (NATDEPFILES): Add linux-nat.o.
	* config/arm/linux.mh (NATDEPFILES): Likewise.
	* config/i386/linux.mh (NATDEPFILES): Likewise.
	* config/i386/x86-64linux.mh (NATDEPFILES): Likewise.
	* config/ia64/linux.mh (NATDEPFILES): Likewise.
	* config/m68k/linux.mh (NATDEPFILES): Likewise.
	* config/mips/linux.mh (NATDEPFILES): Likewise.
	* config/powerpc/linux.mh (NATDEPFILES): Likewise.
	* config/s390/s390.mh (NATDEPFILES): Likewise.
	* config/sparc/linux.mh (NATDEPFILES): Likewise.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.406
diff -u -p -r1.406 Makefile.in
--- Makefile.in	15 Jun 2003 00:27:54 -0000	1.406
+++ Makefile.in	15 Jun 2003 20:55:48 -0000
@@ -1916,6 +1916,7 @@ lin-lwp.o: lin-lwp.c $(defs_h) $(gdb_ass
 linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
 	$(symfile_h) $(objfiles_h) $(source_h) $(demangle_h) $(value_h) \
 	$(completer_h) $(cp_abi_h) $(parser_defs_h) $(block_h) $(objc_lang_h)
+linux-nat.o: linux-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdb_wait_h)
 linux-proc.o: linux-proc.c $(defs_h) $(inferior_h) $(regcache_h) \
 	$(gregset_h) $(gdbcore_h) $(gdbthread_h) $(elf_bfd_h) \
 	$(cli_decode_h) $(gdb_string_h)
Index: linux-nat.c
===================================================================
RCS file: linux-nat.c
diff -N linux-nat.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ linux-nat.c	15 Jun 2003 20:55:48 -0000
@@ -0,0 +1,176 @@
+/* GNU/Linux native-dependent code common to multiple platforms.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "inferior.h"
+#include "target.h"
+
+#include "gdb_wait.h"
+#include <sys/ptrace.h>
+
+/* If the system headers did not provide the constants, hard-code the normal
+   values.  */
+#ifndef PTRACE_EVENT_FORK
+
+#define PTRACE_SETOPTIONS	0x4200
+#define PTRACE_GETEVENTMSG	0x4201
+
+/* options set using PTRACE_SETOPTIONS */
+#define PTRACE_O_TRACESYSGOOD	0x00000001
+#define PTRACE_O_TRACEFORK	0x00000002
+#define PTRACE_O_TRACEVFORK	0x00000004
+#define PTRACE_O_TRACECLONE	0x00000008
+#define PTRACE_O_TRACEEXEC	0x00000010
+
+/* Wait extended result codes for the above trace options.  */
+#define PTRACE_EVENT_FORK	1
+#define PTRACE_EVENT_VFORK	2
+#define PTRACE_EVENT_CLONE	3
+#define PTRACE_EVENT_EXEC	4
+
+#endif /* PTRACE_EVENT_FORK */
+
+/* We can't always assume that this flag is available, but all systems
+   with the ptrace event handlers also have __WALL, so it's safe to use
+   here.  */
+#ifndef __WALL
+#define __WALL          0x40000000 /* Wait for any child.  */
+#endif
+
+/* This variable is a tri-state flag: -1 for unknown, 0 if PTRACE_O_TRACEFORK
+   can not be used, 1 if it can.  */
+
+static int linux_supports_tracefork_flag = -1;
+
+
+/* A helper function for linux_test_for_tracefork, called after fork ().  */
+
+static void
+linux_tracefork_child (void)
+{
+  int ret;
+
+  ptrace (PTRACE_TRACEME, 0, 0, 0);
+  kill (getpid (), SIGSTOP);
+  fork ();
+  exit (0);
+}
+
+/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events.  We
+   create a child process, attach to it, use PTRACE_SETOPTIONS to enable
+   fork tracing, and let it fork.  If the process exits, we assume that
+   we can't use TRACEFORK; if we get the fork notification, and we can
+   extract the new child's PID, then we assume that we can.  */
+
+static void
+linux_test_for_tracefork (void)
+{
+  int child_pid, ret, status;
+  long second_pid;
+
+  child_pid = fork ();
+  if (child_pid == -1)
+    perror_with_name ("linux_test_for_tracefork: fork");
+
+  if (child_pid == 0)
+    linux_tracefork_child ();
+
+  ret = waitpid (child_pid, &status, 0);
+  if (ret == -1)
+    perror_with_name ("linux_test_for_tracefork: waitpid");
+  else if (ret != child_pid)
+    error ("linux_test_for_tracefork: waitpid: unexpected result %d.", ret);
+  if (! WIFSTOPPED (status))
+    error ("linux_test_for_tracefork: waitpid: unexpected status %d.", status);
+
+  linux_supports_tracefork_flag = 0;
+
+  ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK);
+  if (ret != 0)
+    {
+      ptrace (PTRACE_KILL, child_pid, 0, 0);
+      waitpid (child_pid, &status, 0);
+      return;
+    }
+
+  ptrace (PTRACE_CONT, child_pid, 0, 0);
+  ret = waitpid (child_pid, &status, 0);
+  if (ret == child_pid && WIFSTOPPED (status)
+      && status >> 16 == PTRACE_EVENT_FORK)
+    {
+      second_pid = 0;
+      ret = ptrace (PTRACE_GETEVENTMSG, child_pid, 0, &second_pid);
+      if (ret == 0 && second_pid != 0)
+	{
+	  int second_status;
+
+	  linux_supports_tracefork_flag = 1;
+	  waitpid (second_pid, &second_status, 0);
+	  ptrace (PTRACE_DETACH, second_pid, 0, 0);
+	}
+    }
+
+  if (WIFSTOPPED (status))
+    {
+      ptrace (PTRACE_DETACH, child_pid, 0, 0);
+      waitpid (child_pid, &status, 0);
+    }
+}
+
+/* Return non-zero iff we have tracefork functionality available.
+   This function also sets linux_supports_tracefork_flag.  */
+
+static int
+linux_supports_tracefork (void)
+{
+  if (linux_supports_tracefork_flag == -1)
+    linux_test_for_tracefork ();
+  return linux_supports_tracefork_flag;
+}
+
+
+int
+child_insert_fork_catchpoint (int pid)
+{
+  if (linux_supports_tracefork ())
+    error ("Fork catchpoints have not been implemented yet.");
+  else
+    error ("Your system does not support fork catchpoints.");
+}
+
+int
+child_insert_vfork_catchpoint (int pid)
+{
+  if (linux_supports_tracefork ())
+    error ("Vfork catchpoints have not been implemented yet.");
+  else
+    error ("Your system does not support vfork catchpoints.");
+}
+
+int
+child_insert_exec_catchpoint (int pid)
+{
+  if (linux_supports_tracefork ())
+    error ("Exec catchpoints have not been implemented yet.");
+  else
+    error ("Your system does not support exec catchpoints.");
+}
+
+
Index: config/nm-linux.h
===================================================================
RCS file: /cvs/src/src/gdb/config/nm-linux.h,v
retrieving revision 1.14
diff -u -p -r1.14 nm-linux.h
--- config/nm-linux.h	12 Apr 2003 17:41:26 -0000	1.14
+++ config/nm-linux.h	15 Jun 2003 20:55:48 -0000
@@ -77,3 +77,7 @@ struct mem_attrib;
 extern int linux_proc_xfer_memory (CORE_ADDR addr, char *myaddr, int len,
 				   int write, struct mem_attrib *attrib,
 				   struct target_ops *target);
+
+#define CHILD_INSERT_FORK_CATCHPOINT
+#define CHILD_INSERT_VFORK_CATCHPOINT
+#define CHILD_INSERT_EXEC_CATCHPOINT
Index: config/alpha/alpha-linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/alpha/alpha-linux.mh,v
retrieving revision 1.10
diff -u -p -r1.10 alpha-linux.mh
--- config/alpha/alpha-linux.mh	4 Dec 2002 05:40:40 -0000	1.10
+++ config/alpha/alpha-linux.mh	15 Jun 2003 20:55:48 -0000
@@ -2,7 +2,8 @@
 XM_FILE= xm-alphalinux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o corelow.o alpha-nat.o linux-proc.o \
-	fork-child.o proc-service.o thread-db.o lin-lwp.o gcore.o
+	fork-child.o proc-service.o thread-db.o lin-lwp.o gcore.o \
+	linux-nat.o
 
 LOADLIBES = -ldl -rdynamic
 
Index: config/arm/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/arm/linux.mh,v
retrieving revision 1.10
diff -u -p -r1.10 linux.mh
--- config/arm/linux.mh	18 Jan 2002 04:50:58 -0000	1.10
+++ config/arm/linux.mh	15 Jun 2003 20:55:48 -0000
@@ -5,7 +5,7 @@ XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o	\
 	core-regset.o arm-linux-nat.o linux-proc.o gcore.o	\
-	proc-service.o thread-db.o lin-lwp.o
+	proc-service.o thread-db.o lin-lwp.o linux-nat.o
 
 LOADLIBES= -ldl -rdynamic
 
Index: config/i386/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/linux.mh,v
retrieving revision 1.12
diff -u -p -r1.12 linux.mh
--- config/i386/linux.mh	11 May 2002 17:22:27 -0000	1.12
+++ config/i386/linux.mh	15 Jun 2003 20:55:48 -0000
@@ -5,7 +5,8 @@ XM_FILE= xm-i386.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o linux-proc.o \
 	core-aout.o i386-nat.o i386-linux-nat.o \
-	proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o
+	proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o \
+	linux-nat.o
 
 # The dynamically loaded libthread_db needs access to symbols in the
 # gdb executable.
Index: config/i386/x86-64linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/x86-64linux.mh,v
retrieving revision 1.8
diff -u -p -r1.8 x86-64linux.mh
--- config/i386/x86-64linux.mh	31 May 2003 08:15:38 -0000	1.8
+++ config/i386/x86-64linux.mh	15 Jun 2003 20:55:48 -0000
@@ -5,6 +5,7 @@ XM_FILE= xm-i386.h
 NAT_FILE= nm-x86-64linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
 	core-regset.o i386-nat.o x86-64-linux-nat.o \
+	linux-nat.o \
 	proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o 
 
 # The dynamically loaded libthread_db needs access to symbols in the
Index: config/ia64/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/ia64/linux.mh,v
retrieving revision 1.13
diff -u -p -r1.13 linux.mh
--- config/ia64/linux.mh	4 Feb 2002 19:11:17 -0000	1.13
+++ config/ia64/linux.mh	15 Jun 2003 20:55:48 -0000
@@ -5,6 +5,6 @@ XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o gcore.o \
 	core-aout.o core-regset.o ia64-linux-nat.o linux-proc.o \
-	proc-service.o thread-db.o lin-lwp.o
+	proc-service.o thread-db.o lin-lwp.o linux-nat.o
 
 LOADLIBES = -ldl -rdynamic
Index: config/m68k/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/m68k/linux.mh,v
retrieving revision 1.10
diff -u -p -r1.10 linux.mh
--- config/m68k/linux.mh	14 Feb 2002 05:48:35 -0000	1.10
+++ config/m68k/linux.mh	15 Jun 2003 20:55:48 -0000
@@ -5,7 +5,7 @@ XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o \
 	corelow.o core-aout.o m68klinux-nat.o linux-proc.o gcore.o \
-	proc-service.o thread-db.o lin-lwp.o 
+	proc-service.o thread-db.o lin-lwp.o linux-nat.o
 
 # The dynamically loaded libthread_db needs access to symbols in the
 # gdb executable.
Index: config/mips/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/linux.mh,v
retrieving revision 1.4
diff -u -p -r1.4 linux.mh
--- config/mips/linux.mh	18 Jan 2002 04:51:03 -0000	1.4
+++ config/mips/linux.mh	15 Jun 2003 20:55:49 -0000
@@ -2,6 +2,7 @@
 XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o mips-linux-nat.o \
-	thread-db.o lin-lwp.o proc-service.o linux-proc.o gcore.o
+	thread-db.o lin-lwp.o proc-service.o linux-proc.o gcore.o \
+	linux-nat.o
 
 LOADLIBES = -ldl -rdynamic
Index: config/powerpc/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/powerpc/linux.mh,v
retrieving revision 1.12
diff -u -p -r1.12 linux.mh
--- config/powerpc/linux.mh	30 Jul 2002 19:03:49 -0000	1.12
+++ config/powerpc/linux.mh	15 Jun 2003 20:55:49 -0000
@@ -6,7 +6,7 @@ XM_CLIBS=
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o linux-proc.o \
 	ppc-linux-nat.o proc-service.o thread-db.o lin-lwp.o \
-	gcore.o
+	gcore.o linux-nat.o
 
 LOADLIBES = -ldl -rdynamic
 
Index: config/s390/s390.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/s390/s390.mh,v
retrieving revision 1.6
diff -u -p -r1.6 s390.mh
--- config/s390/s390.mh	28 Apr 2002 00:30:01 -0000	1.6
+++ config/s390/s390.mh	15 Jun 2003 20:55:49 -0000
@@ -6,7 +6,7 @@ XM_CLIBS=
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o s390-nat.o \
 	core-aout.o core-regset.o linux-proc.o gcore.o thread-db.o lin-lwp.o \
-	proc-service.o
+	proc-service.o linux-nat.o
 LOADLIBES = -ldl -rdynamic
 
 
Index: config/sparc/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/linux.mh,v
retrieving revision 1.9
diff -u -p -r1.9 linux.mh
--- config/sparc/linux.mh	4 May 2002 15:52:42 -0000	1.9
+++ config/sparc/linux.mh	15 Jun 2003 20:55:49 -0000
@@ -5,7 +5,7 @@ XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o \
 	proc-service.o thread-db.o lin-lwp.o sparc-linux-nat.o \
-	linux-proc.o gcore.o 
+	linux-proc.o gcore.o linux-nat.o
 
 # The dynamically loaded libthread_db needs access to symbols in the
 # gdb executable.


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