static void* thread_start_mark(void *arg){
  tar_threadstart threadstart=(tar_threadstart)arg;
#if (!NO_SNAPSHOT)
  bound_thread_to_cpu(MARK_CPU);
#else
  bound_thread_to_cpu(NONSNAPSHOT_MARK_CPU);
#endif
  threadstart();
  return NULL;
}
static void* thread_start_free(void *arg){
  tar_threadstart threadstart=(tar_threadstart)arg;
  bound_thread_to_cpu(FREE_CPU);
  threadstart();
  return NULL;
}
static void* thread_start_snapshot(void *arg){
  tar_threadstart threadstart=(tar_threadstart)arg;
  threadstart();
  return NULL;
}
Beispiel #4
0
int
ctlproc(int id, char *msg)
{
	Thread *t;
	int status;

	// Hang/attached dance is for debugging newly exec'ed programs.
	// After fork, the child does ctlproc("hang") before exec,
	// and the parent does ctlproc("attached") and then waitstop.
	// Using these requires the BSD ptrace interface, unlike everything
	// else we do, which uses only the Mach interface.  Our goal here
	// is to do as little as possible using ptrace and then flip over to Mach.

	if(strcmp(msg, "hang") == 0)
		return ptrace(PT_TRACE_ME, 0, 0, 0);

	if(strcmp(msg, "attached") == 0){
		// The pid "id" has done a ctlproc "hang" and then
		// exec, so we should find it stoppped just before exec
		// of the new program.
		#undef waitpid
		if(waitpid(id, &status, WUNTRACED) < 0){
			fprint(2, "ctlproc attached waitpid: %r\n");
			return -1;
		}
		if(WIFEXITED(status) || !WIFSTOPPED(status)){
			fprint(2, "ctlproc attached: bad process state\n");
			return -1;
		}

		// Find Mach thread for pid and suspend it.
		t = addpid(id, 1);
		if(t == nil)
			return -1;
		if(me(thread_suspend(t->thread)) < 0){
			fprint(2, "ctlproc attached: thread_suspend: %r\n");
			return -1;
		}

		// Let ptrace tell the process to keep going:
		// then ptrace is out of the way and we're back in Mach land.
		return ptrace(PT_CONTINUE, id, (caddr_t)1, 0);
	}

	// All the other control messages require a Thread structure.
	if((t = idtotable(id)) == nil){
		werrstr("no such thread");
		return -1;
	}

	if(strcmp(msg, "kill") == 0)
		return ptrace(PT_KILL, t->pid, 0, 0);

	if(strcmp(msg, "start") == 0)
		return threadstart(t, 0);

	if(strcmp(msg, "stop") == 0)
		return threadstop(t);

	if(strcmp(msg, "startstop") == 0){
		if(threadstart(t, 0) < 0)
			return -1;
		return waitstop(t);
	}

	if(strcmp(msg, "step") == 0){
		if(threadstart(t, 1) < 0)
			return -1;
		return waitstop(t);
	}

	if(strcmp(msg, "waitstop") == 0)
		return waitstop(t);

	// sysstop not available on OS X

	werrstr("unknown control message");
	return -1;
}