]> git.saurik.com Git - apple/xnu.git/blobdiff - tools/tests/xnu_quick_test/memory_tests.c
xnu-2782.40.9.tar.gz
[apple/xnu.git] / tools / tests / xnu_quick_test / memory_tests.c
index eb8817b9ad7849732c6079ac5a982b9fc868a97f..c14564a32ebd27590395713e71268a20d7b51e4a 100644 (file)
 
 extern char  g_target_path[ PATH_MAX ];
 
+/*
+ * static to localize to this compilation unit; volatile to avoid register
+ * optimization which would prevent modification by a signal handler.
+ */
+static volatile int    my_err;
+
+void
+bus_handler(int sig, siginfo_t *si, void *mcontext)
+{
+       /* Reset global error value when we see a SIGBUS */
+       if (sig == SIGBUS) {
+               _exit(0);
+       }
+}
+
 /*  **************************************************************************************************************
  *     Test madvise, mincore, minherit, mlock, mlock, mmap, mprotect, msync, munmap system calls.
  *     todo - see if Francois has better versions of these tests...
@@ -19,7 +34,6 @@ extern char  g_target_path[ PATH_MAX ];
  */
 int memory_tests( void * the_argp )
 {
-       int                     my_err;
        int                     my_page_size, my_status;
        int                     my_fd = -1;
        char *          my_pathp = NULL;
@@ -29,6 +43,7 @@ int memory_tests( void * the_argp )
        ssize_t         my_result;
        pid_t           my_pid, my_wait_pid;
        kern_return_t   my_kr;          
+       struct sigaction        my_sa;
 
         my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
         if(my_kr != KERN_SUCCESS){
@@ -252,18 +267,28 @@ int memory_tests( void * the_argp )
                        goto exit_child;
                }
 
+               my_sa.sa_sigaction = bus_handler;
+               my_sa.sa_flags = SA_SIGINFO | SA_RESETHAND;
+               if ((my_err = sigaction(SIGBUS, &my_sa, NULL)) != 0) {
+                       printf("sigaction call failed with error %d - \"%s\" \n", errno, strerror( errno) );
+                       my_err = -1;
+                       goto exit_child;
+               }
+
+               my_err = -1;    /* default to error out if we do NOT trigger a SIGBUS */
+
                *my_addr = 'z'; /* should cause SIGBUS signal (we look for this at child termination within the parent) */
-       
 
-                
-               my_err = 0;
+               /* NOTREACHED */
+
+               printf("Expected SIGBUS signal, got nothing!\n");
+               my_err = -1;
 exit_child:
                exit( my_err );
        }
 
-       
        /* parent process -
-        * we should get SIGBUS exit when child tries to write to read only memory 
+        * we should get no error if the child has completed all tests successfully
         */
        my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
        if ( my_wait_pid == -1 ) {
@@ -277,8 +302,10 @@ exit_child:
                goto test_failed_exit;
        }
 
-       if ( WIFSIGNALED( my_status ) && WTERMSIG( my_status ) != SIGBUS ) {
-               printf( "wait4 returned wrong signal status - 0x%02X \n", my_status );
+       /* If we did not exit cleanly, report it
+        */
+       if ( !WIFEXITED( my_status ) || (WEXITSTATUS( my_status ) != 0)) {
+               printf( "wait4 returned child died of status - 0x%08X \n", my_status );
                goto test_failed_exit;
        }