#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <linux/unistd.h>
+#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <pthread.h>
+#include <sys/syscall.h>
#include "debugger.h"
#include "debugger.c"
-_syscall2(int, tkill, int, tid, int, sig)
-int tkill(int tid, int sig);
+#define tkill(tid, sig) syscall (SYS_tkill, (tid), (sig))
static int attach_checked (pid_t pid, int redelivered_expect)
struct registry *iter;
for (iter = registry_list; iter != NULL; iter = iter->next)
- kill (iter->pid, SIGKILL);
+ {
+ tkill (iter->pid, SIGCONT);
+ tkill (iter->pid, SIGKILL);
+ kill (iter->pid, SIGKILL);
+ }
+}
+
+static void registry_cleanup (void)
+{
+ struct registry *iter;
+ pid_t pid;
+
+ registry_atexit ();
+ while ((pid = wait (NULL)) != -1)
+ {
+ for (iter = registry_list; iter != NULL; iter = iter->next)
+ if (iter->pid == pid)
+ break;
+ assert (iter != NULL);
+ }
+ assert (errno == ECHILD);
+ while (registry_list)
+ {
+ iter = registry_list;
+ registry_list = iter->next;
+ free (iter);
+ }
}
static void registry_handler (int signo)
delay ();
i = tkill (inferior, SIGSTOP);
assert (i == 0);
+ /* Wait till it gets stopped otherwise we may get STATE_ENOENT below. */
+ STATE (inferior, 1 << STATE_STOPPED);
delay ();
i = tkill (inferior, SIGALRM);
assert (i == 0);
delay ();
i = tkill (inferior, SIGCONT);
assert (i == 0);
+ /* This is a race, we may not prove the successful SIGALRM delivery by it. */
STATE (inferior, 1 << STATE_RUNNING);
murder (inferior);
}
body_spawner (spawn_with_waiter, ¶m_local, NULL);
}
+static volatile unsigned long loops = 0;
+static volatile int loops_print = 0;
+
+static void handler_sigusr1 (int signo)
+{
+ assert (signo == SIGUSR1);
+
+ loops_print++;
+}
+
int main (int argc, char **argv)
{
+ int loop = 0;
+ int i;
+
+ if (argc == 1)
+ ;
+ else if (argc == 2 && strcmp (argv[1], "-l") == 0)
+ loop = 1;
+ else
+ abort ();
+
+ i = nice (10);
+ assert (i != -1);
+
atexit (registry_atexit);
signal (SIGINT, registry_handler);
signal (SIGABRT, registry_handler);
- body_maywaiter (spawn_singlethreaded, NULL, NULL);
- body_maywaiter (spawn_threaded_parent, NULL, NULL);
- body_maywaiter (spawn_threaded_child, NULL, NULL);
+ signal (SIGUSR1, handler_sigusr1);
+
+ do
+ {
+ while (loops_print > 0)
+ {
+ printf ("%lu\n", loops);
+ loops_print--;
+ }
+ body_maywaiter (spawn_singlethreaded, NULL, NULL);
+ body_maywaiter (spawn_threaded_parent, NULL, NULL);
+ body_maywaiter (spawn_threaded_child, NULL, NULL);
+
+ registry_cleanup ();
+ loops++;
+ }
+ while (loop != 0);
return EXIT_SUCCESS;
}