void ksmc_resumeEnvironment() { #if KSCRASH_HAS_THREADS_API KSLOG_DEBUG("Resuming environment."); kern_return_t kr; const task_t thisTask = mach_task_self(); const thread_t thisThread = (thread_t)ksthread_self(); thread_act_array_t threads; mach_msg_type_number_t numThreads; if((kr = task_threads(thisTask, &threads, &numThreads)) != KERN_SUCCESS) { KSLOG_ERROR("task_threads: %s", mach_error_string(kr)); return; } for(mach_msg_type_number_t i = 0; i < numThreads; i++) { thread_t thread = threads[i]; if(thread != thisThread && !isThreadInList(thread, g_reservedThreads, g_reservedThreadsCount)) { if((kr = thread_resume(thread)) != KERN_SUCCESS) { // Record the error and keep going. KSLOG_ERROR("thread_resume (%08x): %s", thread, mach_error_string(kr)); } } } for(mach_msg_type_number_t i = 0; i < numThreads; i++) { mach_port_deallocate(thisTask, threads[i]); } vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * numThreads); KSLOG_DEBUG("Resume complete."); #endif }
bool ksmach_resumeAllThreadsExcept(thread_t* exceptThreads, int exceptThreadsCount) { kern_return_t kr; const task_t thisTask = mach_task_self(); const thread_t thisThread = ksmach_thread_self(); thread_act_array_t threads; mach_msg_type_number_t numThreads; if((kr = task_threads(thisTask, &threads, &numThreads)) != KERN_SUCCESS) { KSLOG_ERROR("task_threads: %s", mach_error_string(kr)); return false; } for(mach_msg_type_number_t i = 0; i < numThreads; i++) { thread_t thread = threads[i]; if(thread != thisThread && !isThreadInList(thread, exceptThreads, exceptThreadsCount)) { if((kr = thread_resume(thread)) != KERN_SUCCESS) { KSLOG_ERROR("thread_resume (%08x): %s", thread, mach_error_string(kr)); // Don't treat this as a fatal error. } } } for(mach_msg_type_number_t i = 0; i < numThreads; i++) { mach_port_deallocate(thisTask, threads[i]); } vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * numThreads); return true; }