]> git.saurik.com Git - apple/system_cmds.git/commitdiff
system_cmds-671.10.3.tar.gz os-x-10112 os-x-10113 os-x-10114 os-x-10115 os-x-10116 v671.10.3
authorApple <opensource@apple.com>
Wed, 9 Dec 2015 05:23:10 +0000 (05:23 +0000)
committerApple <opensource@apple.com>
Wed, 9 Dec 2015 05:23:10 +0000 (05:23 +0000)
lsmp.tproj/common.h
lsmp.tproj/lsmp.c
lsmp.tproj/port_details.c
lsmp.tproj/task_details.c
system_cmds.xcodeproj/project.pbxproj
tests/system_cmds.plist [new file with mode: 0644]

index 6f9ca37809291bcd7b0adae17b686ddae3a27e2b..cfc29fd36c357a72d9a09ca6c14504bcd6f56b7b 100644 (file)
 #ifndef system_cmds_common_h
 #define system_cmds_common_h
 
+#include <mach/mach.h>
+
 #define PROC_NAME_LEN 100
 #define BUFSTR_LEN 30
-
+#define VOUCHER_DETAIL_MAXLEN 1024
 
 /* common struct to hold all configurations, static and args based */
 struct prog_configs {
@@ -40,6 +42,23 @@ struct prog_configs {
 
 extern struct prog_configs lsmp_config;
 
+/* exception port information */
+struct exc_port_info {
+    mach_msg_type_number_t   count;
+    mach_port_t      ports[EXC_TYPES_COUNT];
+    exception_mask_t masks[EXC_TYPES_COUNT];
+    exception_behavior_t behaviors[EXC_TYPES_COUNT];
+    thread_state_flavor_t flavors[EXC_TYPES_COUNT];
+};
+
+/* private structure to hold thread specific information */
+struct my_per_thread_info {
+    mach_port_t thread;
+    uint32_t th_kobject;
+    uint64_t th_id;
+    char * voucher_detail;
+};
+
 /* private structure to wrap up per-task info */
 typedef struct my_per_task_info {
     task_t task;
@@ -52,6 +71,10 @@ typedef struct my_per_task_info {
     mach_msg_type_number_t treeCount;
     boolean_t valid; /* TRUE if all data is accurately collected */
     char processName[PROC_NAME_LEN];
+    struct exc_port_info exceptionInfo;
+    struct my_per_thread_info * threadInfos; /* dynamically allocated in collect_per_task_info */
+    unsigned int threadCount;
+    struct exc_port_info *threadExceptionInfos;  /* this is 2 dimensional array with threadCount X struct exc_port_info  of ports */
 } my_per_task_info_t;
 
 
@@ -110,8 +133,8 @@ typedef struct my_per_task_info {
   (flags & MACH_PORT_STATUS_FLAG_TASKPTR)              ?"P":"-"
 
 
-void show_recipe_detail(mach_voucher_attr_recipe_t recipe);
-void show_voucher_detail(mach_port_t task, mach_port_name_t voucher);
+void show_recipe_detail(mach_voucher_attr_recipe_t recipe, char * voucher_outstr, uint32_t maxlen);
+char *copy_voucher_detail(mach_port_t task, mach_port_name_t voucher);
 
 /* mach port related functions */
 const char * kobject_name(natural_t kotype);
@@ -130,8 +153,9 @@ my_per_task_info_t * get_taskinfo_by_kobject(natural_t kobj);
 void get_exc_behavior_string(exception_behavior_t b, char *out_string, size_t len);
 void get_exc_mask_string(exception_mask_t m, char *out_string, size_t len);
 kern_return_t get_taskinfo_of_receiver_by_send_right(ipc_info_name_t *sendright, my_per_task_info_t **out_taskinfo, mach_port_name_t *out_recv_info);
+kern_return_t get_ipc_info_from_lsmp_spaceinfo(mach_port_t port_name, ipc_info_name_t *out_sendright);
 
 /* basic util functions */
-void print_hex_data(char *prefix, char *desc, void *addr, int len);
+void print_hex_data(char *outstr, size_t maxlen, char *prefix, char *desc, void *addr, int len);
 
 #endif
index 463c24984f83d33868a41c89e4129013d957c411..4afa36ddc9a9e27344995e398d3daf21180bbccd 100644 (file)
@@ -141,6 +141,21 @@ int main(int argc, char *argv[]) {
                }
                mach_port_deallocate(mach_task_self(), pset_priv);
         
+        /* swap my current instances port to be last to collect all threads and exception port info */
+        int myTaskPosition = -1;
+        for (int i = 0; i < taskCount; i++) {
+            if (tasks[i] == mach_task_self()){
+                myTaskPosition = i;
+                break;
+            }
+        }
+        if (myTaskPosition >= 0) {
+            mach_port_t swap_holder = MACH_PORT_NULL;
+            swap_holder = tasks[taskCount - 1];
+            tasks[taskCount - 1] = tasks[myTaskPosition];
+            tasks[myTaskPosition] = swap_holder;
+        }
+
        }
        else
        {
index 438e6041f9f102e7af53bab426cdd1a26f0b36d6..985fb89bf846996a5cf16b57c44963911b17c66a 100644 (file)
@@ -81,64 +81,78 @@ static const unsigned int voucher_contents_size = 8192;
 static uint8_t voucher_contents[voucher_contents_size];
 
 
-void show_recipe_detail(mach_voucher_attr_recipe_t recipe) {
-    printf(VOUCHER_DETAIL_PREFIX "Key: %u, ", recipe->key);
-    printf("Command: %u, ", recipe->command);
-    printf("Previous voucher: 0x%x, ", recipe->previous_voucher);
-    printf("Content size: %u\n", recipe->content_size);
+static uint32_t safesize (int len){
+    return (len > 0)? len : 0;
+}
+
+void show_recipe_detail(mach_voucher_attr_recipe_t recipe, char *voucher_outstr, uint32_t maxlen) {
+    uint32_t len = 0;
+    len += safesize(snprintf(&voucher_outstr[len], maxlen - len, VOUCHER_DETAIL_PREFIX "Key: %u, ", recipe->key));
+    len += safesize(snprintf(&voucher_outstr[len], maxlen - len, "Command: %u, ", recipe->command));
+    len += safesize(snprintf(&voucher_outstr[len], maxlen - len, "Previous voucher: 0x%x, ", recipe->previous_voucher));
+    len += safesize(snprintf(&voucher_outstr[len], maxlen - len, "Content size: %u\n", recipe->content_size));
     switch (recipe->key) {
         case MACH_VOUCHER_ATTR_KEY_ATM:
-            printf(VOUCHER_DETAIL_PREFIX "ATM ID: %llu\n", *(uint64_t *)(uintptr_t)recipe->content);
+            len += safesize(snprintf(&voucher_outstr[len], maxlen - len, VOUCHER_DETAIL_PREFIX "ATM ID: %llu\n", *(uint64_t *)(uintptr_t)recipe->content));
             break;
         case MACH_VOUCHER_ATTR_KEY_IMPORTANCE:
-            printf(VOUCHER_DETAIL_PREFIX "IMPORTANCE INFO: %s\n", (char *)recipe->content);
+            len += safesize(snprintf(&voucher_outstr[len], maxlen - len, VOUCHER_DETAIL_PREFIX "IMPORTANCE INFO: %s\n", (char *)recipe->content));
             break;
         case MACH_VOUCHER_ATTR_KEY_BANK:
-            printf(VOUCHER_DETAIL_PREFIX "RESOURCE ACCOUNTING INFO: %s\n", (char *)recipe->content);
+            len += safesize(snprintf(&voucher_outstr[len], maxlen - len, VOUCHER_DETAIL_PREFIX "RESOURCE ACCOUNTING INFO: %s\n", (char *)recipe->content));
             break;
         default:
-            print_hex_data(VOUCHER_DETAIL_PREFIX, "Recipe Contents", (void *)recipe->content, MIN(recipe->content_size, lsmp_config.voucher_detail_length));
+            print_hex_data(&voucher_outstr[len], maxlen - len, VOUCHER_DETAIL_PREFIX, "Recipe Contents", (void *)recipe->content, MIN(recipe->content_size, lsmp_config.voucher_detail_length));
             break;
     }
-    
+
 }
 
-void show_voucher_detail(mach_port_t task, mach_port_name_t voucher) {
+
+char * copy_voucher_detail(mach_port_t task, mach_port_name_t voucher) {
     unsigned int recipe_size = voucher_contents_size;
     kern_return_t kr = KERN_SUCCESS;
     bzero((void *)&voucher_contents[0], sizeof(voucher_contents));
     unsigned v_kobject = 0;
     unsigned v_kotype = 0;
+    uint32_t detail_maxlen = VOUCHER_DETAIL_MAXLEN;
+    char * voucher_outstr = (char *)malloc(detail_maxlen);
+    voucher_outstr[0] = '\0';
+    uint32_t plen = 0;
+
     kr = mach_port_kernel_object( task,
                                  voucher,
                                  &v_kotype, (unsigned *)&v_kobject);
     if (kr == KERN_SUCCESS && v_kotype == IKOT_VOUCHER ) {
+
         kr = mach_voucher_debug_info(task, voucher,
                                      (mach_voucher_attr_raw_recipe_array_t)&voucher_contents[0],
                                      &recipe_size);
         if (kr != KERN_SUCCESS && kr != KERN_NOT_SUPPORTED) {
-            printf(VOUCHER_DETAIL_PREFIX "Voucher: 0x%x Failed to get contents %s\n", v_kobject, mach_error_string(kr));
-            return;
+            plen += safesize(snprintf(&voucher_outstr[plen], detail_maxlen - plen, VOUCHER_DETAIL_PREFIX "Voucher: 0x%x Failed to get contents %s\n", v_kobject, mach_error_string(kr)));
+            return voucher_outstr;
         }
+
         if (recipe_size == 0) {
-            printf(VOUCHER_DETAIL_PREFIX "Voucher: 0x%x has no contents\n", v_kobject);
-            return;
+            plen += safesize(snprintf(&voucher_outstr[plen], detail_maxlen - plen, VOUCHER_DETAIL_PREFIX "Voucher: 0x%x has no contents\n", v_kobject));
+            return voucher_outstr;
         }
-        printf(VOUCHER_DETAIL_PREFIX "Voucher: 0x%x\n", v_kobject);
+
+        plen += safesize(snprintf(&voucher_outstr[plen], detail_maxlen - plen, VOUCHER_DETAIL_PREFIX "Voucher: 0x%x\n", v_kobject));
         unsigned int used_size = 0;
         mach_voucher_attr_recipe_t recipe = NULL;
         while (recipe_size > used_size) {
             recipe = (mach_voucher_attr_recipe_t)&voucher_contents[used_size];
             if (recipe->key) {
-                show_recipe_detail(recipe);
+                show_recipe_detail(recipe, &voucher_outstr[plen], detail_maxlen - plen);
             }
             used_size += sizeof(mach_voucher_attr_recipe_data_t) + recipe->content_size;
         }
     } else {
-        printf(VOUCHER_DETAIL_PREFIX "Invalid voucher: 0x%x\n", voucher);
+        plen += safesize(snprintf(&voucher_outstr[plen], detail_maxlen - plen, VOUCHER_DETAIL_PREFIX "Invalid voucher: 0x%x\n", voucher));
     }
+    
+    return voucher_outstr;
 }
 
 void get_receive_port_context(task_t taskp, mach_port_name_t portname, mach_port_context_t *context) {
@@ -373,7 +387,9 @@ void show_task_mach_ports(my_per_task_info_t *taskinfo, uint32_t taskCount, my_p
             if (kotype == IKOT_VOUCHER) {
                 vouchercount++;
                 if (lsmp_config.show_voucher_details) {
-                    show_voucher_detail(taskinfo->task, taskinfo->table[i].iin_name);
+                    char * detail = copy_voucher_detail(taskinfo->task, taskinfo->table[i].iin_name);
+                    printf("%s\n", detail);
+                    free(detail);
                 }
             }
                        continue;
@@ -414,24 +430,25 @@ void show_task_mach_ports(my_per_task_info_t *taskinfo, uint32_t taskCount, my_p
     
 }
 
-void print_hex_data(char *prefix, char *desc, void *addr, int len) {
+void print_hex_data(char *outstr, size_t maxlen, char *prefix, char *desc, void *addr, int len) {
     int i;
     unsigned char buff[17];
     unsigned char *pc = addr;
+    uint32_t plen = 0;
     
     if (desc != NULL)
-        printf ("%s%s:\n", prefix, desc);
+        plen += safesize(snprintf(&outstr[len], maxlen - plen, "%s%s:\n", prefix, desc));
     
     for (i = 0; i < len; i++) {
         
         if ((i % 16) == 0) {
             if (i != 0)
-                printf ("  %s\n", buff);
+                plen += safesize(snprintf(&outstr[len], maxlen - plen, "  %s\n", buff));
             
-            printf ("%s  %04x ", prefix, i);
+            plen += safesize(snprintf(&outstr[len], maxlen - plen, "%s  %04x ", prefix, i));
         }
         
-        printf (" %02x", pc[i]);
+        plen += safesize(snprintf(&outstr[len], maxlen - plen, " %02x", pc[i]));
         
         if ((pc[i] < 0x20) || (pc[i] > 0x7e))
             buff[i % 16] = '.';
@@ -441,9 +458,9 @@ void print_hex_data(char *prefix, char *desc, void *addr, int len) {
     }
     
     while ((i % 16) != 0) {
-        printf ("   ");
+        plen += safesize(snprintf(&outstr[len], maxlen - plen, "   "));
         i++;
     }
     
-    printf ("  %s\n", buff);
+    plen += safesize(snprintf(&outstr[len], maxlen - plen, "  %s\n", buff));
 }
index 6fb8deee887e5734318e94ff30b799aeacb32b6b..bb490f2cbf9a8dea22ef111ce617217e2d2d14eb 100644 (file)
@@ -41,6 +41,10 @@ static my_per_task_info_t NOT_FOUND_TASK_INFO = {
     .treeCount = 0,
     .valid = FALSE,
     .processName = "Unknown",
+    .exceptionInfo = {0},
+    .threadInfos = NULL,
+    .threadCount = 0,
+    .threadExceptionInfos = NULL
 };
 
 char * get_task_name_by_pid(pid_t pid);
@@ -81,10 +85,79 @@ kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_
     
     taskinfo->task = target_task;
     pid_for_task(target_task, &taskinfo->pid);
+
+    ret = task_get_exception_ports(taskinfo->task, EXC_MASK_ALL, taskinfo->exceptionInfo.masks, &taskinfo->exceptionInfo.count, taskinfo->exceptionInfo.ports, taskinfo->exceptionInfo.behaviors, taskinfo->exceptionInfo.flavors);
+
+    if (ret != KERN_SUCCESS) {
+        fprintf(stderr, "task_get_exception_ports() failed: pid:%d error: %s\n",taskinfo->pid, mach_error_string(ret));
+        taskinfo->pid = 0;
+    }
+
+    /* collect threads port as well */
+    taskinfo->threadCount = 0;
+    thread_act_array_t threadPorts;
+    ret = task_threads(taskinfo->task, &threadPorts, &taskinfo->threadCount);
+
+    if (ret != KERN_SUCCESS) {
+        fprintf(stderr, "task_threads() failed: pid:%d error: %s\n",taskinfo->pid, mach_error_string(ret));
+        taskinfo->threadCount = 0;
+    } else {
+        /* collect the thread information */
+        taskinfo->threadInfos = (struct my_per_thread_info *)malloc(sizeof(struct my_per_thread_info) * taskinfo->threadCount);
+        bzero(taskinfo->threadInfos, sizeof(struct my_per_thread_info) * taskinfo->threadCount);
+
+        /* now collect exception ports for each of those threads as well */
+        taskinfo->threadExceptionInfos = (struct exc_port_info *) malloc(sizeof(struct exc_port_info) * taskinfo->threadCount);
+        boolean_t found_exception = false;
+        for (int i = 0; i < taskinfo->threadCount; i++) {
+            unsigned th_kobject = 0;
+            unsigned th_kotype = 0;
+            ipc_voucher_t th_voucher = IPC_VOUCHER_NULL;
+            thread_identifier_info_data_t th_info;
+            mach_msg_type_number_t th_info_count = THREAD_IDENTIFIER_INFO_COUNT;
+            struct exc_port_info *excinfo = &(taskinfo->threadExceptionInfos[i]);
+
+            ret = thread_get_exception_ports(threadPorts[i], EXC_MASK_ALL, excinfo->masks, &excinfo->count, excinfo->ports, excinfo->behaviors, excinfo->flavors);
+            if (ret != KERN_SUCCESS){
+                fprintf(stderr, "thread_get_exception_ports() failed: pid: %d thread: %d error %s\n", taskinfo->pid, threadPorts[i], mach_error_string(ret));
+            }
+
+            if (excinfo->count != 0) {
+                found_exception = true;
+            }
+
+            taskinfo->threadInfos[i].thread = threadPorts[i];
+
+            if (KERN_SUCCESS == mach_port_kernel_object(mach_task_self(), threadPorts[i], &th_kotype, &th_kobject)) {
+                taskinfo->threadInfos[i].th_kobject = th_kobject;
+                if (KERN_SUCCESS == thread_info(threadPorts[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&th_info, &th_info_count)) {
+                    taskinfo->threadInfos[i].th_id = th_info.thread_id;
+                }
+            }
+
+            if (KERN_SUCCESS == thread_get_mach_voucher(threadPorts[i], 0, &th_voucher) && th_voucher != IPC_VOUCHER_NULL) {
+                char *detail = copy_voucher_detail(mach_task_self(), th_voucher);
+                taskinfo->threadInfos[i].voucher_detail = strndup(detail, VOUCHER_DETAIL_MAXLEN);
+                free(detail);
+
+                mach_port_deallocate(mach_task_self(), th_voucher);
+            }
+
+            mach_port_deallocate(mach_task_self(), threadPorts[i]);
+            threadPorts[i] = MACH_PORT_NULL;
+        }
+
+        if (found_exception == false) {
+            free(taskinfo->threadExceptionInfos);
+            taskinfo->threadExceptionInfos = NULL;
+        }
+
+    }
+
+    vm_deallocate(mach_task_self(), threadPorts, taskinfo->threadCount * sizeof(thread_act_t));
+    threadPorts = NULL;
     
-    ret = mach_port_space_info(target_task, &taskinfo->info,
-                               &taskinfo->table, &taskinfo->tableCount,
-                               &taskinfo->tree, &taskinfo->treeCount);
+    ret = mach_port_space_info(target_task, &taskinfo->info, &taskinfo->table, &taskinfo->tableCount, &taskinfo->tree, &taskinfo->treeCount);
     
     if (ret != KERN_SUCCESS) {
         fprintf(stderr, "mach_port_space_info() failed: pid:%d error: %s\n",taskinfo->pid, mach_error_string(ret));
@@ -93,6 +166,7 @@ kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_
     }
     
     proc_pid_to_name(taskinfo->pid, taskinfo->processName);
+
     ret = mach_port_kernel_object(mach_task_self(), taskinfo->task, &kotype, (unsigned *)&kobject);
     
     if (ret == KERN_SUCCESS && kotype == IKOT_TASK) {
@@ -103,13 +177,7 @@ kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_
     return ret;
 }
 
-struct exc_port_info {
-    mach_msg_type_number_t   count;
-    mach_port_t      ports[EXC_TYPES_COUNT];
-    exception_mask_t masks[EXC_TYPES_COUNT];
-    exception_behavior_t behaviors[EXC_TYPES_COUNT];
-    thread_state_flavor_t flavors[EXC_TYPES_COUNT];
-};
+
 
 void get_exc_behavior_string(exception_behavior_t b, char *out_string, size_t len)
 {
@@ -165,51 +233,41 @@ void get_exc_mask_string(exception_mask_t m, char *out_string, size_t len)
 
 kern_return_t print_task_exception_info(my_per_task_info_t *taskinfo)
 {
-    kern_return_t kr = KERN_SUCCESS;
-    exception_mask_t mask = EXC_MASK_ALL;
-    struct exc_port_info excinfo;
+
     char behavior_string[30];
     char mask_string[200];
-    
-    kr = task_get_exception_ports(taskinfo->task, mask, excinfo.masks, &excinfo.count, excinfo.ports, excinfo.behaviors, excinfo.flavors);
-    
-    if (kr != KERN_SUCCESS) {
-        fprintf(stderr, "Failed task_get_exception_ports task: %d pid: %d\n", taskinfo->task, taskinfo->pid);
-        return kr;
-    }
+
     boolean_t header_required = TRUE;
-    for (int i = 0; i < excinfo.count; i++) {
-        if (excinfo.ports[i] != MACH_PORT_NULL) {
+    for (int i = 0; i < taskinfo->exceptionInfo.count; i++) {
+        if (taskinfo->exceptionInfo.ports[i] != MACH_PORT_NULL) {
             if (header_required) {
-                printf("port        flavor <behaviors>           mask   \n");
+
+                printf("    exc_port    flavor <behaviors>           mask   \n");
                 header_required = FALSE;
             }
-            get_exc_behavior_string(excinfo.behaviors[i], behavior_string, sizeof(behavior_string));
-            get_exc_mask_string(excinfo.masks[i], mask_string, 200);
-            printf("0x%08x  0x%03x  <%s> %s  \n" , excinfo.ports[i], excinfo.flavors[i], behavior_string, mask_string);
-            mach_port_deallocate(mach_task_self(), excinfo.ports[i]);
+            get_exc_behavior_string(taskinfo->exceptionInfo.behaviors[i], behavior_string, sizeof(behavior_string));
+            get_exc_mask_string(taskinfo->exceptionInfo.masks[i], mask_string, 200);
+            printf("    0x%08x  0x%03x  <%s>           %s  \n" , taskinfo->exceptionInfo.ports[i], taskinfo->exceptionInfo.flavors[i], behavior_string, mask_string);
         }
         
     }
     
-    return kr;
+    return KERN_SUCCESS;
 }
 
 
 kern_return_t print_task_threads_special_ports(my_per_task_info_t *taskinfo)
 {
     kern_return_t kret = KERN_SUCCESS;
-    thread_act_array_t threadlist;
-    mach_msg_type_number_t threadcount=0;
-    kret = task_threads(taskinfo->task, &threadlist, &threadcount);
+    mach_msg_type_number_t threadcount = taskinfo->threadCount;
     boolean_t header_required = TRUE;
     boolean_t newline_required = TRUE;
-    unsigned th_kobject = 0;
-    unsigned th_kotype = 0;
+    struct my_per_thread_info * info = NULL;
     
     for (int i = 0; i < threadcount; i++) {
+        info = &taskinfo->threadInfos[i];
         if (header_required) {
-            printf("Threads             Thread-ID     Port Description.");
+            printf("Thread_KObject  Thread-ID     Port Description.");
             header_required = FALSE;
         }
         
@@ -217,26 +275,62 @@ kern_return_t print_task_threads_special_ports(my_per_task_info_t *taskinfo)
             printf("\n");
         }
         newline_required = TRUE;
-        if (KERN_SUCCESS == mach_port_kernel_object(mach_task_self(), threadlist[i], &th_kotype, &th_kobject)) {
+        
+        if (info->th_kobject != 0) {
             /* TODO: Should print tid and stuff */
-            thread_identifier_info_data_t th_info;
-            mach_msg_type_number_t th_info_count = THREAD_IDENTIFIER_INFO_COUNT;
-            printf("0x%08x ", th_kobject);
-            if (KERN_SUCCESS == thread_info(threadlist[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&th_info, &th_info_count)) {
-                printf("0x%llx  ", th_info.thread_id);
-            }
-            else
-                printf("                   ");
-            
+            printf("0x%08x       ", info->th_kobject);
+            printf("0x%llx  ", info->th_id);
         }
 
-        ipc_voucher_t th_voucher = IPC_VOUCHER_NULL;
-        if (KERN_SUCCESS == thread_get_mach_voucher(threadlist[i], 0, &th_voucher) && th_voucher != IPC_VOUCHER_NULL) {
-            show_voucher_detail(mach_task_self(), th_voucher);
-            mach_port_deallocate(mach_task_self(), th_voucher);
-            newline_required = FALSE;
+        if (info->voucher_detail != NULL) {
+            printf("%s\n", info->voucher_detail);
+        }
+
+        /* print the thread exception ports also */
+        if (taskinfo->threadExceptionInfos != NULL)
+        {
+
+            struct exc_port_info *excinfo = &taskinfo->threadExceptionInfos[i];
+            char behavior_string[30];
+            char mask_string[200];
+
+            if (excinfo->count > 0) {
+                boolean_t header_required = TRUE;
+                for (int i = 0; i < excinfo->count; i++) {
+                    if (excinfo->ports[i] != MACH_PORT_NULL) {
+                        if (header_required) {
+                            printf("\n    exc_port    flavor <behaviors>           mask   -> name    owner\n");
+                            header_required = FALSE;
+                        }
+                        get_exc_behavior_string(excinfo->behaviors[i], behavior_string, sizeof(behavior_string));
+                        get_exc_mask_string(excinfo->masks[i], mask_string, sizeof(mask_string));
+                        printf("    0x%08x  0x%03x  <%s>           %s  " , excinfo->ports[i], excinfo->flavors[i], behavior_string, mask_string);
+
+                        ipc_info_name_t actual_sendinfo;
+                        if (KERN_SUCCESS == get_ipc_info_from_lsmp_spaceinfo(excinfo->ports[i], &actual_sendinfo)) {
+                            my_per_task_info_t *recv_holder_taskinfo;
+                            mach_port_name_t recv_name = MACH_PORT_NULL;
+                            if (KERN_SUCCESS == get_taskinfo_of_receiver_by_send_right(&actual_sendinfo, &recv_holder_taskinfo, &recv_name)) {
+                                printf("   -> 0x%08x  0x%08x  (%d) %s\n",
+                                       recv_name,
+                                       actual_sendinfo.iin_object,
+                                       recv_holder_taskinfo->pid,
+                                       recv_holder_taskinfo->processName);
+                            }
+
+                        } else {
+                            fprintf(stderr, "failed to find");
+                        }
+
+                        printf("\n");
+
+                    }
+
+                }
+            }
+
         }
-        mach_port_deallocate(mach_task_self(), threadlist[i]);
+
     }
     printf("\n");
     return kret;
@@ -283,4 +377,27 @@ kern_return_t get_taskinfo_of_receiver_by_send_right(ipc_info_name_t *sendright,
     return retval;
 }
 
+kern_return_t get_ipc_info_from_lsmp_spaceinfo(mach_port_t port_name, ipc_info_name_t *out_sendright){
+    kern_return_t retval = KERN_FAILURE;
+    bzero(out_sendright, sizeof(ipc_info_name_t));
+    my_per_task_info_t *mytaskinfo = NULL;
+    for (int i = global_taskcount - 1; i >= 0; i--){
+        if (global_taskinfo[i].task == mach_task_self()){
+            mytaskinfo = &global_taskinfo[i];
+            break;
+        }
+    }
+    if (mytaskinfo) {
+        for (int k = 0; k < mytaskinfo->tableCount; k++) {
+            if (port_name == mytaskinfo->table[k].iin_name){
+                bcopy(&mytaskinfo->table[k], out_sendright, sizeof(ipc_info_name_t));
+                retval = KERN_SUCCESS;
+                break;
+            }
+        }
+    }
+    return retval;
+
+}
+
 
index f545174b15cd0173a4bf4d7264df3e58583bcbf7..98c424dc6840c77ca61b96f9e52b9db0c5ca2ada 100644 (file)
@@ -11,6 +11,7 @@
                        isa = PBXAggregateTarget;
                        buildConfigurationList = BA4FD2FF1372FE4E0025925C /* Build configuration list for PBXAggregateTarget "All_MacOSX" */;
                        buildPhases = (
+                               C9D64CD21B91066B00CFA43B /* CopyFiles */,
                        );
                        dependencies = (
                                97999D351AE84D3A00E8B10F /* PBXTargetDependency */,
                        isa = PBXAggregateTarget;
                        buildConfigurationList = BACC1D191377B4C9007728F4 /* Build configuration list for PBXAggregateTarget "All_iOS" */;
                        buildPhases = (
+                               C9D64CD01B91064700CFA43B /* CopyFiles */,
                        );
                        dependencies = (
                                97999D371AE84D4100E8B10F /* PBXTargetDependency */,
                C96F50BD15BDFEFB008682F7 /* lsmp.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C96F50AC15BDCBF0008682F7 /* lsmp.1 */; };
                C96F50BE15BDFF03008682F7 /* lsmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C96F50AD15BDCE8E008682F7 /* lsmp.c */; };
                C9779F6E159A2A0C009436FD /* libutil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BA4B7A091373BA4600003422 /* libutil.dylib */; };
+               C9D64CD11B91065D00CFA43B /* system_cmds.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = C9D64CCF1B91063200CFA43B /* system_cmds.plist */; };
+               C9D64CD31B91067500CFA43B /* system_cmds.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = C9D64CCF1B91063200CFA43B /* system_cmds.plist */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
+               C9D64CD01B91064700CFA43B /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /AppleInternal/CoreOS/BATS/unit_tests;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               C9D64CD11B91065D00CFA43B /* system_cmds.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+               C9D64CD21B91066B00CFA43B /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /AppleInternal/CoreOS/BATS/unit_tests;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               C9D64CD31B91067500CFA43B /* system_cmds.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
                C96F50AC15BDCBF0008682F7 /* lsmp.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; name = lsmp.1; path = lsmp.tproj/lsmp.1; sourceTree = SOURCE_ROOT; };
                C96F50AD15BDCE8E008682F7 /* lsmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lsmp.c; path = lsmp.tproj/lsmp.c; sourceTree = SOURCE_ROOT; };
                C96F50B715BDCEC3008682F7 /* lsmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lsmp; sourceTree = BUILT_PRODUCTS_DIR; };
+               C9D64CCF1B91063200CFA43B /* system_cmds.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = system_cmds.plist; path = tests/system_cmds.plist; sourceTree = "<group>"; };
                FEBEE5CF1B0EACEB00166A8B /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = entitlements.plist; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
                BA2DE9161372FA9100D1913C = {
                        isa = PBXGroup;
                        children = (
+                               C9D64CCF1B91063200CFA43B /* system_cmds.plist */,
                                A6738D041AF6FFB5001EF064 /* CoreFoundation.framework */,
                                A6738D021AF6FF9F001EF064 /* IOKit.framework */,
                                A624DA851AF6F3CF00F56A5C /* CoreSymbolication.framework */,
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = BA4FD2FB1372FB710025925C /* BSD.xcconfig */;
                        buildSettings = {
-                               APPLY_RULES_IN_COPY_FILES = YES;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_OPTIMIZATION_LEVEL = 0;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = BA4FD2FB1372FB710025925C /* BSD.xcconfig */;
                        buildSettings = {
-                               APPLY_RULES_IN_COPY_FILES = YES;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_TREAT_WARNINGS_AS_ERRORS = NO;
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
diff --git a/tests/system_cmds.plist b/tests/system_cmds.plist
new file mode 100644 (file)
index 0000000..5f5b961
--- /dev/null
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>BATSConfigVersion</key>
+       <string>0.1.0</string>
+       <key>IgnoreCrashes</key>
+       <array>
+       </array>
+       <key>Project</key>
+       <string>system_cmds</string>
+       <key>IgnoreOutput</key>
+       <true/>
+       <key>TestSpecificLogs</key>
+       <array>
+               <string>/tmp/system_cmds.*.txt</string>
+       </array>
+       <key>Tests</key>
+       <array>
+               <dict>
+                       <key>Arch</key>
+                       <string>platform-native</string>
+                       <key>AsRoot</key>
+                       <true/>
+                       <key>Command</key>
+                       <array>
+                               <string>/usr/bin/lsmp</string>
+                               <string>-all</string>
+                       </array>
+                       <key>IgnoreCrashes</key>
+                       <array>
+                       </array>
+                       <key>TestName</key>
+                       <string>test_lsmp</string>
+                       <key>TestSpecificLogs</key>
+                       <array>
+                       </array>
+                       <key>WorkingDirectory</key>
+                       <string>/tmp/</string>
+               </dict>
+               <dict>
+                       <key>Arch</key>
+                       <string>platform-native</string>
+                       <key>AsRoot</key>
+                       <true/>
+                       <key>Command</key>
+                       <array>
+                               <string>/usr/sbin/lsof</string>
+                       </array>
+                       <key>IgnoreCrashes</key>
+                       <array>
+                       </array>
+                       <key>TestName</key>
+                       <string>test_lsof</string>
+                       <key>TestSpecificLogs</key>
+                       <array>
+                       </array>
+                       <key>WorkingDirectory</key>
+                       <string>/tmp/</string>
+               </dict>
+
+               <dict>
+                       <key>Arch</key>
+                       <string>platform-native</string>
+                       <key>AsRoot</key>
+                       <true/>
+                       <key>Command</key>
+                       <array>
+                               <string>/usr/bin/zprint</string>
+                       </array>
+                       <key>IgnoreCrashes</key>
+                       <array>
+                       </array>
+                       <key>TestName</key>
+                       <string>test_zprint</string>
+                       <key>TestSpecificLogs</key>
+                       <array>
+                       </array>
+                       <key>WorkingDirectory</key>
+                       <string>/tmp/</string>
+               </dict>
+               <dict>
+                       <key>Arch</key>
+                       <string>platform-native</string>
+                       <key>AsRoot</key>
+                       <true/>
+                       <key>Command</key>
+                       <array>
+                               <string>/usr/bin/hostinfo</string>
+                       </array>
+                       <key>IgnoreCrashes</key>
+                       <array>
+                       </array>
+                       <key>TestName</key>
+                       <string>test_hostinfo</string>
+                       <key>TestSpecificLogs</key>
+                       <array>
+                       </array>
+                       <key>WorkingDirectory</key>
+                       <string>/tmp/</string>
+               </dict>
+               <dict>
+                       <key>Arch</key>
+                       <string>platform-native</string>
+                       <key>AsRoot</key>
+                       <false/>
+                       <key>Command</key>
+                       <array>
+                               <string>/usr/local/bin/ltop</string>
+                       </array>
+                       <key>IgnoreCrashes</key>
+                       <array>
+                       </array>
+                       <key>TestName</key>
+                       <string>test_ltop</string>
+                       <key>TestSpecificLogs</key>
+                       <array>
+                       </array>
+                       <key>WorkingDirectory</key>
+                       <string>/tmp/</string>
+               </dict>
+               <dict>
+                       <key>Arch</key>
+                       <string>platform-native</string>
+                       <key>AsRoot</key>
+                       <false/>
+                       <key>Command</key>
+                       <array>
+                               <string>/usr/bin/vm_stat</string>
+                       </array>
+                       <key>IgnoreCrashes</key>
+                       <array>
+                       </array>
+                       <key>TestName</key>
+                       <string>test_vm_stat</string>
+                       <key>TestSpecificLogs</key>
+                       <array>
+                       </array>
+                       <key>WorkingDirectory</key>
+                       <string>/tmp/</string>
+               </dict>
+               <dict>
+                       <key>Arch</key>
+                       <string>platform-native</string>
+                       <key>AsRoot</key>
+                       <true/>
+                       <key>Command</key>
+                       <array>
+                               <string>/sbin/dmesg</string>
+                       </array>
+                       <key>IgnoreCrashes</key>
+                       <array>
+                       </array>
+                       <key>TestName</key>
+                       <string>test_dmesg</string>
+                       <key>TestSpecificLogs</key>
+                       <array>
+                       </array>
+                       <key>WorkingDirectory</key>
+                       <string>/tmp/</string>
+               </dict>
+               <dict>
+                       <key>Arch</key>
+                       <string>platform-native</string>
+                       <key>AsRoot</key>
+                       <true/>
+                       <key>Command</key>
+                       <array>
+                               <string>/usr/sbin/sysctl</string>
+                               <string>-a</string>
+                       </array>
+                       <key>IgnoreCrashes</key>
+                       <array>
+                       </array>
+                       <key>TestName</key>
+                       <string>test_sysctl</string>
+                       <key>TestSpecificLogs</key>
+                       <array>
+                       </array>
+                       <key>WorkingDirectory</key>
+                       <string>/tmp/</string>
+               </dict>
+       </array>
+</dict>
+</plist>