Example #1
0
int
__cdecl
ThreadPThread__SuspendThread (m3_pthread_t mt)
{
  kern_return_t status = { 0 };
  mach_port_t mach_thread = PTHREAD_FROM_M3(mt);
  status = thread_suspend(mach_thread);
  if (status != KERN_SUCCESS)
  {
    fprintf(stderr, "thread_suspend returned %d instead of %d\n",
            (int)status, (int)KERN_SUCCESS);
    return 0;
  }
  status = thread_abort_safely(mach_thread);
  if (status != KERN_SUCCESS)
  {
    fprintf(stderr, "thread_abort_safely returned %d instead of %d\n",
            (int)status, (int)KERN_SUCCESS);
    status = thread_resume(mach_thread);
    if (status != KERN_SUCCESS)
    {
      fprintf(stderr, "thread_resume returned %d instead of %d\n",
              (int)status, (int)KERN_SUCCESS);
      abort();
    }
    return 0;
  }
  return 1;
}
Example #2
0
void sys_pause(struct cpu_state **cpu)
{
    thread_suspend(current_thread);
    (*cpu)->CPU_ARG0 = 0;

    *cpu = (struct cpu_state *)task_schedule(*cpu);
}
Example #3
0
void Thread::suspend(void)
{
	if(!priv)
		return;

#ifdef WIN32
	if (!priv->_active || !priv->_suspendEnable)
	{
#ifdef	CCXX_EXCEPTIONS
		if (Thread::getException() != throwNothing)
			throw this;
#endif
		return;
	}
	SuspendThread(priv->_hThread);

#else

	if (!priv->_suspendEnable) return;
#if CCXX_SUSPEND_MODE == CCXX_SUSPEND_MODE_MACH
	thread_suspend(priv->_mach);
#endif
#if CCXX_SUSPEND_MODE == CCXX_SUSPEND_MODE_RECURSIVE
	ccxx_suspend(priv->_tid);
#endif
#if (CCXX_SUSPEND_MODE == CCXX_SUSPEND_MODE_NOT_RECURSIVE) \
  || (CCXX_SUSPEND_MODE == CCXX_SUSPEND_MODE_ONE_SIGNAL)
	if (++priv->_suspendcount != 1) return;
	ccxx_suspend(priv->_tid);
#endif

#endif // WIN32
}
Example #4
0
void 
o_thrSuspend(o_thr_t thr) {
    mach_port_t mthread;

    mthread = pthread_mach_thread_np(thr);
    thread_suspend(mthread);
}
Example #5
0
int
main(int argc, char *argv[])
{
	static char stack[10][1024];
	int i;

	printf("Semaphore sample program\n");

	/*
	 * Initialize semaphore with initial count 3
	 */
	sem_init(&sem, 3);

	/*
	 * Boost the priority of this thread
	 */
	thread_setpri(thread_self(), 100);

	/*
	 * Create 10 threads
	 */
	for (i = 0; i < 10; i++)
		thread_run(new_thread, stack[i]+1024);

	/*
	 * Wait...
	 */
	thread_suspend(thread_self());

	return 0;
}
Example #6
0
static void
notify_loading_app(status_t result, bool suspend)
{
	Team* team = thread_get_current_thread()->team;

	TeamLocker teamLocker(team);

	if (team->loading_info) {
		// there's indeed someone waiting
		struct team_loading_info* loadingInfo = team->loading_info;
		team->loading_info = NULL;

		loadingInfo->result = result;

		// we're done with the team stuff, get the scheduler lock instead
		teamLocker.Unlock();

		thread_prepare_suspend();

		// wake up the waiting thread
		loadingInfo->condition.NotifyAll();

		// suspend ourselves, if desired
		if (suspend)
			thread_suspend(true);
	}
}
void
gdb_pthread_kill(pthread_t pthread)
{
  mach_port_t mthread;
  kern_return_t kret;
  int ret;

  mthread = pthread_mach_thread_np(pthread);

  kret = thread_suspend(mthread);
  MACH_CHECK_ERROR(kret);

  ret = pthread_cancel(pthread);
  if (ret != 0)
    {
/* in case a macro has re-defined this function: */
#undef strerror
      warning("Unable to cancel thread: %s (%d)", strerror(errno), errno);
      thread_terminate(mthread);
    }

  kret = thread_abort (mthread);
  MACH_CHECK_ERROR (kret);

  kret = thread_resume (mthread);
  MACH_CHECK_ERROR (kret);

  ret = pthread_join (pthread, NULL);
  if (ret != 0)
    {
      warning ("Unable to join to canceled thread: %s (%d)", strerror (errno),
               errno);
    }
}
Example #8
0
gboolean
gum_process_modify_thread (GumThreadId thread_id,
                           GumModifyThreadFunc func,
                           gpointer user_data)
{
  gboolean success = FALSE;
  mach_port_t task;
  thread_act_array_t threads;
  mach_msg_type_number_t count;
  kern_return_t kr;

  task = mach_task_self ();

  kr = task_threads (task, &threads, &count);
  if (kr == KERN_SUCCESS)
  {
    guint i;

    for (i = 0; i != count; i++)
    {
      thread_t thread = threads[i];

      if (thread == thread_id)
      {
        gum_thread_state_t state;
        mach_msg_type_number_t state_count = GUM_THREAD_STATE_COUNT;
        thread_state_flavor_t state_flavor = GUM_THREAD_STATE_FLAVOR;
        GumCpuContext cpu_context;

        kr = thread_suspend (thread);
        if (kr != KERN_SUCCESS)
          break;

        kr = thread_get_state (thread, state_flavor, (thread_state_t) &state,
            &state_count);
        if (kr != KERN_SUCCESS)
        {
          thread_resume (thread);
          break;
        }

        gum_cpu_context_from_darwin (&state, &cpu_context);
        func (thread_id, &cpu_context, user_data);
        gum_cpu_context_to_darwin (&cpu_context, &state);

        kr = thread_set_state (thread, state_flavor, (thread_state_t) &state,
            state_count);

        success =
            (thread_resume (thread) == KERN_SUCCESS && kr == KERN_SUCCESS);
      }
    }

    for (i = 0; i != count; i++)
      mach_port_deallocate (task, threads[i]);
    vm_deallocate (task, (vm_address_t) threads, count * sizeof (thread_t));
  }

  return success;
}
void
mono_threads_core_abort_syscall (MonoThreadInfo *info)
{
	kern_return_t ret;

	do {
		ret = thread_suspend (info->native_handle);
	} while (ret == KERN_ABORTED);

	if (ret != KERN_SUCCESS)
		return;

	do {
		ret = thread_abort_safely (info->native_handle);
	} while (ret == KERN_ABORTED);

	/*
	 * We are doing thread_abort when thread_abort_safely returns KERN_SUCCESS because
	 * for some reason accept is not interrupted by thread_abort_safely.
	 * The risk of aborting non-atomic operations while calling thread_abort should not
	 * exist because by the time thread_abort_safely returns KERN_SUCCESS the target
	 * thread should have return from the kernel and should be waiting for thread_resume
	 * to resume the user code.
	 */
	if (ret == KERN_SUCCESS)
		ret = thread_abort (info->native_handle);

	do {
		ret = thread_resume (info->native_handle);
	} while (ret == KERN_ABORTED);

	g_assert (ret == KERN_SUCCESS);
}
Example #10
0
gboolean
mono_threads_core_begin_async_suspend (MonoThreadInfo *info, gboolean interrupt_kernel)
{
	kern_return_t ret;
	gboolean res;

	g_assert (info);

	ret = thread_suspend (info->native_handle);
	THREADS_SUSPEND_DEBUG ("SUSPEND %p -> %d\n", (void*)info->native_handle, ret);
	if (ret != KERN_SUCCESS)
		return FALSE;

	/* We're in the middle of a self-suspend, resume and register */
	if (!mono_threads_transition_finish_async_suspend (info)) {
		mono_threads_add_to_pending_operation_set (info);
		g_assert (thread_resume (info->native_handle) == KERN_SUCCESS);
		THREADS_SUSPEND_DEBUG ("FAILSAFE RESUME/1 %p -> %d\n", (void*)info->native_handle, 0);
		//XXX interrupt_kernel doesn't make sense in this case as the target is not in a syscall
		return TRUE;
	}
	res = mono_threads_get_runtime_callbacks ()->
		thread_state_init_from_handle (&info->thread_saved_state [ASYNC_SUSPEND_STATE_INDEX], info);
	THREADS_SUSPEND_DEBUG ("thread state %p -> %d\n", (void*)info->native_handle, res);
	if (res) {
		if (interrupt_kernel)
			thread_abort (info->native_handle);
	} else {
		mono_threads_transition_async_suspend_compensation (info);
		g_assert (thread_resume (info->native_handle) == KERN_SUCCESS);
		THREADS_SUSPEND_DEBUG ("FAILSAFE RESUME/2 %p -> %d\n", (void*)info->native_handle, 0);
	}
	return res;
}
Example #11
0
void entry(ptrdiff_t codeOffset, void *param, size_t paramSize, void *pthreadData) {
#if defined(__i386__) || defined(__x86_64__)
	extern void __pthread_set_self(char *);
	__pthread_set_self(pthreadData);
#endif
	printf("Access granted\n");
	thread_suspend(mach_thread_self());
}
Example #12
0
void
attack(void)
{
	object_t *objp	= (object_t *)random();
	object_t obj	= (object_t)random();
	char *name	= (char *)random();
	void *msg	= (void *)random();
	size_t size	= (size_t)random();
	task_t self	= task_self();
	void *addr	= (void *)random();
	int attr	= random() & 7;
	thread_t t	= (thread_t)random();
	thread_t *tp	= (thread_t *)random();

	object_create(NULL, NULL);
	object_create(NULL, objp);
	object_create(name, NULL);
	object_create(name, objp);

	object_destroy(0);
	object_destroy(obj);

	object_lookup(NULL, objp);
	object_lookup(name, NULL);
	object_lookup(name, objp);

	msg_send(0, msg, size);
	msg_send(obj, NULL, size);
	msg_send(obj, msg, 0);
	msg_send(0, msg, 0);
	msg_send(0, NULL, size);
	msg_send(obj, msg, size);

	msg_receive(0, msg, size);
	msg_receive(obj, NULL, size);
	msg_receive(obj, msg, 0);
	msg_receive(0, msg, 0);
	msg_receive(0, NULL, size);
	msg_receive(obj, msg, size);

	msg_reply(0, msg, size);
	msg_reply(obj, NULL, size);
	msg_reply(obj, msg, 0);
	msg_reply(0, msg, 0);
	msg_reply(0, NULL, size);
	msg_reply(obj, msg, size);

	vm_allocate(self, addr, size, 1);
	vm_allocate(self, &addr, size, 1);

	vm_free(self, addr);
	vm_attribute(self, addr, attr);
	vm_map(self, addr, size, &addr);

	thread_create(self, tp);
	thread_suspend(t);
	thread_terminate(t);
}
Example #13
0
File: darwin.c Project: 8l/go-learn
// Stop thread t.
static int
threadstop(Thread *t)
{
	if(threadstopped(t))
		return 0;
	if(me(thread_suspend(t->thread)) < 0)
		return -1;
	return 0;
}
Example #14
0
main()
{
  long tid1, tid2;
  tid1 = thread_create(thread1, 0);
  tid2 = thread_create(thread2, 0);

  if (thread_suspend(tid1) != 1) 
    fprintf(stderr, "** Incorrect return value for successful suspend\n");
  if (thread_suspend(tid1) != 1) 
    fprintf(stderr, "** Incorrect return value for successful suspend\n");
  if (thread_suspend(tid1+456) != 0) 
    fprintf(stderr, "** Incorrect return value for unsuccessful suspend\n");

  thread_suspend(tid2);
  thread_suspend(thread_self()); /* this should cause program to halt */

  fprintf(stderr, "** Error: only running thread able to suspend itself\n");
}
Example #15
0
static int
suspendAllPreemptive(PlatformWalkData *data)
{
	mach_msg_type_number_t threadCount = 0;
	data->threadCount = 0;
	mach_port_t task = mach_task_self();
	struct sigaction upcallAction;
	int rc = 0;

	/* Install a signal handler to get thread context info from the handler. */
	upcallAction.sa_sigaction = upcallHandler;
	upcallAction.sa_flags = SA_SIGINFO | SA_RESTART;

	if (-1 == sigaction(SUSPEND_SIG, &upcallAction, &data->oldHandler)) {
		RECORD_ERROR(data->state, SIGNAL_SETUP_ERROR, -1);
		rc = -1;
	} else if (data->oldHandler.sa_sigaction == upcallHandler) {
		/* Handler's already installed so already iterating threads. We mustn't uninstall the handler
		 * while cleaning as the thread that installed the initial handler will do so.
		 */
		memset(&data->oldHandler, 0, sizeof(struct sigaction));
		RECORD_ERROR(data->state, CONCURRENT_COLLECTION, -1);
		rc = -1;
	}

	if (0 == rc) {
		/* After this point it's safe to go through the full cleanup. */
		data->cleanupRequired = 1;

		/* Suspend all threads until there are no new threads. */
		do {
			int i = 0;

			/* Get a list of the threads within the process. */
			data->threadCount = threadCount;
			if (KERN_SUCCESS != task_threads(task, &data->threadList, &threadCount)) {
				RECORD_ERROR(data->state, SIGNAL_SETUP_ERROR, -1);
				rc = -1;
				break;
			}

			/* Suspend each thread except this one. */
			for (i = data->threadCount; i < threadCount; i += 1) {
				if (data->filterThread != data->threadList[i]) {
					if (KERN_SUCCESS != thread_suspend(data->threadList[i])) {
						data->threadCount = i;
						rc = -1;
						break;
					}
				}
			}
		} while ((threadCount > data->threadCount) && (0 == rc));
	}

	return rc;
}
Example #16
0
gboolean
sgen_suspend_thread (SgenThreadInfo *info)
{
	mach_msg_type_number_t num_state;
	thread_state_t state;
	kern_return_t ret;
	ucontext_t ctx;
	mcontext_t mctx;

	gpointer stack_start;

	state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
	mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());

	do {
		ret = thread_suspend (info->client_info.info.native_handle);
	} while (ret == KERN_ABORTED);
	if (ret != KERN_SUCCESS)
		return FALSE;

	do {
		ret = mono_mach_arch_get_thread_state (info->client_info.info.native_handle, state, &num_state);
	} while (ret == KERN_ABORTED);
	if (ret != KERN_SUCCESS)
		return FALSE;

	mono_mach_arch_thread_state_to_mcontext (state, mctx);
	ctx.uc_mcontext = mctx;

	info->client_info.stopped_domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN);
	info->client_info.stopped_ip = (gpointer) mono_mach_arch_get_ip (state);
	info->client_info.stack_start = NULL;
	stack_start = (char*) mono_mach_arch_get_sp (state) - REDZONE_SIZE;
	/* If stack_start is not within the limits, then don't set it in info and we will be restarted. */
	if (stack_start >= info->client_info.stack_start_limit && stack_start <= info->client_info.stack_end) {
		info->client_info.stack_start = stack_start;

#ifdef USE_MONO_CTX
		mono_sigctx_to_monoctx (&ctx, &info->client_info.ctx);
#else
		ARCH_COPY_SIGCTX_REGS (&info->client_info.regs, &ctx);
#endif
	} else {
		g_assert (!info->client_info.stack_start);
	}

	/* Notify the JIT */
	if (mono_gc_get_gc_callbacks ()->thread_suspend_func)
		mono_gc_get_gc_callbacks ()->thread_suspend_func (info->client_info.runtime_data, &ctx, NULL);

	SGEN_LOG (2, "thread %p stopped at %p stack_start=%p", (void*)(gsize)info->client_info.info.native_handle, info->client_info.stopped_ip, info->client_info.stack_start);
	binary_protocol_thread_suspend ((gpointer)mono_thread_info_get_tid (info), info->client_info.stopped_ip);

	return TRUE;
}
Example #17
0
/*
 * smp_halt_processor()
 *	Halt this hardware thread.
 */
