rem: }
context: handle_signals(struct thread *thread, cpu_status *state){	uint32 signalMask = thread->sig_pending & (~thread->sig_block_mask);	int i, sig, global_resched = 0;	struct sigaction *handler;	while (signalMask == 0) {		// check, if the thread shall stop for debugging		// ToDo: This isn't quite right yet. We always need to check		// whether the thread has to stop, also, if there is a signal. Since		// in case signal debugging is disabled the thread wouldn't stop		// below. At the moment it doesn't stop either, if the signal is		// ignored.		if (thread->debug_info.flags & B_THREAD_DEBUG_STOP) {			RELEASE_THREAD_LOCK();			restore_interrupts(*state);			user_debug_stop_thread();			*state = disable_interrupts();			GRAB_THREAD_LOCK();			signalMask = thread->sig_pending & (~thread->sig_block_mask);			continue;		}		return 0;	}	for (i = 0; i < NSIG; i++) {		if (signalMask & 0x1) {			bool debugSignal = atomic_get(&thread->team->debug_info.flags)				& B_TEAM_DEBUG_SIGNALS;			sig = i + 1;			handler = &thread->sig_action[i];			signalMask >>= 1;			thread->sig_pending &= ~(1L << i);			TRACE(("Thread 0x%lx received signal %s\n", thread->id, sigstr[sig]));			if (handler->sa_handler == SIG_IGN) {				// signal is to be ignored				// ToDo: apply zombie cleaning on SIGCHLD				// ToDo: Do we need to notify the debugger?				continue;			}			if (handler->sa_handler == SIG_DFL) {				// default signal behaviour				switch (sig) {					case SIGCHLD:					case SIGWINCH:					case SIGTSTP:					case SIGTTIN:					case SIGTTOU:					case SIGCONT:						continue;					case SIGSTOP:						thread->next_state = B_THREAD_SUSPENDED;						global_resched = 1;						continue;					case SIGQUIT:					case SIGILL:					case SIGTRAP:					case SIGABRT:					case SIGFPE:					case SIGSEGV:						TRACE(("Shutting down thread 0x%lx due to signal #%d\n", thread->id, sig));					case SIGKILL:					case SIGKILLTHR:					default:						if (thread->exit.reason != THREAD_RETURN_EXIT)							thread->exit.reason = THREAD_RETURN_INTERRUPTED;						RELEASE_THREAD_LOCK();						restore_interrupts(*state);						// ToDo: when we have more than a thread per process,						// it can likely happen (for any thread other than the first)						// that here, interrupts are still disabled.						// Changing the above line with "enable_interrupts()" fixes						// the problem, though we should find its cause.						// We absolutely need interrupts enabled when we enter						// thread_exit().						if (debugSignal && sig != SIGKILL								&& sig != SIGKILLTHR) {							// notify the debugger							if (user_debug_handle_signal(sig, true)									== B_THREAD_DEBUG_IGNORE_SIGNAL) {								continue;							}						}						thread_exit();				}			}			if (debugSignal) {				// notify the debugger				RELEASE_THREAD_LOCK();				restore_interrupts(*state);				if (user_debug_handle_signal(sig, false)						== B_THREAD_DEBUG_IGNORE_SIGNAL) {					continue;				}				*state = disable_interrupts();				GRAB_THREAD_LOCK();			}			// ToDo: it's not safe to call arch_setup_signal_frame with			//		interrupts disabled since it writes to the user stack			//		and may page fault.			// User defined signal handler			TRACE(("### Setting up custom signal handler frame...\n"));			arch_setup_signal_frame(thread, handler, sig, thread->sig_block_mask);			if (handler->sa_flags & SA_ONESHOT)				handler->sa_handler = SIG_DFL;			if (!(handler->sa_flags & SA_NOMASK))				thread->sig_block_mask |= (handler->sa_mask | SIGNAL_TO_MASK(sig)) & BLOCKABLE_SIGS;			return global_resched;		} else			signalMask >>= 1;	}	arch_check_syscall_restart(thread);	return global_resched;}