diff options
author | Daniel Jacobowitz <drow@false.org> | 2007-11-01 19:19:39 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2007-11-01 19:19:39 +0000 |
commit | 51c2684ec132409fcc073686f6eb2574c332b7c6 (patch) | |
tree | ddfb5bcab6fa3f1f3dbde954008c193c9b4cf97f | |
parent | 7ce189b305dfcd2d0c094d763696f71a67baaab3 (diff) | |
download | gdb-51c2684ec132409fcc073686f6eb2574c332b7c6.zip gdb-51c2684ec132409fcc073686f6eb2574c332b7c6.tar.gz gdb-51c2684ec132409fcc073686f6eb2574c332b7c6.tar.bz2 |
* linux-low.c (linux_tracefork_grandchild): New.
(linux_tracefork_child): Use clone.
(linux_test_for_tracefork): Use clone; allocate and free a stack.
-rw-r--r-- | gdb/gdbserver/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 26 |
2 files changed, 23 insertions, 9 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 518901e..4c56ce0 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -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. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index fb80020..9876491 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -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); } |