static void smp_halt_processor(void)
{
	int cpuid = thread_get_self();
	cpu_clear(smp_processor_id(), cpu_online_map);
	local_irq_disable();
	printk(KERN_EMERG "cpu[%d] has halted. It is not OK to turn off power \
		until all cpu's are off.\n", cpuid);
	for (;;) {
		thread_suspend();
	}
}
Example #18
0
static void demo_thread_entry(void)
{
#if 0
    point_t a = {0,0};
    point_t b = {639, 479};
    unsigned i;

    vga_drv.init_fn();

    for (i = 0; i < 16; i++) {
        vga_drv.rectangle_fn(a,b,5,i);
        a.x+=5;
        a.y+=5;
        b.x-=5;
        b.y-=5;
    }

    a.x+=16;
    a.y+=16;
    b.x-=16;
    b.y-=16;
    vga_drv.write_text_fn(a, 15, "DiegOS DiegOS DiegOS");
#else
    point_t a,b,c,d;
    //unsigned i;

    vga_drv.init_fn();
    a.x = a.y = 0;
    b.x = 639;
    b.y = 479;
    vga_drv.filled_rectangle_fn(a,b,7);
    a.x = 40;
    a.y = 30;
    b.x = 600;
    b.y = 30;
    c.x = 600;
    c.y = 450;
    d.x = 40;
    d.y = 450;
    vga_drv.line_fn(a,b,1,0);
    vga_drv.line_fn(a,d,1,2);
    vga_drv.line_fn(d,c,1,6);
    vga_drv.line_fn(b,c,1,5);
    a.x++;a.y++;b.x--;b.y++;c.x--;c.y--;d.x++;d.y--;
    vga_drv.line_fn(a,b,1,0);
    vga_drv.line_fn(a,d,1,2);
    vga_drv.line_fn(d,c,1,6);
    vga_drv.line_fn(b,c,1,5);
    a.x++;a.y++;b.x--;b.y++;c.x--;c.y--;d.x++;d.y--;
    vga_drv.filled_rectangle_fn(a,c,2);

#endif
    while (TRUE) thread_suspend();
}
static inline void suspendThread(const PlatformThread& platformThread)
{
#if OS(DARWIN)
    thread_suspend(platformThread);
#elif OS(WINDOWS)
    SuspendThread(platformThread);
#elif USE(PTHREADS)
    pthread_kill(platformThread, SigThreadSuspendResume);
#else
#error Need a way to suspend threads on this platform
#endif
}
Example #20
0
int uSleep(u32 time)
{
	if(time==0)
		return 0;
	int thid=thread_current();
	if(time != U_INFINITE)
	{
		set_timer_proc(time,0,uSleep_wakeup,thid,0);
	}
	thread_suspend(thid);
	return 0;
}
Example #21
0
/*
 * Suspend thread, retrieve registers, and clear the trace bit in the
 * thread's PSW.
 */
