]>
git.saurik.com Git - apple/xnu.git/blob - tests/proc_core_name_24152432.c
1 #include <darwintest.h>
7 #include <sys/sysctl.h>
8 #include <sys/resource.h>
13 #include <TargetConditionals.h>
19 #define TIMEOUT 420 /* Timeout in seconds to wait for coredumps to appear */
21 static const char corefile_ctl
[] = "kern.corefile";
22 static const char coredump_ctl
[] = "kern.coredump";
23 /* The directory where coredumps will be */
24 static const char dump_dir
[] = "/cores";
25 /* The default coredump location if the kern.coredump ctl is invalid */
26 static const char default_dump_fmt
[] = "/cores/core.%d";
27 /* The coredump location when we set kern.coredump ctl to something valid */
28 static const char valid_dump_fmt
[] = "/cores/test-core.%d";
29 static const char ls_path
[] = "/bin/ls";
31 /* /cores/core.%(null), then BORK immediately after. */
32 static char evil
[] = "/cores/core.%\0BORK";
33 /* A valid coredump location to test. */
34 static char valid_dump_loc
[] = "/cores/test-core.%P";
36 static const struct rlimit lim_infty
= {
41 static volatile int stop_looking
= 0;
43 static const struct timespec timeout
= {
49 static int fork_and_wait_for_segfault(void);
52 sigalrm_handler(int sig
)
63 char buf
[BUFFLEN
] = { 0 };
65 T_LOG("Contents of %s:", dump_dir
);
66 snprintf(buf
, BUFFLEN
, "%s %s", ls_path
, dump_dir
);
68 T_ASSERT_POSIX_SUCCESS(ret
, "Listing contents of cores directory");
73 fork_and_wait_for_segfault()
78 unsigned int *ptr
= NULL
; /* Cause a segfault so that we get a coredump */
80 T_FAIL("Expected segmentation fault on write to NULL pointer");
82 T_ASSERT_TRUE(pid
!= -1, "Checking fork success in parent");
85 T_ASSERT_TRUE(ret
!= -1, "Waited for child to segfault and dump core");
90 setup_coredump_kevent(struct kevent
*kev
, int dir
)
95 EV_SET(kev
, dir
, EVFILT_VNODE
, EV_ADD
, NOTE_WRITE
, 0, NULL
);
97 T_ASSERT_POSIX_SUCCESS(kqfd
, "kqueue: get kqueue for coredump monitoring");
99 ret
= kevent(kqfd
, kev
, 1, NULL
, 0, NULL
);
100 T_ASSERT_POSIX_SUCCESS(ret
, "kevent: setup directory monitoring for coredump");
105 look_for_coredump(const char *format
, int pid
, int kqfd
, struct kevent
*kev
)
110 memset(buf
, 0, BUFFLEN
);
112 * Something else might touch this directory. If we get notified and don't see
113 * anything, try a few more times before failing.
116 while (!stop_looking
) {
117 /* Wait for kevent to tell us the coredump folder was modified */
118 ret
= kevent(kqfd
, NULL
, 0, kev
, 1, &timeout
);
119 T_ASSERT_POSIX_SUCCESS(ret
, "kevent: Waiting for coredump to appear");
121 snprintf(buf
, BUFFLEN
, format
, pid
);
128 T_LOG("Couldn't find coredump file (try #%d).", i
+ 1);
134 /* Couldn't find the coredump -- list contents of /cores */
135 list_coredump_files();
137 T_ASSERT_POSIX_SUCCESS(ret
, "Removing coredump file (should be at %s)", buf
);
141 sysctl_enable_coredumps(void)
144 int enable_core_dump
= 1;
145 size_t oldlen
= BUFFLEN
;
147 memset(buf
, 0, BUFFLEN
);
149 ret
= sysctlbyname(coredump_ctl
, buf
, &oldlen
, &enable_core_dump
, sizeof(int));
150 T_ASSERT_POSIX_SUCCESS(ret
, "sysctl: enable core dumps");
152 ret
= setrlimit(RLIMIT_CORE
, &lim_infty
);
153 T_ASSERT_POSIX_SUCCESS(ret
, "setrlimit: remove limit on maximum coredump size");
158 proc_core_name_24152432
,
159 "Tests behavior of core dump when kern.corefile ends in %, e.g., /cores/core.%",
161 T_META_IGNORECRASHES("proc_core_name_24152432.*"))
167 memset(buf
, 0, BUFFLEN
);
168 size_t oldlen
= BUFFLEN
;
173 sig
= signal(SIGALRM
, sigalrm_handler
);
174 T_WITH_ERRNO
; T_EXPECT_NE(sig
, SIG_ERR
, "signal: set sigalrm handler");
176 dirp
= opendir(dump_dir
);
177 T_ASSERT_NOTNULL(dirp
, "opendir: opening coredump directory");
179 T_ASSERT_POSIX_SUCCESS(dir
, "dirfd: getting file descriptor for coredump directory");
180 kqfd
= setup_coredump_kevent(&kev
, dir
);
182 sysctl_enable_coredumps();
184 ret
= sysctlbyname(corefile_ctl
, buf
, &oldlen
, evil
, EVILLEN
);
185 T_ASSERT_POSIX_SUCCESS(ret
, "sysctl: set bad core dump location, old value was %s", buf
);
186 memset(buf
, 0, BUFFLEN
);
189 pid
= fork_and_wait_for_segfault();
190 look_for_coredump(default_dump_fmt
, pid
, kqfd
, &kev
);
192 ret
= sysctlbyname(corefile_ctl
, buf
, &oldlen
, valid_dump_loc
, strlen(valid_dump_loc
));
193 T_ASSERT_POSIX_SUCCESS(ret
, "sysctl: set valid core dump location, old value was %s", buf
);
194 memset(buf
, 0, BUFFLEN
);
196 pid
= fork_and_wait_for_segfault();
197 look_for_coredump(valid_dump_fmt
, pid
, kqfd
, &kev
);
202 T_LOG("proc_core_name appears in OS X only, skipping test.");
204 T_PASS("proc_core_name_24152432 PASSED");