X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fnat%2Flinux-waitpid.c;h=f50e0c7bcff5575f0f5ed1ac63568efb1ce443d3;hb=1ee1a363454d88a87ad2ade7530b2a7fb670021e;hp=2debea488758d7722fbe148b873c883d38672d78;hpb=96d7229d2aa856ef96a420827f3e785081af66ea;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/nat/linux-waitpid.c b/gdb/nat/linux-waitpid.c index 2debea4887..f50e0c7bcf 100644 --- a/gdb/nat/linux-waitpid.c +++ b/gdb/nat/linux-waitpid.c @@ -1,6 +1,6 @@ /* Wrapper implementation for waitpid for GNU/Linux (LWP layer). - Copyright (C) 2001-2013 Free Software Foundation, Inc. + Copyright (C) 2001-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -17,104 +17,50 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifdef GDBSERVER -#include "server.h" -#else -#include "defs.h" -#include "signal.h" -#endif +#include "gdbsupport/common-defs.h" -#include "nat/linux-nat.h" -#include "nat/linux-waitpid.h" -#include "gdb_wait.h" +#include "linux-nat.h" +#include "linux-waitpid.h" +#include "gdbsupport/gdb_wait.h" -/* Print debugging output based on the format string FORMAT and - its parameters. */ +/* Convert wait status STATUS to a string. Used for printing debug + messages only. */ -static inline void -linux_debug (const char *format, ...) +char * +status_to_str (int status) { -#ifdef GDBSERVER - if (debug_threads) + static char buf[64]; + + if (WIFSTOPPED (status)) { - va_list args; - va_start (args, format); - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - va_end (args); + if (WSTOPSIG (status) == SYSCALL_SIGTRAP) + snprintf (buf, sizeof (buf), "%s (stopped at syscall)", + strsignal (SIGTRAP)); + else + snprintf (buf, sizeof (buf), "%s (stopped)", + strsignal (WSTOPSIG (status))); } -#else - /* GDB-specific debugging output. */ -#endif + else if (WIFSIGNALED (status)) + snprintf (buf, sizeof (buf), "%s (terminated)", + strsignal (WTERMSIG (status))); + else + snprintf (buf, sizeof (buf), "%d (exited)", WEXITSTATUS (status)); + + return buf; } -/* Wrapper function for waitpid which handles EINTR, and emulates - __WALL for systems where that is not available. */ +/* See linux-waitpid.h. */ int my_waitpid (int pid, int *status, int flags) { - int ret, out_errno; + int ret; - linux_debug ("my_waitpid (%d, 0x%x)\n", pid, flags); - - if (flags & __WALL) + do { - 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; - - linux_debug ("blocking\n"); - - /* Block waiting for signals. */ - sigsuspend (&wake_mask); - } - flags ^= __WCLONE; - } - - sigprocmask (SIG_SETMASK, &org_mask, NULL); + ret = waitpid (pid, status, flags); } - else - { - do - ret = waitpid (pid, status, flags); - while (ret == -1 && errno == EINTR); - out_errno = errno; - } - - linux_debug ("my_waitpid (%d, 0x%x): status(%x), %d\n", - pid, flags, status ? *status : -1, ret); + while (ret == -1 && errno == EINTR); - errno = out_errno; return ret; }