void
tgdb_clear_trace(mach_port_t thread)
{
	struct i386_thread_state ss;

	if (thread_suspend(thread) != KERN_SUCCESS) {
		printf("tgdb: can't suspend thread\n");
		return;
	}
	tgdb_get_registers(thread, &ss, 0);
	ss.efl &= ~EFL_TF;
	tgdb_set_registers(thread, &ss, 0);

}
Example #22
0
int 
suspend_thread(unsigned int thread)
{
    int sts;
	//fprintf(stderr, "suspend_thread %x\n", thread);
    sts = thread_suspend(thread);
    if(sts == KERN_SUCCESS){
        sts = 0;
    } else {
        //fprintf(stderr, "Got bad return of %d\n", sts);
        sts = -1;
    }
    return sts;
}
Example #23
0
int
SuspendThread (pthread_t t)
{
  mach_port_t mach_thread = pthread_mach_thread_np(t);
  if (thread_suspend(mach_thread) != KERN_SUCCESS)
    return 0;
  if (thread_abort_safely(mach_thread) != KERN_SUCCESS)
  {
    kern_return_t status = thread_resume(mach_thread);
    assert(status == KERN_SUCCESS);
    return 0;
  }
  return 1;
}
Example #24
0
void thread_may_suspend()
{
    thread_t *prev = scheduler_running_thread();
    uint8_t total;

    update_schedule();

    total = scheduler_ready_threads(prev->priority);

    if (!total) {
        return;
    }

    thread_suspend();
}
Example #25
0
gboolean
mono_sgen_suspend_thread (SgenThreadInfo *info)
{
	mach_msg_type_number_t num_state;
	thread_state_t state;
	kern_return_t ret;
	ucontext_t ctx;
	mcontext_t mctx;

	gpointer stack_start;

	state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
	mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());

	ret = thread_suspend (info->mach_port);
	if (ret != KERN_SUCCESS)
		return FALSE;

	ret = mono_mach_arch_get_thread_state (info->mach_port, state, &num_state);
	if (ret != KERN_SUCCESS)
		return FALSE;

	mono_mach_arch_thread_state_to_mcontext (state, mctx);
	ctx.uc_mcontext = mctx;

	info->stopped_domain = mono_mach_arch_get_tls_value_from_thread ((pthread_t)info->id, mono_domain_get_tls_offset ());
	info->stopped_ip = (gpointer) mono_mach_arch_get_ip (state);
	stack_start = (char*) mono_mach_arch_get_sp (state) - REDZONE_SIZE;
	/* If stack_start is not within the limits, then don't set it in info and we will be restarted. */
	if (stack_start >= info->stack_start_limit && info->stack_start <= info->stack_end) {
		info->stack_start = stack_start;

#ifdef USE_MONO_CTX
		mono_sigctx_to_monoctx (&ctx, &info->ctx);
		info->monoctx = &info->ctx;
#else
		ARCH_COPY_SIGCTX_REGS (&info->regs, &ctx);
		info->stopped_regs = &info->regs;
#endif
	} else {
		g_assert (!info->stack_start);
	}

	/* Notify the JIT */
	if (mono_gc_get_gc_callbacks ()->thread_suspend_func)
		mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, &ctx);
	return TRUE;
}
Example #26
0
inline bool MachineThreads::Thread::suspend()
{
#if OS(DARWIN)
    kern_return_t result = thread_suspend(platformThread);
    return result == KERN_SUCCESS;
#elif OS(WINDOWS)
    bool threadIsSuspended = (SuspendThread(platformThreadHandle) != (DWORD)-1);
    ASSERT(threadIsSuspended);
    return threadIsSuspended;
#elif USE(PTHREADS)
    pthread_kill(platformThread, SigThreadSuspendResume);
    return true;
#else
#error Need a way to suspend threads on this platform
#endif
}
Example #27
0
gboolean
mono_threads_core_suspend (MonoThreadInfo *info)
{
	kern_return_t ret;
	gboolean res;

	g_assert (info);

	ret = thread_suspend (info->native_handle);
	if (ret != KERN_SUCCESS)
		return FALSE;
	res = mono_threads_get_runtime_callbacks ()->
		thread_state_init_from_handle (&info->suspend_state, mono_thread_info_get_tid (info), info->native_handle);
	if (!res)
		thread_resume (info->native_handle);
	return res;
}
void NaClUntrustedThreadSuspend(struct NaClAppThread *natp,
                                int save_registers) {
  /*
   * We claim suspend_mu here to block trusted/untrusted context
   * switches by blocking NaClAppThreadSetSuspendState().  This blocks
   * any untrusted->trusted context switch that might happen before
   * SuspendThread() takes effect.  It blocks any trusted->untrusted
   * context switch that might happen if the syscall running in the
   * target thread returns.
   */
  NaClXMutexLock(&natp->suspend_mu);
  if (natp->suspend_state == NACL_APP_THREAD_UNTRUSTED) {
    kern_return_t result;
    mach_msg_type_number_t size;
    mach_port_t thread_port = GetHostThreadPort(natp);

    result = thread_suspend(thread_port);
    if (result != KERN_SUCCESS) {
      NaClLog(LOG_FATAL, "NaClUntrustedThreadSuspend: "
              "thread_suspend() call failed: error %d\n", (int) result);
    }

    if (save_registers) {
      if (natp->suspended_registers == NULL) {
        natp->suspended_registers = malloc(sizeof(*natp->suspended_registers));
        if (natp->suspended_registers == NULL) {
          NaClLog(LOG_FATAL, "NaClUntrustedThreadSuspend: malloc() failed\n");
        }
      }

      size = sizeof(natp->suspended_registers->context) / sizeof(natural_t);
      result = thread_get_state(thread_port, x86_THREAD_STATE,
                                (void *) &natp->suspended_registers->context,
                                &size);
      if (result != KERN_SUCCESS) {
        NaClLog(LOG_FATAL, "NaClUntrustedThreadSuspend: "
                "thread_get_state() call failed: error %d\n", (int) result);
      }
    }
  }
  /*
   * We leave suspend_mu held so that NaClAppThreadSetSuspendState()
   * will block.
   */
}
Example #29
0
File: darwin.c Project: 8l/go-learn
// Callback for exc_server below.  Called when a thread we are
// watching has an exception like hitting a breakpoint.
kern_return_t
catch_exception_raise(mach_port_t eport, mach_port_t thread,
	mach_port_t task, exception_type_t exception,
	exception_data_t code, mach_msg_type_number_t ncode)
{
	Thread *t;
	int i;

	t = nil;
	for(i=0; i<nthr; i++){
		if(thr[i].thread == thread){
			t = &thr[i];
			goto havet;
		}
	}
	if(nthr > 0)
		addpid(thr[0].pid, 1);
	for(i=0; i<nthr; i++){
		if(thr[i].thread == thread){
			t = &thr[i];
			goto havet;
		}
	}
	fprint(2, "did not find thread in catch_exception_raise\n");
	return KERN_SUCCESS;	// let thread continue

havet:
	t->exc = exception;
	if(ncode > nelem(t->code))
		ncode = nelem(t->code);
	memmove(t->code, code, ncode*sizeof t->code[0]);

	// Suspend thread, so that we can look at it & restart it later.
	if(me(thread_suspend(thread)) < 0)
		fprint(2, "catch_exception_raise thread_suspend: %r\n");

	// Synchronize with waitstop below.
	pthread_mutex_lock(&mu);
	pthread_cond_broadcast(&cond);
	pthread_mutex_unlock(&mu);

	return KERN_SUCCESS;
}
Example #30
0
static void jl_thread_suspend_and_get_state(int tid, unw_context_t **ctx, int sig)
{
    (void)sig;
    mach_port_t tid_port = pthread_mach_thread_np(jl_all_task_states[tid].system_id);

    kern_return_t ret = thread_suspend(tid_port);
    HANDLE_MACH_ERROR("thread_suspend", ret);

    // Do the actual sampling
    unsigned int count = MACHINE_THREAD_STATE_COUNT;
    static unw_context_t state;
    memset(&state, 0, sizeof(unw_context_t));

    // Get the state of the suspended thread
    ret = thread_get_state(tid_port, x86_THREAD_STATE64, (thread_state_t)&state, &count);

    // Initialize the unwind context with the suspend thread's state
    *ctx = &state;
}