Example #1
0
static void PrintPortSetMembers(mach_port_t taskSendRight, mach_port_name_t portSetName)
// For a given Mach port set within a given task, print the members
// of the port set.
{
    kern_return_t           err;
    kern_return_t           junk;
    mach_port_name_array_t  memberNames;
    mach_msg_type_number_t  memberNamesCount;
    mach_msg_type_number_t  memberIndex;

    memberNames = NULL;

    // Get an array of members.

    err = mach_port_get_set_status(
              taskSendRight,
              portSetName,
              &memberNames,
              &memberNamesCount
          );

    // Iterate over the array, printing each one.  Note that we print 6 members to
    // a line and we start every line except the second with enough spaces to
    // account for the information that we print that's common to each type
    // of output.

    if (err == KERN_SUCCESS) {
        fprintf(stdout, "    ");
        for (memberIndex = 0; memberIndex < memberNamesCount; memberIndex++) {
            if ( (memberIndex != 0) && (memberIndex % 6) == 0) {
                // 6 columns of (8 characters plus space)
                // plus DNR column (3 chars) plus space
                fprintf(stdout, "\n%*s    ", (6 * (8 + 1)) + 3 + 1, "");
            }
            fprintf(stdout, "%#8x ", memberNames[memberIndex]);
        }
    } else {
        fprintf(stdout, "??? ");
    }

    // Clean up.

    if (memberNames != NULL) {
        junk = vm_deallocate(mach_task_self(), (vm_address_t) memberNames, memberNamesCount * sizeof(*memberNames));
        assert(junk == KERN_SUCCESS);
    }
}
Example #2
0
void
mportset_callback(void)
{
	mach_port_name_array_t members;
	mach_msg_type_number_t membersCnt;
	mach_port_status_t status;
	mach_msg_type_number_t statusCnt;
	struct kevent kev;
	unsigned int i;

	if (os_assumes_zero(mach_port_get_set_status(mach_task_self(), demand_port_set, &members, &membersCnt)) != 0) {
		return;
	}

	for (i = 0; i < membersCnt; i++) {
		statusCnt = MACH_PORT_RECEIVE_STATUS_COUNT;
		if (mach_port_get_attributes(mach_task_self(), members[i], MACH_PORT_RECEIVE_STATUS, (mach_port_info_t)&status,
					&statusCnt) != KERN_SUCCESS) {
			continue;
		}
		if (status.mps_msgcount) {
			EV_SET(&kev, members[i], EVFILT_MACHPORT, 0, 0, 0, job_find_by_service_port(members[i]));
#if 0
			if (kev.udata != NULL) {
#endif
				log_kevent_struct(LOG_DEBUG, &kev, 0);
				(*((kq_callback *)kev.udata))(kev.udata, &kev);
#if 0
			} else {
				log_kevent_struct(LOG_ERR, &kev, 0);
			}
#endif
			/* the callback may have tainted our ability to continue this for loop */
			break;
		}
	}

	(void)os_assumes_zero(vm_deallocate(mach_task_self(), (vm_address_t)members, (vm_size_t) membersCnt * sizeof(mach_port_name_t)));
}
void show_task_mach_ports(my_per_task_info_t *taskinfo, uint32_t taskCount, my_per_task_info_t *allTaskInfos)
{
    int i, emptycount = 0, portsetcount = 0, sendcount = 0, receivecount = 0, sendoncecount = 0, deadcount = 0, dncount = 0, vouchercount = 0, pid;
    kern_return_t ret;
    pid_for_task(taskinfo->task, &pid);
    
    printf("  name      ipc-object    rights     flags   boost  reqs  recv  send sonce oref  qlimit  msgcount  context            identifier  type\n");
    printf("---------   ----------  ----------  -------- -----  ---- ----- ----- ----- ----  ------  --------  ------------------ ----------- ------------\n");
	for (i = 0; i < taskinfo->tableCount; i++) {
		int j, k;
		boolean_t send = FALSE;
		boolean_t sendonce = FALSE;
		boolean_t dnreq = FALSE;
		int sendrights = 0;
		unsigned int kotype = 0;
		vm_offset_t kobject = (vm_offset_t)0;
        
        /* skip empty slots in the table */
        if ((taskinfo->table[i].iin_type & MACH_PORT_TYPE_ALL_RIGHTS) == 0) {
            emptycount++;
            continue;
        }
        
        
		if (taskinfo->table[i].iin_type == MACH_PORT_TYPE_PORT_SET) {
			mach_port_name_array_t members;
			mach_msg_type_number_t membersCnt;
			
			ret = mach_port_get_set_status(taskinfo->task,
										   taskinfo->table[i].iin_name,
										   &members, &membersCnt);
			if (ret != KERN_SUCCESS) {
				fprintf(stderr, "mach_port_get_set_status(0x%08x) failed: %s\n",
						taskinfo->table[i].iin_name,
						mach_error_string(ret));
				continue;
			}
			printf("0x%08x  0x%08x  port-set    --------        ---      1                                                        %d  members\n",
				   taskinfo->table[i].iin_name,
				   taskinfo->table[i].iin_object,
				   membersCnt);
			/* get some info for each portset member */
			for (j = 0; j < membersCnt; j++) {
				for (k = 0; k < taskinfo->tableCount; k++) {
					if (taskinfo->table[k].iin_name == members[j]) {
                        mach_port_info_ext_t info;
                        mach_port_status_t port_status;
                        mach_port_context_t port_context = (mach_port_context_t)0;
                        if (0 != get_recieve_port_status(taskinfo->task, taskinfo->table[k].iin_name, &info)) {
                            bzero((void *)&info, sizeof(info));
                        }
                        port_status = info.mpie_status;
                        get_receive_port_context(taskinfo->task, taskinfo->table[k].iin_name, &port_context);
                        printf(" -          0x%08x  %s  --%s%s%s%s%s%s %5d  %s%s%s  %5d %5.0d %5.0d   %s   %6d  %8d  0x%016llx 0x%08x  (%d) %s\n",
							   taskinfo->table[k].iin_object,
							   (taskinfo->table[k].iin_type & MACH_PORT_TYPE_SEND) ? "recv,send ":"recv      ",
                               SHOW_PORT_STATUS_FLAGS(port_status.mps_flags),
                               info.mpie_boost_cnt,
                               (taskinfo->table[k].iin_type & MACH_PORT_TYPE_DNREQUEST) ? "D" : "-",
                               (port_status.mps_nsrequest) ? "N" : "-",
                               (port_status.mps_pdrequest) ? "P" : "-",
                               1,
                               taskinfo->table[k].iin_urefs,
                               port_status.mps_sorights,
                               (port_status.mps_srights) ? "Y" : "N",
                               port_status.mps_qlimit,
                               port_status.mps_msgcount,
                               (uint64_t)port_context,
							   taskinfo->table[k].iin_name,
							   pid,
                               taskinfo->processName);
						break;
					}
				}
			}
            
			ret = vm_deallocate(mach_task_self(), (vm_address_t)members,
								membersCnt * sizeof(mach_port_name_t));
			if (ret != KERN_SUCCESS) {
				fprintf(stderr, "vm_deallocate() failed: %s\n",
						mach_error_string(ret));
				exit(1);
			}
			portsetcount++;
			continue;
		}
        
		if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_SEND) {
			send = TRUE;
			sendrights = taskinfo->table[i].iin_urefs;
			sendcount++;
		}
		
		if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_DNREQUEST) {
			dnreq = TRUE;
			dncount++;
		}
        
		if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_RECEIVE) {
			mach_port_status_t status;
			mach_port_info_ext_t info;
			mach_port_context_t context = (mach_port_context_t)0;
            ret = get_recieve_port_status(taskinfo->task, taskinfo->table[i].iin_name, &info);
            get_receive_port_context(taskinfo->task, taskinfo->table[i].iin_name, &context);
            /* its ok to fail in fetching attributes */
            if (ret < 0) {
                continue;
            }
            status = info.mpie_status;
			printf("0x%08x  0x%08x  %s  --%s%s%s%s%s%s %5d  %s%s%s  %5d %5.0d %5.0d   %s   %6d  %8d  0x%016llx \n",
				   taskinfo->table[i].iin_name,
				   taskinfo->table[i].iin_object,
				   (send) ? "recv,send ":"recv      ",
				   SHOW_PORT_STATUS_FLAGS(status.mps_flags),
				   info.mpie_boost_cnt,
				   (dnreq) ? "D":"-",
				   (status.mps_nsrequest) ? "N":"-",
				   (status.mps_pdrequest) ? "P":"-",
                   1,
				   sendrights,
                   status.mps_sorights,
				   (status.mps_srights) ? "Y":"N",
				   status.mps_qlimit,
				   status.mps_msgcount,
				   (uint64_t)context);
			receivecount++;
            
            
			/* show other rights (in this and other tasks) for the port */
			for (j = 0; j < taskCount; j++) {
				for (k = 0; k < allTaskInfos->tableCount; k++) {
					if (allTaskInfos[j].valid == FALSE ||
						&allTaskInfos[j].table[k] == &taskinfo->table[i] ||
						allTaskInfos[j].table[k].iin_object != taskinfo->table[i].iin_object)
						continue;
                    
                    printf("                  +     %s  --------        %s%s%s        %5d         <-                                       0x%08x  (%d) %s\n",
						   (allTaskInfos[j].table[k].iin_type & MACH_PORT_TYPE_SEND_ONCE) ?
					       "send-once " : "send      ",
						   (allTaskInfos[j].table[k].iin_type & MACH_PORT_TYPE_DNREQUEST) ? "D" : "-",
                           "-",
                           "-",
                           allTaskInfos[j].table[k].iin_urefs,
						   allTaskInfos[j].table[k].iin_name,
						   allTaskInfos[j].pid,
                           allTaskInfos[j].processName);
				}
			}
			continue;
		}
		else if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_DEAD_NAME)
		{
			printf("0x%08x  0x%08x  dead-name   --------        ---        %5d      \n",
				   taskinfo->table[i].iin_name,
				   taskinfo->table[i].iin_object,
				   taskinfo->table[i].iin_urefs);
			deadcount++;
			continue;
		}
        
		if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_SEND_ONCE) {
			sendonce = TRUE;
			sendoncecount++;
		}
		
		printf("0x%08x  0x%08x  %s  --------        %s%s%s        %5.0d     ",
			   taskinfo->table[i].iin_name,
			   taskinfo->table[i].iin_object,
			   (send) ? "send      ":"send-once ",
			   (dnreq) ? "D":"-",
			   "-",
			   "-",
			   (send) ? sendrights : 0);
		
		/* converting to kobjects is not always supported */
		ret = mach_port_kernel_object(taskinfo->task,
									  taskinfo->table[i].iin_name,
									  &kotype, (unsigned *)&kobject);
		if (ret == KERN_SUCCESS && kotype != 0) {
			printf("                                             0x%08x  %s", (natural_t)kobject, kobject_name(kotype));
            if ((kotype == IKOT_TASK_RESUME) || (kotype == IKOT_TASK) || (kotype == IKOT_TASK_NAME)) {
                if (taskinfo->task_kobject == kobject) {
                    /* neat little optimization since in most cases tasks have themselves in their ipc space */
                    printf(" SELF (%d) %s", taskinfo->pid, taskinfo->processName);
                } else {
                    my_per_task_info_t * _found_task = get_taskinfo_by_kobject((natural_t)kobject);
                    printf(" (%d) %s", _found_task->pid, _found_task->processName);
                }
            }
            
            printf("\n");
            if (kotype == IKOT_VOUCHER) {
                vouchercount++;
                if (lsmp_config.show_voucher_details) {
                    show_voucher_detail(taskinfo->task, taskinfo->table[i].iin_name);
                }
            }
			continue;
		}
        
        /* not kobject - find the receive right holder */
        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(&taskinfo->table[i], &recv_holder_taskinfo, &recv_name)) {
            mach_port_status_t port_status;
            mach_port_info_ext_t info;
            mach_port_context_t port_context = (mach_port_context_t)0;
            if (0 != get_recieve_port_status(recv_holder_taskinfo->task, recv_name, &info)) {
                bzero((void *)&port_status, sizeof(port_status));
            }
            port_status = info.mpie_status;
            get_receive_port_context(recv_holder_taskinfo->task, recv_name, &port_context);
            printf("   ->   %6d  %8d  0x%016llx 0x%08x  (%d) %s\n",
                   port_status.mps_qlimit,
                   port_status.mps_msgcount,
                   (uint64_t)port_context,
                   recv_name,
                   recv_holder_taskinfo->pid,
                   recv_holder_taskinfo->processName);

        } else
			printf("                                             0x00000000  (-) Unknown Process\n");
 
	}
	printf("total     = %d\n", taskinfo->tableCount + taskinfo->treeCount - emptycount);
	printf("SEND      = %d\n", sendcount);
	printf("RECEIVE   = %d\n", receivecount);
	printf("SEND_ONCE = %d\n", sendoncecount);
	printf("PORT_SET  = %d\n", portsetcount);
	printf("DEAD_NAME = %d\n", deadcount);
	printf("DNREQUEST = %d\n", dncount);
    printf("VOUCHERS  = %d\n", vouchercount);
    
}