Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision 5fe7322de7a85b78511cb68a826169697d98f7c8)
+++ libcfa/src/Makefile.am	(revision d119d613d96b2bbb128789cdb7cae928896836d7)
@@ -53,5 +53,5 @@
 
 thread_headers = concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa \
-		concurrency/monitor.hfa concurrency/mutex.hfa
+		concurrency/monitor.hfa concurrency/mutex.hfa concurrency/exception.hfa
 
 thread_libsrc = concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \
Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision 5fe7322de7a85b78511cb68a826169697d98f7c8)
+++ libcfa/src/concurrency/coroutine.cfa	(revision d119d613d96b2bbb128789cdb7cae928896836d7)
@@ -215,8 +215,4 @@
 		return cor;
 	}
-
-	struct $coroutine * __cfactx_cor_active(void) {
-		return active_coroutine();
-	}
 }
 
Index: libcfa/src/concurrency/exception.cfa
===================================================================
--- libcfa/src/concurrency/exception.cfa	(revision d119d613d96b2bbb128789cdb7cae928896836d7)
+++ libcfa/src/concurrency/exception.cfa	(revision d119d613d96b2bbb128789cdb7cae928896836d7)
@@ -0,0 +1,91 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// exception.cfa -- Exceptions in a concurrent environment.
+//
+// Author           : Andrew Beach
+// Created On       : Mon Aug 17 10:41:00 2020
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue Aug 25 14:41:00 2020
+// Update Count     : 0
+//
+
+extern "C" {
+// use this define to make unwind.h play nice, definitely a hack
+#define HIDE_EXPORTS
+#include <unwind.h>
+#undef HIDE_EXPORTS
+}
+
+#include "invoke.h"
+#include "exception.hfa"
+#include "coroutine.hfa"
+
+extern struct $thread * mainThread;
+
+// Common pattern for all the stop functions, wait until the end then act.
+#define STOP_AT_END_FUNCTION(NAME, ...) \
+static _Unwind_Reason_Code NAME( \
+		int version, \
+		_Unwind_Action actions, \
+		_Unwind_Exception_Class exception_class, \
+		struct _Unwind_Exception * unwind_exception, \
+		struct _Unwind_Context * unwind_context, \
+		void * stop_param) { \
+	verify(actions & _UA_CLEANUP_PHASE); \
+	verify(actions & _UA_FORCE_UNWIND); \
+	verify(!(actions & _UA_SEARCH_PHASE)); \
+	verify(!(actions & _UA_HANDLER_FRAME)); \
+	if ( actions & _UA_END_OF_STACK ) { \
+		__VA_ARGS__ \
+	} else { \
+		return _URC_NO_REASON; \
+	} \
+}
+
+STOP_AT_END_FUNCTION(main_cancelstop,
+	abort();
+)
+
+STOP_AT_END_FUNCTION(thread_cancelstop,
+	// TODO: Instead pass information to the joiner.
+	abort();
+)
+
+STOP_AT_END_FUNCTION(coroutine_cancelstop,
+	// TODO: Instead pass information to the last resumer.
+	abort();
+)
+
+extern "C" {
+
+struct exception_context_t * this_exception_context(void) {
+	return &__get_stack( active_coroutine() )->exception_context;
+}
+
+_Unwind_Reason_Code __cfaehm_cancellation_unwind( struct _Unwind_Exception * unwind_exception ) {
+	_Unwind_Stop_Fn stop_func;
+	void * stop_param;
+
+	struct $thread * this_thread = TL_GET( this_thread );
+	if ( &this_thread->self_cor != this_thread->curr_cor ) {
+		struct $coroutine * cor = this_thread->curr_cor;
+		cor->cancellation = unwind_exception;
+
+		stop_func = coroutine_cancelstop;
+		stop_param = cor;
+	} else if ( mainThread == this_thread ) {
+		stop_func = main_cancelstop;
+		stop_param = (void *)0x22;
+	} else {
+		stop_func = thread_cancelstop;
+		stop_param = this_thread;
+	}
+
+	return _Unwind_ForcedUnwind( unwind_exception, stop_func, stop_param );
+}
+
+}
Index: libcfa/src/concurrency/exception.hfa
===================================================================
--- libcfa/src/concurrency/exception.hfa	(revision d119d613d96b2bbb128789cdb7cae928896836d7)
+++ libcfa/src/concurrency/exception.hfa	(revision d119d613d96b2bbb128789cdb7cae928896836d7)
@@ -0,0 +1,35 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// exception.hfa -- Exceptions in a concurrent environment.
+//
+// Author           : Andrew Beach
+// Created On       : Mon Aug 24 10:41:00 2020
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Aug 24 14:27:00 2020
+// Update Count     : 0
+//
+
+#pragma once
+
+#include "bits/defs.hfa"
+#include "invoke.h"
+struct _Unwind_Exception;
+
+// It must also be usable as a C header file.
+
+#ifdef __cforall
+extern "C" {
+#endif
+
+struct exception_context_t * this_exception_context(void) OPTIONAL_THREAD;
+
+_Unwind_Reason_Code __cfaehm_cancellation_unwind(
+		struct _Unwind_Exception * unwind_exception ) OPTIONAL_THREAD;
+
+#ifdef __cforall
+}
+#endif
Index: libcfa/src/concurrency/invoke.c
===================================================================
--- libcfa/src/concurrency/invoke.c	(revision 5fe7322de7a85b78511cb68a826169697d98f7c8)
+++ libcfa/src/concurrency/invoke.c	(revision d119d613d96b2bbb128789cdb7cae928896836d7)
@@ -29,5 +29,4 @@
 // Called from the kernel when starting a coroutine or task so must switch back to user mode.
 
