aboutsummaryrefslogtreecommitdiff
path: root/gdb/linux-nat.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2004-03-29 18:07:14 +0000
committerDaniel Jacobowitz <drow@false.org>2004-03-29 18:07:14 +0000
commita2f23071c92ee8e0ad72cef70e82af6192b48ba9 (patch)
tree42d5acab992069bc32ad50036e985434d3e25e50 /gdb/linux-nat.c
parent8d5f9dcb37b90814ac723d46d5b93169da19e391 (diff)
downloadgdb-a2f23071c92ee8e0ad72cef70e82af6192b48ba9.zip
gdb-a2f23071c92ee8e0ad72cef70e82af6192b48ba9.tar.gz
gdb-a2f23071c92ee8e0ad72cef70e82af6192b48ba9.tar.bz2
* Makefile.in (linux_nat_h): Update dependencies.
* configure.in: Check for <gnu/libc-version.h>. * configure: Regenerate. * config.in: Regenerate. * linux-nat.h: Include "target.h". Add waitstatus field to struct lwp_info. * lin-lwp.c (add_lwp): Initialize waitstatus.kind. (lin_lwp_attach_lwp): Don't attach to LWPs we have already attached to. (lin_lwp_handle_extended): New function. Handle clone events. (wait_lwp): Use lin_lwp_handle_extended. Update comment about thread exit events. (child_wait): Handle clone events. (lin_lwp_wait: Use lin_lwp_handle_extended and handle clone events. * linux-nat.c (linux_enable_event_reporting): Turn on PTRACE_O_TRACECLONE. (linux_handle_extended_wait): Handle clone events. * thread-db.c: Include <gnu/libc-version.h>. (struct private_thread_info): Add dying flag. (enable_thread_event_reporting): Enable TD_DEATH for glibc 2.2 and higher. (attach_thread): Update comments. Handle dying threads. (detach_thread): Set the dying flag. (check_event): Always call attach_thread.
Diffstat (limited to 'gdb/linux-nat.c')
-rw-r--r--gdb/linux-nat.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 2680422..e421c9c 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -1,5 +1,5 @@
/* GNU/Linux native-dependent code common to multiple platforms.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GDB.
@@ -224,7 +224,8 @@ linux_enable_event_reporting (ptid_t ptid)
if (! linux_supports_tracefork ())
return;
- options = PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXEC;
+ options = PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXEC
+ | PTRACE_O_TRACECLONE;
if (linux_supports_tracevforkdone ())
options |= PTRACE_O_TRACEVFORKDONE;
@@ -391,11 +392,8 @@ linux_handle_extended_wait (int pid, int status,
{
int event = status >> 16;
- if (event == PTRACE_EVENT_CLONE)
- internal_error (__FILE__, __LINE__,
- "unexpected clone event");
-
- if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK)
+ if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK
+ || event == PTRACE_EVENT_CLONE)
{
unsigned long new_pid;
int ret;
@@ -406,12 +404,10 @@ linux_handle_extended_wait (int pid, int status,
if (! pull_pid_from_list (&stopped_pids, new_pid))
{
/* The new child has a pending SIGSTOP. We can't affect it until it
- hits the SIGSTOP, but we're already attached.
-
- It won't be a clone (we didn't ask for clones in the event mask)
- so we can just call waitpid and wait for the SIGSTOP. */
+ hits the SIGSTOP, but we're already attached. */
do {
- ret = waitpid (new_pid, &status, 0);
+ ret = waitpid (new_pid, &status,
+ (event == PTRACE_EVENT_CLONE) ? __WCLONE : 0);
} while (ret == -1 && errno == EINTR);
if (ret == -1)
perror_with_name ("waiting for new child");
@@ -423,8 +419,13 @@ linux_handle_extended_wait (int pid, int status,
"wait returned unexpected status 0x%x", status);
}
- ourstatus->kind = (event == PTRACE_EVENT_FORK)
- ? TARGET_WAITKIND_FORKED : TARGET_WAITKIND_VFORKED;
+ if (event == PTRACE_EVENT_FORK)
+ ourstatus->kind = TARGET_WAITKIND_FORKED;
+ else if (event == PTRACE_EVENT_VFORK)
+ ourstatus->kind = TARGET_WAITKIND_VFORKED;
+ else
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+
ourstatus->value.related_pid = new_pid;
return inferior_ptid;
}