* linux-low.c (linux_tracefork_grandchild): New.
authorDaniel Jacobowitz <drow@false.org>
Thu, 1 Nov 2007 19:19:39 +0000 (19:19 +0000)
committerDaniel Jacobowitz <drow@false.org>
Thu, 1 Nov 2007 19:19:39 +0000 (19:19 +0000)
(linux_tracefork_child): Use clone.
(linux_test_for_tracefork): Use clone; allocate and free a stack.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c

index 518901eaeb6fe53e8260c18476ba304e12565394..4c56ce0863ec39852363f487490e29c77e3ce2e6 100644 (file)
@@ -1,3 +1,9 @@
+2007-11-01  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * linux-low.c (linux_tracefork_grandchild): New.
+       (linux_tracefork_child): Use clone.
+       (linux_test_for_tracefork): Use clone; allocate and free a stack.
+
 2007-10-31  Joel Brobecker  <brobecker@adacore.com>
 
        * Makefile.in: Use $(SHELL) instead of "sh" to call regdat.sh.
index fb8002088efb035a4abc8754b8c7fb809d7892a5..987649163f1d74756e532200f690145af8e6fdae 100644 (file)
@@ -1732,14 +1732,20 @@ linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 
 static int linux_supports_tracefork_flag;
 
-/* A helper function for linux_test_for_tracefork, called after fork ().  */
+/* Helper functions for linux_test_for_tracefork, called via clone ().  */
 
-static void
-linux_tracefork_child (void)
+static int
+linux_tracefork_grandchild (void *arg)
+{
+  _exit (0);
+}
+
+static int
+linux_tracefork_child (void *arg)
 {
   ptrace (PTRACE_TRACEME, 0, 0, 0);
   kill (getpid (), SIGSTOP);
-  fork ();
+  clone (linux_tracefork_grandchild, arg, CLONE_VM | SIGCHLD, NULL);
   _exit (0);
 }
 
@@ -1767,15 +1773,15 @@ linux_test_for_tracefork (void)
 {
   int child_pid, ret, status;
   long second_pid;
+  char *stack = malloc (8192);
 
   linux_supports_tracefork_flag = 0;
 
-  child_pid = fork ();
+  /* Use CLONE_VM instead of fork, to support uClinux (no MMU).  */
+  child_pid = clone (linux_tracefork_child, stack + 2048,
+                    CLONE_VM | SIGCHLD, stack + 6144);
   if (child_pid == -1)
-    perror_with_name ("fork");
-
-  if (child_pid == 0)
-    linux_tracefork_child ();
+    perror_with_name ("clone");
 
   ret = my_waitpid (child_pid, &status, 0);
   if (ret == -1)
@@ -1840,6 +1846,8 @@ linux_test_for_tracefork (void)
       my_waitpid (child_pid, &status, 0);
     }
   while (WIFSTOPPED (status));
+
+  free (stack);
 }