Set the glibc thread's pointer_guard (XCC)
[akaros.git] / user / utest / atexit.c
1 /* Copyright (c) 2016 Google, Inc.
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details. */
4
5 #include <utest/utest.h>
6 #include <pthread.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 /* This tests a bug where if a thread other than thread0 registered an atexit()
11  * function, we'd GPF when thread0 exited.  Due to the way our infrastructure
12  * prints tests results before the program exited, you may see this say that the
13  * test succeeded, but then fail later with a GPF or other assertion. */
14
15 TEST_SUITE("AT-EXIT");
16
17 /* <--- Begin definition of test cases ---> */
18
19 static bool child_ran_atexit = FALSE;
20
21 static void child_atexit(void)
22 {
23         child_ran_atexit = TRUE;
24 }
25
26 static void *child_func(void *arg)
27 {
28         atexit(child_atexit);
29         return 0;
30 }
31
32 static void main_atexit(void)
33 {
34         /* Using the non-UT assert, since the test_atexit_threads() has already
35          * returned.  Also, since the child called atexit() after main, its handler
36          * should run first, according to the man page. */
37         assert(child_ran_atexit);
38 }
39
40 bool test_atexit_threads(void)
41 {
42         pthread_t child;
43         void *child_ret;
44
45         atexit(main_atexit);
46         pthread_create(&child, NULL, &child_func, NULL);
47         pthread_join(child, &child_ret);
48         return TRUE;
49 }
50
51 /* <--- End definition of test cases ---> */
52
53 struct utest utests[] = {
54         UTEST_REG(atexit_threads),
55 };
56 int num_utests = sizeof(utests) / sizeof(struct utest);
57
58 int main(int argc, char *argv[])
59 {
60         // Run test suite passing it all the args as whitelist of what tests to run.
61         char **whitelist = &argv[1];
62         int whitelist_len = argc - 1;
63
64         RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
65 }