This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit] Fix gdbserver build on uClinux
- From: Daniel Jacobowitz <drow at false dot org>
- To: gdb-patches at sourceware dot org
- Date: Thu, 1 Nov 2007 15:21:50 -0400
- Subject: [commit] Fix gdbserver build on uClinux
uClinux does not have fork. So here's an improved fork events test
that uses clone (CLONE_VM) instead, which works on both Linux and
uClinux. It fails on the only uClinux board I found to test, but
that's because PTRACE_SETOPTIONS returned -EIO; something must be
wrong in its kernel.
Committed.
--
Daniel Jacobowitz
CodeSourcery
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.
Index: linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.64
diff -u -p -r1.64 linux-low.c
--- linux-low.c 24 Oct 2007 13:27:01 -0000 1.64
+++ linux-low.c 1 Nov 2007 17:54:44 -0000
@@ -1732,14 +1732,20 @@ linux_write_memory (CORE_ADDR memaddr, c
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);
}