[testsuite] asan/clone-test-1.c: Handle clone() failure
[official-gcc.git] / gcc / testsuite / c-c++-common / asan / clone-test-1.c
blobc58c376f5dfe43cd1acdd166c86c4e8570b91628
1 /* Regression test for:
2 http://code.google.com/p/address-sanitizer/issues/detail?id=37 */
4 /* { dg-do run { target { *-*-linux* } } } */
5 /* { dg-require-effective-target clone } */
6 /* { dg-require-effective-target hw } */
7 /* { dg-options "-D_GNU_SOURCE" } */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sched.h>
12 #include <sys/syscall.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <unistd.h>
17 int Child(void *arg) {
18 char x[32] = {0}; /* Stack gets poisoned. */
19 printf("Child: %p\n", x);
20 _exit(1); /* NoReturn, stack will remain unpoisoned unless we do something. */
23 volatile int zero = 0;
25 int main(int argc, char **argv) {
26 int i;
27 const int kStackSize = 1 << 20;
28 char __attribute__((aligned(16))) child_stack[kStackSize + 1];
29 char *sp = child_stack + kStackSize; /* Stack grows down. */
30 printf("Parent: %p\n", sp);
31 pid_t clone_pid = clone(Child, sp, CLONE_FILES | CLONE_VM, NULL, 0, 0, 0);
32 if (clone_pid == -1) {
33 perror("clone");
34 return 1;
36 int status;
37 pid_t wait_result = waitpid(clone_pid, &status, __WCLONE);
38 if (wait_result < 0) {
39 perror("waitpid");
40 return 1;
42 if (wait_result == clone_pid && WIFEXITED(status)) {
43 /* Make sure the child stack was indeed unpoisoned. */
44 for (i = 0; i < kStackSize; i++)
45 child_stack[i] = i;
46 int ret = child_stack[zero];
47 return ret;
49 return 1;