Exemple #1
50
static void setExceptionThread(void)
{
    kern_return_t r;
//    char *nullAddr = NULL;
    
    bailOut = FALSE;
    /* save the old exception port for this task */
    r = task_get_exception_port(task_self(), &(ports.old_exc_port));
    if (r != KERN_SUCCESS) {
	mach_error("task_get_exception_port",r);
	exit(1);
    }
    
    if (!ports.exc_port) {
	/* create a new exception port for this task */
	r = port_allocate(task_self(), &(ports.exc_port));
	if (r != KERN_SUCCESS) {
	    mach_error("port_allocate",r);
	    exit(1);
	}
	/* Fork the thread that listens to the exception port. */
	cthread_detach(cthread_fork((cthread_fn_t)exc_thread,(any_t)&ports));
	ports.clear_port = thread_reply();
    }

    /* install the new exception port for this task */
    r = task_set_exception_port(task_self(), (ports.exc_port));
    if (r != KERN_SUCCESS) {
	mach_error("task_set_exception_port",r);
	exit(1);
    }
    
}
Exemple #2
0
static void restoreExceptionThread(void)
{
    /* install the old port again */
    kern_return_t r = task_set_exception_port(task_self(), (ports.old_exc_port));
    if (r != KERN_SUCCESS) {
	mach_error("task_set_exception_port",r);
	exit(1);
    }
}
void next_create_inferior_for_task
(struct next_inferior_status *inferior, task_t task, int pid)
{
  kern_return_t ret;

  CHECK_FATAL (inferior != NULL);

  next_inferior_destroy (inferior);
  next_inferior_reset (inferior);

  inferior->task = task;
  inferior->pid = pid;

  inferior->attached_in_ptrace = 0;
  inferior->stopped_in_ptrace = 0;
  inferior->suspend_count = 0;

  /* */

  dyld_init_paths (&inferior->dyld_status.path_info);

  /* get notification messages for current task */

  ret = port_allocate (task_self (), &inferior->notify_port);
  MACH_CHECK_ERROR (ret);

  ret = port_set_backlog (task_self (), inferior->notify_port, PORT_BACKLOG_MAX);
  MACH_CHECK_ERROR (ret);

  if (inferior_bind_notify_port_flag) {
    ret = task_set_notify_port (task_self (), inferior->notify_port);
    MACH_CHECK_ERROR (ret);
  }

  /* initialize signal port */

  ret = port_allocate (task_self (), &inferior->signal_port);
  MACH_CHECK_ERROR (ret);

  ret = port_set_backlog (task_self (), inferior->signal_port, PORT_BACKLOG_MAX);
  MACH_CHECK_ERROR (ret);

  /* initialize dyld port */

  ret = port_allocate (task_self (), &inferior->dyld_port);
  MACH_WARN_ERROR (ret);

  ret = port_set_backlog (task_self (), inferior->dyld_port, PORT_BACKLOG_MAX);
  MACH_CHECK_ERROR (ret);

  /* initialize gdb exception port */

  ret = port_allocate (task_self (), &inferior->exception_port);
  MACH_CHECK_ERROR (ret);

  ret = port_set_backlog (task_self (), inferior->exception_port, PORT_BACKLOG_MAX);
  MACH_CHECK_ERROR (ret);

  ret = port_allocate (task_self (), &inferior->exception_reply_port);
  MACH_CHECK_ERROR (ret);

  ret = port_set_backlog (task_self (), inferior->exception_reply_port, PORT_BACKLOG_MAX);
  MACH_CHECK_ERROR (ret);

  /* commandeer inferior exception port */

  if (inferior_bind_exception_port_flag) {
    next_save_exception_ports (inferior->task, &inferior->saved_exceptions);

    ret = task_set_exception_port (task, inferior->exception_port);
    MACH_CHECK_ERROR (ret);
  }

  inferior->last_thread = next_primary_thread_of_task (inferior->task);
}
Exemple #4
0
int
main (int argc, char **argv)
{
  const task_t my_task = mach_task_self();
  error_t err;
  memory_object_t defpager;

  err = get_privileged_ports (&bootstrap_master_host_port,
			      &bootstrap_master_device_port);
  if (err)
    error (1, err, "cannot get privileged ports");

  defpager = MACH_PORT_NULL;
  err = vm_set_default_memory_manager (bootstrap_master_host_port, &defpager);
  if (err)
    error (1, err, "cannot check current default memory manager");
  if (MACH_PORT_VALID (defpager))
    error (2, 0, "Another default memory manager is already running");

  if (!(argc == 2 && !strcmp (argv[1], "-d")))
    {
      /* We don't use the `daemon' function because we might exit back to the
	 parent before the daemon has completed vm_set_default_memory_manager.
	 Instead, the parent waits for a SIGUSR1 from the child before
	 exitting, and the child sends that signal after it is set up.  */
      sigset_t set;
      signal (SIGUSR1, nohandler);
      sigemptyset (&set);
      sigaddset (&set, SIGUSR1);
      sigprocmask (SIG_BLOCK, &set, 0);
      switch (fork ())
	{
	case -1:
	  error (1, errno, "cannot become daemon");
	case 0:
	  setsid ();
	  chdir ("/");
	  close (0);
	  close (1);
	  close (2);
	  break;
	default:
	  sigemptyset (&set);
	  sigsuspend (&set);
	  _exit (0);
	}
    }

  /* Mark us as important.  */
  mach_port_t proc = getproc ();
  if (proc == MACH_PORT_NULL)
    error (3, err, "cannot get a handle to our process");

  err = proc_mark_important (proc);
  /* This might fail due to permissions or because the old proc server
     is still running, ignore any such errors.  */
  if (err && err != EPERM && err != EMIG_BAD_ID)
    error (3, err, "cannot mark us as important");

  mach_port_deallocate (mach_task_self (), proc);

  printf_init(bootstrap_master_device_port);

  /*
   * Set up the default pager.
   */
  partition_init();

  /*
   * task_set_exception_port and task_set_bootstrap_port
   * both require a send right.
   */
  (void) mach_port_insert_right(my_task, default_pager_exception_port,
				default_pager_exception_port,
				MACH_MSG_TYPE_MAKE_SEND);

  /*
   * Change our exception port.
   */
  if (!debug)
  (void) task_set_exception_port(my_task, default_pager_exception_port);

  default_pager_initialize (bootstrap_master_host_port);

  if (!(argc == 2 && !strcmp (argv[1], "-d")))
    kill (getppid (), SIGUSR1);

  /*
   * Become the default pager
   */
  default_pager();
  /*NOTREACHED*/
  return -1;
}