]>
Commit | Line | Data |
---|---|---|
c3c9b80d A |
1 | #include <unistd.h> |
2 | #include <stdio.h> | |
3 | ||
4 | #include <darwintest.h> | |
5 | #include <darwintest_utils.h> | |
6 | ||
7 | T_GLOBAL_META(T_META_RUN_CONCURRENTLY(false)); | |
8 | ||
9 | /* | |
10 | * No system(3c) on watchOS, so provide our own. | |
11 | * returns -1 if fails to run | |
12 | * returns 0 if process exits normally. | |
13 | * returns +n if process exits due to signal N | |
14 | */ | |
15 | static int | |
16 | my_system(const char *command) | |
17 | { | |
18 | pid_t pid; | |
19 | int status = 0; | |
20 | int signal = 0; | |
21 | int err; | |
22 | const char *argv[] = { | |
23 | "/bin/sh", | |
24 | "-c", | |
25 | command, | |
26 | NULL | |
27 | }; | |
28 | ||
29 | if (dt_launch_tool(&pid, (char **)(void *)argv, FALSE, NULL, NULL)) { | |
30 | return -1; | |
31 | } | |
32 | ||
33 | err = dt_waitpid(pid, &status, &signal, 30); | |
34 | if (err) { | |
35 | return 0; | |
36 | } | |
37 | ||
38 | return signal; | |
39 | } | |
40 | ||
41 | ||
42 | /* | |
43 | * The tests are run in the following order: | |
44 | * | |
45 | * - call foo | |
46 | * - corrupt foo, then call foo | |
47 | * - call foo | |
48 | * | |
49 | * - call atan | |
50 | * - corrupt atan, then call atan | |
51 | * - call atan | |
52 | * | |
53 | * The first and last of each should exit normally. The middle one should exit with SIGILL. | |
54 | * | |
55 | * atan() was picked as a shared region function that isn't likely used by any normal daemons. | |
56 | */ | |
57 | T_DECL(text_corruption_recovery, "test detection/recovery of text corruption", | |
58 | T_META_IGNORECRASHES(".*text_corruption_helper.*"), | |
59 | T_META_ASROOT(true)) | |
60 | { | |
61 | int ret; | |
62 | ||
63 | ret = my_system("./text_corruption_helper foo"); | |
64 | T_QUIET; T_ASSERT_EQ(ret, 0, "First call of foo"); | |
65 | ||
66 | ret = my_system("./text_corruption_helper Xfoo"); | |
67 | T_QUIET; T_ASSERT_EQ(ret, SIGILL, "Call of corrupted foo"); | |
68 | ||
69 | ret = my_system("./text_corruption_helper foo"); | |
70 | T_QUIET; T_ASSERT_EQ(ret, 0, "Fixed call of foo"); | |
71 | ||
72 | ret = my_system("./text_corruption_helper atan"); | |
73 | T_QUIET; T_ASSERT_EQ(ret, 0, "First call of atan"); | |
74 | ||
75 | ret = my_system("./text_corruption_helper Xatan"); | |
76 | T_QUIET; T_ASSERT_EQ(ret, SIGILL, "Call of corrupted atan"); | |
77 | ||
78 | ret = my_system("./text_corruption_helper atan"); | |
79 | T_QUIET; T_ASSERT_EQ(ret, 0, "Fixed call of atan"); | |
80 | } |