-extern struct $coroutine * __cfactx_cor_active(void);
 extern struct $coroutine * __cfactx_cor_finish(void);
 extern void __cfactx_cor_leave ( struct $coroutine * );
@@ -36,8 +35,4 @@
 extern void disable_interrupts() OPTIONAL_THREAD;
 extern void enable_interrupts( __cfaabi_dbg_ctx_param );
-
-struct exception_context_t * this_exception_context() {
-	return &__get_stack( __cfactx_cor_active() )->exception_context;
-}
 
 void __cfactx_invoke_coroutine(
Index: libcfa/src/concurrency/invoke.h
===================================================================
--- libcfa/src/concurrency/invoke.h	(revision 5fe7322de7a85b78511cb68a826169697d98f7c8)
+++ libcfa/src/concurrency/invoke.h	(revision d119d613d96b2bbb128789cdb7cae928896836d7)
@@ -98,6 +98,4 @@
 	}
 
-	struct exception_context_t * this_exception_context();
-
 	// struct which calls the monitor is accepting
 	struct __waitfor_mask_t {
Index: libcfa/src/exception.c
===================================================================
--- libcfa/src/exception.c	(revision 5fe7322de7a85b78511cb68a826169697d98f7c8)
+++ libcfa/src/exception.c	(revision d119d613d96b2bbb128789cdb7cae928896836d7)
@@ -209,9 +209,11 @@
 		void * stop_param) {
 	// Verify actions follow the rules we expect.
-	verify((actions & _UA_CLEANUP_PHASE) && (actions & _UA_FORCE_UNWIND));
-	verify(!(actions & (_UA_SEARCH_PHASE | _UA_HANDLER_FRAME)));
+	verify(actions & _UA_CLEANUP_PHASE);
+	verify(actions & _UA_FORCE_UNWIND);
+	verify(!(actions & _UA_SEARCH_PHASE));
+	verify(!(actions & _UA_HANDLER_FRAME));
 
 	if ( actions & _UA_END_OF_STACK ) {
-		exit(1);
+		abort();
 	} else {
 		return _URC_NO_REASON;
@@ -219,11 +221,27 @@
 }
 
-static struct _Unwind_Exception cancel_exception_storage;
+__attribute__((weak)) _Unwind_Reason_Code
+__cfaehm_cancellation_unwind( struct _Unwind_Exception * exception ) {
+	return _Unwind_ForcedUnwind( exception, _Stop_Fn, (void*)0x22 );
+}
 
 // Cancel the current stack, prefroming approprate clean-up and messaging.
 void __cfaehm_cancel_stack( exception_t * exception ) {
-	// TODO: Detect current stack and pick a particular stop-function.
+	__cfaehm_allocate_exception( exception );
+
+	struct exception_context_t * context = this_exception_context();
+	struct __cfaehm_node * node = EXCEPT_TO_NODE(context->current_exception);
+
+	// Preform clean-up of any extra active exceptions.
+	while ( node->next ) {
+		struct __cfaehm_node * to_free = node->next;
+		node->next = to_free->next;
+		exception_t * except = NODE_TO_EXCEPT( to_free );
+		except->virtual_table->free( except );
+	    free( to_free );
+	}
+
 	_Unwind_Reason_Code ret;
-	ret = _Unwind_ForcedUnwind( &cancel_exception_storage, _Stop_Fn, (void*)0x22 );
+	ret = __cfaehm_cancellation_unwind( &node->unwind_exception );
 	printf("UNWIND ERROR %d after force unwind\n", ret);
 	abort();
