Index: uspace/app/tester/proc/task_wait.c
===================================================================
--- uspace/app/tester/proc/task_wait.c	(revision 1fb4a497b893f079da0aa5d8d86ebb054c860933)
+++ uspace/app/tester/proc/task_wait.c	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
@@ -262,5 +262,5 @@
 	TASSERT(rc == EOK);
 	TASSERT(task_wait_get(&wait) == 0);
-	//TASSERT(texit == TASK_EXIT_UNEXPECTED); // TODO resolve this in taskman/kernel
+	TASSERT(texit == TASK_EXIT_UNEXPECTED);
 	TPRINTF("OK\n");
 	/* ---- */
Index: uspace/srv/taskman/main.c
===================================================================
--- uspace/srv/taskman/main.c	(revision 1fb4a497b893f079da0aa5d8d86ebb054c860933)
+++ uspace/srv/taskman/main.c	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
@@ -122,8 +122,15 @@
 static void task_exit_event(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
-	// TODO design substitution for taskmon (monitoring)
 	task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall));
-	printf("%s:%i from %llu/%i\n", __func__, __LINE__, id, (task_exit_t)arg);
-	task_terminated(id, (task_exit_t)arg);
+	exit_reason_t exit_reason = IPC_GET_ARG3(*icall);
+	printf("%s:%i from %llu/%i\n", __func__, __LINE__, id, exit_reason);
+	task_terminated(id, exit_reason);
+}
+
+static void task_fault_event(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall));
+	printf("%s:%i from %llu\n", __func__, __LINE__, id);
+	task_failed(id);
 }
 
@@ -254,5 +261,5 @@
 	}
 
-	rc = async_event_subscribe(EVENT_EXIT, task_exit_event, (void *)TASK_EXIT_NORMAL);
+	rc = async_event_subscribe(EVENT_EXIT, task_exit_event, NULL);
 	if (rc != EOK) {
 		printf("Cannot register for exit events (%i).\n", rc);
@@ -260,5 +267,5 @@
 	}
 
-	rc = async_event_subscribe(EVENT_FAULT, task_exit_event, (void *)TASK_EXIT_UNEXPECTED);
+	rc = async_event_subscribe(EVENT_FAULT, task_fault_event, NULL);
 	if (rc != EOK) {
 		printf("Cannot register for fault events (%i).\n", rc);
Index: uspace/srv/taskman/task.c
===================================================================
--- uspace/srv/taskman/task.c	(revision 1fb4a497b893f079da0aa5d8d86ebb054c860933)
+++ uspace/srv/taskman/task.c	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
@@ -64,8 +64,9 @@
 	ht_link_t link;
 	
-	task_id_t id;        /**< task id. */
-	task_exit_t exit;    /**< task is done. */
+	task_id_t id;          /**< task id. */
+	task_exit_t exit;      /**< task's uspace exit status. */
+	bool failed;           /**< task failed. */
 	retval_t retval_type;  /**< task returned a value. */
-	int retval;          /**< the return value. */
+	int retval;            /**< the return value. */
 } hashed_task_t;
 
@@ -302,4 +303,5 @@
 	ht->id = call->in_task_id;
 	ht->exit = TASK_EXIT_RUNNING;
+	ht->failed = false;
 	ht->retval_type = RVAL_UNSET;
 	ht->retval = -1;
@@ -339,5 +341,5 @@
 }
 
-void task_terminated(task_id_t id, task_exit_t texit)
+void task_terminated(task_id_t id, exit_reason_t exit_reason)
 {
 	/* Mark task as finished. */
@@ -351,15 +353,35 @@
 	
 	/*
-	 * If daemon returns a value and then fails/is killed, it's unexpected
-	 * termination.
+	 * If daemon returns a value and then fails/is killed, it's an
+	 * unexpected termination.
 	 */
-	if (ht->retval_type == RVAL_UNSET || texit == TASK_EXIT_UNEXPECTED) {
+	if (ht->retval_type == RVAL_UNSET || exit_reason == EXIT_REASON_KILLED) {
 		ht->exit = TASK_EXIT_UNEXPECTED;
-	} else {
-		ht->exit = texit;
+	} else if (ht->failed) {
+		ht->exit = TASK_EXIT_UNEXPECTED;
+	} else  {
+		ht->exit = TASK_EXIT_NORMAL;
 	}
 	process_pending_wait();
 
 	hash_table_remove_item(&task_hash_table, &ht->link);
+finish:
+	fibril_rwlock_write_unlock(&task_hash_table_lock);
+}
+
+void task_failed(task_id_t id)
+{
+	/* Mark task as failed. */
+	fibril_rwlock_write_lock(&task_hash_table_lock);
+	ht_link_t *link = hash_table_find(&task_hash_table, &id);
+	if (link == NULL) {
+		goto finish;
+	}
+
+	hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link);
+	
+	ht->failed = true;
+	// TODO design substitution for taskmon (monitoring) = invoke dump utility
+
 finish:
 	fibril_rwlock_write_unlock(&task_hash_table_lock);
Index: uspace/srv/taskman/task.h
===================================================================
--- uspace/srv/taskman/task.h	(revision 1fb4a497b893f079da0aa5d8d86ebb054c860933)
+++ uspace/srv/taskman/task.h	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
@@ -45,5 +45,6 @@
 
 extern int task_intro(ipc_call_t *, bool);
-extern void task_terminated(task_id_t, task_exit_t);
+extern void task_terminated(task_id_t, exit_reason_t);
+extern void task_failed(task_id_t);
 
 #endif
