Index: kernel/generic/src/interrupt/interrupt.c
===================================================================
--- kernel/generic/src/interrupt/interrupt.c	(revision 336db2955b9fd1ee85c8818b9408bc4e9dad9fc2)
+++ kernel/generic/src/interrupt/interrupt.c	(revision a074b4f9d5cf65707ae3aaffaf4564453f710efd)
@@ -44,4 +44,8 @@
 #include <console/console.h>
 #include <console/cmd.h>
+#include <ipc/event.h>
+#include <synch/mutex.h>
+#include <time/delay.h>
+#include <macros.h>
 #include <panic.h>
 #include <print.h>
@@ -107,4 +111,51 @@
 	fault_if_from_uspace(istate, "Unhandled exception %d.", n);
 	panic("Unhandled exception %d.", n);
+}
+
+/** Terminate thread and task if exception came from userspace. */
+void fault_if_from_uspace(istate_t *istate, char *fmt, ...)
+{
+	task_t *task = TASK;
+	va_list args;
+
+	if (!istate_from_uspace(istate))
+		return;
+
+	printf("Task %s (%" PRIu64 ") killed due to an exception at "
+	    "program counter %p.\n", task->name, task->taskid,
+	    istate_get_pc(istate));
+
+	stack_trace_istate(istate);
+
+	printf("Kill message: ");
+	va_start(args, fmt);
+	vprintf(fmt, args);
+	va_end(args);
+	printf("\n");
+
+	if (event_is_subscribed(EVENT_FAULT)) {
+		event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),
+		    UPPER32(TASK->taskid), (unative_t) THREAD);
+	}
+
+#ifdef CONFIG_UDEBUG
+	/* Wait until a debugger attends to us. */
+	mutex_lock(&THREAD->udebug.lock);
+	while (!THREAD->udebug.active)
+		condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
+	mutex_unlock(&THREAD->udebug.lock);
+
+	udebug_stoppable_begin();
+	udebug_stoppable_end();
+
+	/* Make sure the debugging session is over before proceeding. */
+	mutex_lock(&THREAD->udebug.lock);
+	while (THREAD->udebug.active)
+		condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
+	mutex_unlock(&THREAD->udebug.lock);
+#endif
+
+	task_kill(task->taskid);
+	thread_exit();
 }
 
Index: kernel/generic/src/udebug/udebug.c
===================================================================
--- kernel/generic/src/udebug/udebug.c	(revision 336db2955b9fd1ee85c8818b9408bc4e9dad9fc2)
+++ kernel/generic/src/udebug/udebug.c	(revision a074b4f9d5cf65707ae3aaffaf4564453f710efd)
@@ -69,4 +69,5 @@
 	mutex_initialize(&ut->lock, MUTEX_PASSIVE);
 	waitq_initialize(&ut->go_wq);
+	condvar_initialize(&ut->active_cv);
 
 	ut->go_call = NULL;
@@ -446,6 +447,9 @@
 				waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST);
 			}
+			mutex_unlock(&t->udebug.lock);
+			condvar_broadcast(&t->udebug.active_cv);
+		} else {
+			mutex_unlock(&t->udebug.lock);
 		}
-		mutex_unlock(&t->udebug.lock);
 	}
 
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision 336db2955b9fd1ee85c8818b9408bc4e9dad9fc2)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision a074b4f9d5cf65707ae3aaffaf4564453f710efd)
@@ -209,7 +209,11 @@
 
 		mutex_lock(&t->udebug.lock);
-		if ((t->flags & THREAD_FLAG_USPACE) != 0)
+		if ((t->flags & THREAD_FLAG_USPACE) != 0) {
 			t->udebug.active = true;
-		mutex_unlock(&t->udebug.lock);
+			mutex_unlock(&t->udebug.lock);
+			condvar_broadcast(&t->udebug.active_cv);
+		} else {
+			mutex_unlock(&t->udebug.lock);
+		}
 	}
 
