* defs.h (wait_to_die_with_timeout): Declare.
* utils.c: #include "gdb_wait.h". (sigalrm_handler, wait_to_die_with_timeout): New functions. * ser-pipe.c: Don't #include "gdb_wait.h". (pipe_close): Give child a chance to die on its own after closing its stdin before SIGTERM'ing it.
This commit is contained in:
parent
afaabefa90
commit
0b6cb71e50
4 changed files with 106 additions and 5 deletions
|
@ -1,3 +1,12 @@
|
|||
2011-12-14 Doug Evans <dje@google.com>
|
||||
|
||||
* defs.h (wait_to_die_with_timeout): Declare.
|
||||
* utils.c: #include "gdb_wait.h".
|
||||
(sigalrm_handler, wait_to_die_with_timeout): New functions.
|
||||
* ser-pipe.c: Don't #include "gdb_wait.h".
|
||||
(pipe_close): Give child a chance to die on its own after closing
|
||||
its stdin before SIGTERM'ing it.
|
||||
|
||||
2011-12-14 Joel Brobecker <brobecker@adacore.com>
|
||||
Tom Tromey <tromey@redhat.com>
|
||||
|
||||
|
|
|
@ -440,6 +440,10 @@ extern struct cleanup *make_bpstat_clear_actions_cleanup (void);
|
|||
|
||||
extern int producer_is_gcc_ge_4 (const char *producer);
|
||||
|
||||
#ifdef HAVE_WAITPID
|
||||
extern pid_t wait_to_die_with_timeout (pid_t pid, int *status, int timeout);
|
||||
#endif
|
||||
|
||||
|
||||
/* Annotation stuff. */
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include "gdb_string.h"
|
||||
#include "gdb_wait.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
|
@ -163,14 +162,30 @@ pipe_close (struct serial *scb)
|
|||
|
||||
if (state != NULL)
|
||||
{
|
||||
int status;
|
||||
kill (state->pid, SIGTERM);
|
||||
#ifdef HAVE_WAITPID
|
||||
int wait_result, status;
|
||||
|
||||
/* Don't kill the task right away, give it a chance to shut down cleanly.
|
||||
But don't wait forever though. */
|
||||
#define PIPE_CLOSE_TIMEOUT 5
|
||||
|
||||
/* Assume the program will exit after SIGTERM. Might be
|
||||
useful to print any remaining stderr output from
|
||||
scb->error_fd while waiting. */
|
||||
waitpid (state->pid, &status, 0);
|
||||
#define SIGTERM_TIMEOUT INT_MAX
|
||||
|
||||
wait_result = -1;
|
||||
#ifdef HAVE_WAITPID
|
||||
wait_result = wait_to_die_with_timeout (state->pid, &status,
|
||||
PIPE_CLOSE_TIMEOUT);
|
||||
#endif
|
||||
if (wait_result == -1)
|
||||
{
|
||||
kill (state->pid, SIGTERM);
|
||||
#ifdef HAVE_WAITPID
|
||||
wait_to_die_with_timeout (state->pid, &status, SIGTERM_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (scb->error_fd != -1)
|
||||
close (scb->error_fd);
|
||||
scb->error_fd = -1;
|
||||
|
|
73
gdb/utils.c
73
gdb/utils.c
|
@ -24,6 +24,7 @@
|
|||
#include "gdb_assert.h"
|
||||
#include <ctype.h>
|
||||
#include "gdb_string.h"
|
||||
#include "gdb_wait.h"
|
||||
#include "event-top.h"
|
||||
#include "exceptions.h"
|
||||
#include "gdbthread.h"
|
||||
|
@ -3784,6 +3785,78 @@ producer_is_gcc_ge_4 (const char *producer)
|
|||
return minor;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAITPID
|
||||
|
||||
#ifdef SIGALRM
|
||||
|
||||
/* SIGALRM handler for waitpid_with_timeout. */
|
||||
|
||||
static void
|
||||
sigalrm_handler (int signo)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Wrapper to wait for child PID to die with TIMEOUT.
|
||||
TIMEOUT is the time to stop waiting in seconds.
|
||||
If TIMEOUT is zero, pass WNOHANG to waitpid.
|
||||
Returns PID if it was successfully waited for, otherwise -1.
|
||||
|
||||
Timeouts are currently implemented with alarm and SIGALRM.
|
||||
If the host does not support them, this waits "forever".
|
||||
It would be odd though for a host to have waitpid and not SIGALRM. */
|
||||
|
||||
pid_t
|
||||
wait_to_die_with_timeout (pid_t pid, int *status, int timeout)
|
||||
{
|
||||
pid_t waitpid_result;
|
||||
|
||||
gdb_assert (pid > 0);
|
||||
gdb_assert (timeout >= 0);
|
||||
|
||||
if (timeout > 0)
|
||||
{
|
||||
#ifdef SIGALRM
|
||||
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
|
||||
struct sigaction sa, old_sa;
|
||||
|
||||
sa.sa_handler = sigalrm_handler;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction (SIGALRM, &sa, &old_sa);
|
||||
#else
|
||||
void (*ofunc) ();
|
||||
|
||||
ofunc = (void (*)()) signal (SIGALRM, sigalrm_handler);
|
||||
#endif
|
||||
|
||||
alarm (timeout);
|
||||
#endif
|
||||
|
||||
waitpid_result = waitpid (pid, status, 0);
|
||||
|
||||
#ifdef SIGALRM
|
||||
alarm (0);
|
||||
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
|
||||
sigaction (SIGALRM, &old_sa, NULL);
|
||||
#else
|
||||
signal (SIGALRM, ofunc);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
waitpid_result = waitpid (pid, status, WNOHANG);
|
||||
|
||||
if (waitpid_result == pid)
|
||||
return pid;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* HAVE_WAITPID */
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_utils;
|
||||
|
||||
|
|
Loading…
Reference in a new issue