Ejemplo n.º 1
0
int check_refs (mach_port_t port) /* To call from gdb */
{
  int err;
  mach_port_urefs_t refs;
  err = mach_port_get_refs (mach_task_self (),
			    port, MACH_PORT_RIGHT_SEND, &refs);
  return err ? -err : refs;
}
void
test_mach_debug_port(mach_port_t name, const char *str, unsigned int line)
{
	mach_port_type_t type;
	mach_msg_bits_t ns = 0, nr = 0, nso = 0, nd = 0;
	unsigned int dnreqs = 0, dnrsiz;
	kern_return_t kr = mach_port_type(mach_task_self(), name, &type);
	if (kr) {
		fprintf(stderr, "machport[0x%08x] = { error(0x%x) \"%s\" }: %s %u\n",
				name, kr, mach_error_string(kr), str, line);
		return;
	}
	if (type & MACH_PORT_TYPE_SEND) {
		test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name,
				MACH_PORT_RIGHT_SEND, &ns));
	}
	if (type & MACH_PORT_TYPE_SEND_ONCE) {
		test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name,
				MACH_PORT_RIGHT_SEND_ONCE, &nso));
	}
	if (type & MACH_PORT_TYPE_DEAD_NAME) {
		test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name,
				MACH_PORT_RIGHT_DEAD_NAME, &nd));
	}
	if (type & (MACH_PORT_TYPE_RECEIVE|MACH_PORT_TYPE_SEND)) {
		test_mach_assume_zero(mach_port_dnrequest_info(mach_task_self(), name,
				&dnrsiz, &dnreqs));
		}
	if (type & MACH_PORT_TYPE_RECEIVE) {
		mach_port_status_t status = { .mps_pset = 0, };
		mach_msg_type_number_t cnt = MACH_PORT_RECEIVE_STATUS_COUNT;
		test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name,
				MACH_PORT_RIGHT_RECEIVE, &nr));
		test_mach_assume_zero(mach_port_get_attributes(mach_task_self(), name,
				MACH_PORT_RECEIVE_STATUS, (void*)&status, &cnt));
		fprintf(stderr, "machport[0x%08x] = { R(%03u) S(%03u) SO(%03u) D(%03u) "
				"dnreqs(%03u) spreq(%s) nsreq(%s) pdreq(%s) srights(%s) "
				"sorights(%03u) qlim(%03u) msgcount(%03u) mkscount(%03u) "
				"seqno(%03u) }: %s %u\n", name, nr, ns, nso, nd, dnreqs,
				type & MACH_PORT_TYPE_SPREQUEST ? "Y":"N",
				status.mps_nsrequest ? "Y":"N", status.mps_pdrequest ? "Y":"N",
				status.mps_srights ? "Y":"N", status.mps_sorights,
				status.mps_qlimit, status.mps_msgcount, status.mps_mscount,
				status.mps_seqno, str, line);
	} else if (type & (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_SEND_ONCE|
Ejemplo n.º 3
0
static bool task_is_dead (int pid) {
	unsigned int count = 0;
	kern_return_t kr = mach_port_get_refs (mach_task_self (),
		pid_to_task (pid), MACH_PORT_RIGHT_SEND, &count);
	return (kr != KERN_SUCCESS || !count);
}
Ejemplo n.º 4
0
static kern_return_t PrintProcessPortSpace(pid_t pid, bool verbose)
// Prints port rights owned by the specified process.
{
    kern_return_t           err;
    kern_return_t           junk;
    mach_port_t             taskSendRight;
    mach_port_name_array_t  rightNames;
    mach_msg_type_number_t  rightNamesCount;
    mach_port_type_array_t  rightTypes;
    mach_msg_type_number_t  rightTypesCount;
    unsigned int            i;

    taskSendRight = MACH_PORT_NULL;
    rightNames    = NULL;
    rightTypes    = NULL;

    // Get the task control port for the process.

    err = task_for_pid(mach_task_self(), pid, &taskSendRight);
    if (err != KERN_SUCCESS) {
        fprintf(stderr, "%s: Could not attach to process %lld (%#08x).\n", gProgramName, (long long) pid, err);
    }

    // Get a snapshot of the port name space for the task.

    if (err == KERN_SUCCESS) {
        err = mach_port_names(taskSendRight, &rightNames, &rightNamesCount, &rightTypes, &rightTypesCount);
    }
    if (err == KERN_SUCCESS) {
        if ( rightNamesCount != rightTypesCount ) {
            fprintf(stderr, "%s: Count mismatch (%u/%u)\n", gProgramName, rightNamesCount, rightTypesCount);
            err = KERN_FAILURE;
        }
    }

    // Print that snapshot.

    if (err == KERN_SUCCESS) {
        fprintf(stdout, "    Name     Send  Receive SendOnce  PortSet DeadName DNR");
        if (verbose) {
            fprintf(stdout, " flg    seqno  mscount   qlimit msgcount sorights     pset");
        }
        fprintf(stdout, "\n");
        fprintf(stdout, "    ----     ----  ------- --------  ------- -------- ---");
        if (verbose) {
            fprintf(stdout, " ---    -----  -------   ------ -------- --------     ----");
        }
        fprintf(stdout, "\n");

        // For each name, print a reference count of each type of right.  If running
        // verbose, print other information as well.

        for (i = 0; i < rightNamesCount; i++) {
            mach_port_right_t   right;

            // We print the right name in hex because it makes it easier to
            // see the index and generation fields.  See <mach/port.h> for
            // information about this.

            fprintf(stdout, "%#8x ", rightNames[i]);

            for (right = MACH_PORT_RIGHT_SEND; right <= MACH_PORT_RIGHT_DEAD_NAME; right++) {
                mach_port_urefs_t   refCount;

                // If the rightTypes for this name has the bit associated
                // with this type of right set (that is, if the name
                // references this type of right), get the name's reference
                // for this right and print it.  Otherwise just print an
                // empty string to keep the columns lined up.

                if (rightTypes[i] & MACH_PORT_TYPE(right)) {

                    err = mach_port_get_refs(taskSendRight, rightNames[i], right, &refCount);
                    if (err == KERN_SUCCESS) {
                        fprintf(stdout, "%8d ", refCount);
                    } else {
                        fprintf(stdout, "%8s ", "???");
                    }
                } else {
                    fprintf(stdout, "%8s ", "");
                }
            }
            if ( rightTypes[i] & MACH_PORT_TYPE_DNREQUEST ) {
                fprintf(stdout, "yes ");
            } else {
                fprintf(stdout, "    ");
            }

            if (verbose) {
                if (rightTypes[i] & MACH_PORT_TYPE_PORT_SET) {
                    PrintPortSetMembers(taskSendRight, rightNames[i]);
                } else if (rightTypes[i] & MACH_PORT_TYPE_RECEIVE) {
                    PrintPortReceiveStatus(taskSendRight, rightNames[i]);
                }
            }
            fprintf(stdout, "\n");
        }
    }

    // Clean up.

    if (rightNames != NULL) {
        junk = vm_deallocate(mach_task_self(), (vm_address_t) rightNames, rightNamesCount * sizeof(*rightNames));
        assert(junk == KERN_SUCCESS);
    }
    if (rightTypes != NULL) {
        junk = vm_deallocate(mach_task_self(), (vm_address_t) rightTypes, rightTypesCount * sizeof(*rightTypes));
        assert(junk == KERN_SUCCESS);
    }
    if (taskSendRight != MACH_PORT_NULL) {
        junk = mach_port_deallocate(mach_task_self(), taskSendRight);
        assert(junk == KERN_SUCCESS);
    }

    return err;
}
Ejemplo n.º 5
0
static void
info_mach_ports_command (char *args, int from_tty)
{
  port_name_array_t names;
  port_type_array_t types;
  unsigned int name_count, type_count;
  kern_return_t result;
  int index;
  task_t task;

  task = get_task_from_args (args);
  if (task == TASK_NULL)
    return;

  result = mach_port_names (task, &names, &name_count, &types, &type_count);
  MACH_CHECK_ERROR (result);

  gdb_assert (name_count == type_count);

  printf_unfiltered (_("Ports for task 0x%x:\n"), task);
  printf_unfiltered (_("port   type\n"));
  for (index = 0; index < name_count; ++index)
    {
      mach_port_t port = names[index];
      unsigned int j;
      struct type_descr
      {
	mach_port_type_t type;
	const char *name;
	mach_port_right_t right;
      };
      static struct type_descr descrs[] =
	{
	  {MACH_PORT_TYPE_SEND, "send", MACH_PORT_RIGHT_SEND},
	  {MACH_PORT_TYPE_SEND_ONCE, "send-once", MACH_PORT_RIGHT_SEND_ONCE},
	  {MACH_PORT_TYPE_RECEIVE, "receive", MACH_PORT_RIGHT_RECEIVE},
	  {MACH_PORT_TYPE_PORT_SET, "port-set", MACH_PORT_RIGHT_PORT_SET},
	  {MACH_PORT_TYPE_DEAD_NAME, "dead", MACH_PORT_RIGHT_DEAD_NAME}
	};

      printf_unfiltered (_("%04x: %08x "), port, types[index]);
      for (j = 0; j < sizeof(descrs) / sizeof(*descrs); j++)
	if (types[index] & descrs[j].type)
	  {
	    mach_port_urefs_t ref;
	    kern_return_t ret;

	    printf_unfiltered (_(" %s("), descrs[j].name);
	    ret = mach_port_get_refs (task, port, descrs[j].right, &ref);
	    if (ret != KERN_SUCCESS)
	      printf_unfiltered (_("??"));
	    else
	      printf_unfiltered (_("%u"), ref);
	    printf_unfiltered (_(" refs)"));
	  }
      
      if (task == task_self ())
	{
	  if (port == task_self())
	    printf_unfiltered (_(" gdb-task"));
	  else if (port == darwin_host_self)
	    printf_unfiltered (_(" host-self"));
	  else if (port == darwin_ex_port)
	    printf_unfiltered (_(" gdb-exception"));
	  else if (port == darwin_port_set)
	    printf_unfiltered (_(" gdb-port_set"));
	  else if (!ptid_equal (inferior_ptid, null_ptid))
	    {
	      struct inferior *inf = current_inferior ();

	      if (port == inf->priv->task)
		printf_unfiltered (_(" inferior-task"));
	      else if (port == inf->priv->notify_port)
		printf_unfiltered (_(" inferior-notify"));
	      else
		{
		  int k;
		  darwin_thread_t *t;

		  for (k = 0; k < inf->priv->exception_info.count; k++)
		    if (port == inf->priv->exception_info.ports[k])
		      {
			printf_unfiltered (_(" inferior-excp-port"));
			break;
		      }

		  if (inf->priv->threads)
		    {
		      for (k = 0;
			   VEC_iterate(darwin_thread_t,
				       inf->priv->threads, k, t);
			   k++)
			if (port == t->gdb_port)
			  {
			    printf_unfiltered (_(" inferior-thread for 0x%x"),
					       inf->priv->task);
			    break;
			  }
		    }
		}
	    }
	}
      printf_unfiltered (_("\n"));
    }

  vm_deallocate (task_self (), (vm_address_t) names,
                 (name_count * sizeof (mach_port_t)));
  vm_deallocate (task_self (), (vm_address_t) types,
                 (type_count * sizeof (mach_port_type_t)));
}
Ejemplo n.º 6
0
//No synchronization issue so far, need to use synchronize if we run into any issues
int stop(mach_port_t task) {
    MachExceptionHandlerData old_handler;
    thread_act_port_array_t threadList;
    mach_msg_type_number_t threadCount;
    unsigned int count;
    kern_return_t kret;
    interface *face;

    threadCount=0;
    task_threads(current_task(), &threadList, &threadCount);
    DEBUG_PRINT("[+stop] Thread count before detaching %d\n", threadCount);

    face = find_interface(task);
    close(face->kq);                  //close kqueue
    count = 1;
    kret = task_swap_exception_ports(current_task(),
                                     EXC_MASK_ALL,
                                     MACH_PORT_NULL,
                                     EXCEPTION_DEFAULT|MACH_EXCEPTION_CODES,
                                     THREAD_STATE_NONE,
                                     (exception_mask_array_t) old_handler.masks,
                                     (mach_msg_type_number_t *) &old_handler.count,
                                     (exception_handler_array_t) old_handler.ports,
                                     (exception_behavior_array_t) old_handler.behaviors,
                                     (exception_flavor_array_t) old_handler.flavors);

    kret = mach_port_mod_refs(mach_task_self(), face->server_port, MACH_PORT_RIGHT_RECEIVE, -1);

    if (kret != KERN_SUCCESS) {
        RETURN_ON_MACH_ERROR("[-stop] mach_port_mod_refs failed", kret);
    }

    kret = mach_port_get_refs(mach_task_self(), face->server_port, MACH_PORT_RIGHT_RECEIVE, &count );
    RETURN_ON_MACH_ERROR("[-stop] mach_port_get_refs failed", kret);


    if (face->server_port) {
        kret = mach_port_deallocate(current_task(),face->server_port);
        RETURN_ON_MACH_ERROR("[-stop] mach_port_deallocate failed", kret);
    }

    if (count) {
        DEBUG_PRINT("[-stop] failed to reset server port ref count exp:0 actual: %d\n", count);
        return 0;
    }

    task_threads(task, &threadList, &threadCount);
    DEBUG_PRINT("[+stop] Thread count after detaching %d\n", threadCount);

    face->registered_exception_handler = 0;
    count = 0;

    //REMOVE PID FROM BAD LIST TO ALLOW REATTACHING
    while(count < bad_list.x) {
        if(bad_list.y[count]->task == task) {
            break;
        }
        count++;
    }

    DEBUG_PRINT("TASK IS NUMBER: %d\n", count);

    int c;
    for(c = count; c < bad_list.x; c++) {
        bad_list.y[c] =  bad_list.y[c+1];
    }
    bad_list.x -= 1;

    return 1;
}