]>
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");