mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-12 14:20:13 +00:00
malloc/tst-mallocfork2: Kill lingering process for unexpected failures
If the test fails due some unexpected failure after the children creation, either in the signal handler by calling abort or in the main loop; the created children might not be killed properly. This patches fixes it by: * Avoid aborting in the signal handler by setting a flag that an error has occured and add a check in the main loop. * Add a atexit handler to handle kill child processes. Checked on x86_64-linux-gnu.
This commit is contained in:
parent
74d9b0811e
commit
d53f5cac50
@ -62,6 +62,9 @@ static volatile sig_atomic_t sigusr1_received;
|
|||||||
progress. Checked by liveness_signal_handler. */
|
progress. Checked by liveness_signal_handler. */
|
||||||
static volatile sig_atomic_t progress_indicator = 1;
|
static volatile sig_atomic_t progress_indicator = 1;
|
||||||
|
|
||||||
|
/* Set to 1 if an error occurs in the signal handler. */
|
||||||
|
static volatile sig_atomic_t error_indicator = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sigusr1_handler (int signo)
|
sigusr1_handler (int signo)
|
||||||
{
|
{
|
||||||
@ -72,7 +75,8 @@ sigusr1_handler (int signo)
|
|||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
{
|
{
|
||||||
write_message ("error: fork\n");
|
write_message ("error: fork\n");
|
||||||
abort ();
|
error_indicator = 1;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
_exit (0);
|
_exit (0);
|
||||||
@ -81,12 +85,14 @@ sigusr1_handler (int signo)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
write_message ("error: waitpid\n");
|
write_message ("error: waitpid\n");
|
||||||
abort ();
|
error_indicator = 1;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
write_message ("error: unexpected exit status from subprocess\n");
|
write_message ("error: unexpected exit status from subprocess\n");
|
||||||
abort ();
|
error_indicator = 1;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,9 +128,25 @@ signal_sender (int signo, bool sleep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Children processes. */
|
||||||
|
static pid_t sigusr1_sender_pids[5] = { 0 };
|
||||||
|
static pid_t sigusr2_sender_pid = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
kill_children (void)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
|
||||||
|
if (sigusr1_sender_pids[i] > 0)
|
||||||
|
kill (sigusr1_sender_pids[i], SIGKILL);
|
||||||
|
if (sigusr2_sender_pid > 0)
|
||||||
|
kill (sigusr2_sender_pid, SIGKILL);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_test (void)
|
do_test (void)
|
||||||
{
|
{
|
||||||
|
atexit (kill_children);
|
||||||
|
|
||||||
/* shared->barrier is intialized along with sigusr1_sender_pids
|
/* shared->barrier is intialized along with sigusr1_sender_pids
|
||||||
below. */
|
below. */
|
||||||
shared = support_shared_allocate (sizeof (*shared));
|
shared = support_shared_allocate (sizeof (*shared));
|
||||||
@ -148,14 +170,13 @@ do_test (void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t sigusr2_sender_pid = xfork ();
|
sigusr2_sender_pid = xfork ();
|
||||||
if (sigusr2_sender_pid == 0)
|
if (sigusr2_sender_pid == 0)
|
||||||
signal_sender (SIGUSR2, true);
|
signal_sender (SIGUSR2, true);
|
||||||
|
|
||||||
/* Send SIGUSR1 signals from several processes. Hopefully, one
|
/* Send SIGUSR1 signals from several processes. Hopefully, one
|
||||||
signal will hit one of the ciritical functions. Use a barrier to
|
signal will hit one of the ciritical functions. Use a barrier to
|
||||||
avoid sending signals while not running fork/free/malloc. */
|
avoid sending signals while not running fork/free/malloc. */
|
||||||
pid_t sigusr1_sender_pids[5];
|
|
||||||
{
|
{
|
||||||
pthread_barrierattr_t attr;
|
pthread_barrierattr_t attr;
|
||||||
xpthread_barrierattr_init (&attr);
|
xpthread_barrierattr_init (&attr);
|
||||||
@ -166,7 +187,7 @@ do_test (void)
|
|||||||
}
|
}
|
||||||
for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
|
for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
|
||||||
{
|
{
|
||||||
sigusr1_sender_pids[i] = fork ();
|
sigusr1_sender_pids[i] = xfork ();
|
||||||
if (sigusr1_sender_pids[i] == 0)
|
if (sigusr1_sender_pids[i] == 0)
|
||||||
signal_sender (SIGUSR1, false);
|
signal_sender (SIGUSR1, false);
|
||||||
}
|
}
|
||||||
@ -211,7 +232,7 @@ do_test (void)
|
|||||||
++malloc_signals;
|
++malloc_signals;
|
||||||
xpthread_barrier_wait (&shared->barrier);
|
xpthread_barrier_wait (&shared->barrier);
|
||||||
|
|
||||||
if (objects[slot] == NULL)
|
if (objects[slot] == NULL || error_indicator != 0)
|
||||||
{
|
{
|
||||||
printf ("error: malloc: %m\n");
|
printf ("error: malloc: %m\n");
|
||||||
for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
|
for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
|
||||||
@ -225,10 +246,6 @@ do_test (void)
|
|||||||
for (int slot = 0; slot < malloc_objects; ++slot)
|
for (int slot = 0; slot < malloc_objects; ++slot)
|
||||||
free (objects[slot]);
|
free (objects[slot]);
|
||||||
|
|
||||||
for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
|
|
||||||
kill (sigusr1_sender_pids[i], SIGKILL);
|
|
||||||
kill (sigusr2_sender_pid, SIGKILL);
|
|
||||||
|
|
||||||
printf ("info: signals received during fork: %u\n", fork_signals);
|
printf ("info: signals received during fork: %u\n", fork_signals);
|
||||||
printf ("info: signals received during free: %u\n", free_signals);
|
printf ("info: signals received during free: %u\n", free_signals);
|
||||||
printf ("info: signals received during malloc: %u\n", malloc_signals);
|
printf ("info: signals received during malloc: %u\n", malloc_signals);
|
||||||
|
Loading…
Reference in New Issue
Block a user