diff options
author | Doug Evans <dje@google.com> | 2009-12-19 01:16:23 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2009-12-19 01:16:23 +0000 |
commit | 07d4f67e9d89774b962d0b506e1b478125c6189a (patch) | |
tree | a3e1783cd5ae58209bba6b210e840d9201b2d637 /gdb | |
parent | f19732033aae407a0a93a6a8be70aa1cdb05a322 (diff) | |
download | gdb-07d4f67e9d89774b962d0b506e1b478125c6189a.zip gdb-07d4f67e9d89774b962d0b506e1b478125c6189a.tar.gz gdb-07d4f67e9d89774b962d0b506e1b478125c6189a.tar.bz2 |
* linux-low.c (my_waitpid): Move definition away from being in
between linux_tracefork_child/linux_test_for_tracefork.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 3 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 150 |
2 files changed, 78 insertions, 75 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index a0a8dd6..3699d1a 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,8 @@ 2009-12-18 Doug Evans <dje@google.com> + * linux-low.c (my_waitpid): Move definition away from being in + between linux_tracefork_child/linux_test_for_tracefork. + * gdb_proc_service.h (psaddr_t): Fix type. * thread-db.c (thread_db_info.td_thr_tls_get_addr_p): Fix signature to match glibc. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 2fc43f0..49460f8 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -272,6 +272,81 @@ linux_remove_process (struct process_info *process, int detaching) remove_process (process); } +/* Wrapper function for waitpid which handles EINTR, and emulates + __WALL for systems where that is not available. */ + +static int +my_waitpid (int pid, int *status, int flags) +{ + int ret, out_errno; + + if (debug_threads) + fprintf (stderr, "my_waitpid (%d, 0x%x)\n", pid, flags); + + if (flags & __WALL) + { + sigset_t block_mask, org_mask, wake_mask; + int wnohang; + + wnohang = (flags & WNOHANG) != 0; + flags &= ~(__WALL | __WCLONE); + flags |= WNOHANG; + + /* Block all signals while here. This avoids knowing about + LinuxThread's signals. */ + sigfillset (&block_mask); + sigprocmask (SIG_BLOCK, &block_mask, &org_mask); + + /* ... except during the sigsuspend below. */ + sigemptyset (&wake_mask); + + while (1) + { + /* Since all signals are blocked, there's no need to check + for EINTR here. */ + ret = waitpid (pid, status, flags); + out_errno = errno; + + if (ret == -1 && out_errno != ECHILD) + break; + else if (ret > 0) + break; + + if (flags & __WCLONE) + { + /* We've tried both flavors now. If WNOHANG is set, + there's nothing else to do, just bail out. */ + if (wnohang) + break; + + if (debug_threads) + fprintf (stderr, "blocking\n"); + + /* Block waiting for signals. */ + sigsuspend (&wake_mask); + } + + flags ^= __WCLONE; + } + + sigprocmask (SIG_SETMASK, &org_mask, NULL); + } + else + { + do + ret = waitpid (pid, status, flags); + while (ret == -1 && errno == EINTR); + out_errno = errno; + } + + if (debug_threads) + fprintf (stderr, "my_waitpid (%d, 0x%x): status(%x), %d\n", + pid, flags, status ? *status : -1, ret); + + errno = out_errno; + return ret; +} + /* Handle a GNU/Linux extended wait response. If we see a clone event, we need to add the new LWP to our list (and not report the trap to higher layers). */ @@ -2475,81 +2550,6 @@ linux_tracefork_child (void *arg) _exit (0); } -/* Wrapper function for waitpid which handles EINTR, and emulates - __WALL for systems where that is not available. */ - -static int -my_waitpid (int pid, int *status, int flags) -{ - int ret, out_errno; - - if (debug_threads) - fprintf (stderr, "my_waitpid (%d, 0x%x)\n", pid, flags); - - if (flags & __WALL) - { - sigset_t block_mask, org_mask, wake_mask; - int wnohang; - - wnohang = (flags & WNOHANG) != 0; - flags &= ~(__WALL | __WCLONE); - flags |= WNOHANG; - - /* Block all signals while here. This avoids knowing about - LinuxThread's signals. */ - sigfillset (&block_mask); - sigprocmask (SIG_BLOCK, &block_mask, &org_mask); - - /* ... except during the sigsuspend below. */ - sigemptyset (&wake_mask); - - while (1) - { - /* Since all signals are blocked, there's no need to check - for EINTR here. */ - ret = waitpid (pid, status, flags); - out_errno = errno; - - if (ret == -1 && out_errno != ECHILD) - break; - else if (ret > 0) - break; - - if (flags & __WCLONE) - { - /* We've tried both flavors now. If WNOHANG is set, - there's nothing else to do, just bail out. */ - if (wnohang) - break; - - if (debug_threads) - fprintf (stderr, "blocking\n"); - - /* Block waiting for signals. */ - sigsuspend (&wake_mask); - } - - flags ^= __WCLONE; - } - - sigprocmask (SIG_SETMASK, &org_mask, NULL); - } - else - { - do - ret = waitpid (pid, status, flags); - while (ret == -1 && errno == EINTR); - out_errno = errno; - } - - if (debug_threads) - fprintf (stderr, "my_waitpid (%d, 0x%x): status(%x), %d\n", - pid, flags, status ? *status : -1, ret); - - errno = out_errno; - return ret; -} - /* Determine if PTRACE_O_TRACEFORK can be used to follow fork events. Make sure that we can enable the option, and that it had the desired effect. */ |