Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision 4c925cd31e0a0d5ba86584befde68164c77404b8)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -215,4 +215,8 @@
 		return cor;
 	}
+
+	struct $coroutine * __cfactx_cor_active(void) {
+		return active_coroutine();
+	}
 }
 
Index: libcfa/src/concurrency/invoke.c
===================================================================
--- libcfa/src/concurrency/invoke.c	(revision 4c925cd31e0a0d5ba86584befde68164c77404b8)
+++ libcfa/src/concurrency/invoke.c	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -29,4 +29,5 @@
 // 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 * );
@@ -35,4 +36,8 @@
 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 4c925cd31e0a0d5ba86584befde68164c77404b8)
+++ libcfa/src/concurrency/invoke.h	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -98,4 +98,6 @@
 	}
 
+	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 4c925cd31e0a0d5ba86584befde68164c77404b8)
+++ libcfa/src/exception.c	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -59,11 +59,9 @@
 
 
-// Temperary global exception context. Does not work with concurency.
-static struct exception_context_t shared_stack = {NULL, NULL};
-
 // Get the current exception context.
 // There can be a single global until multithreading occurs, then each stack
-// needs its own. It will have to be updated to handle that.
-struct exception_context_t * this_exception_context() {
+// needs its own. We get this from libcfathreads (no weak attribute).
+__attribute__((weak)) struct exception_context_t * this_exception_context() {
+	static struct exception_context_t shared_stack = {NULL, NULL};
 	return &shared_stack;
 }
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision 4c925cd31e0a0d5ba86584befde68164c77404b8)
+++ tests/Makefile.am	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -163,4 +163,11 @@
 	$(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@})
 
+# Exception Tests
+# Test with libcfathread; it changes how storage works.
+
+exceptions/%-threads : exceptions/%.cfa $(CFACCBIN)
+	$(CFACOMPILETEST) -include exceptions/with-threads.hfa -c -o $(abspath ${@}).o
+	$(CFACCLOCAL) $($(shell echo "${@}_FLAGSLD" | sed 's/-\|\//_/g')) $(abspath ${@}).o -o $(abspath ${@})
+
 #------------------------------------------------------------------------------
 # Other targets
Index: tests/exceptions/.expect/conditional-threads.txt
===================================================================
--- tests/exceptions/.expect/conditional-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/exceptions/.expect/conditional-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,2 @@
+Caught num_error: expected=2 actual=2.
+Caught num_error: expected=2 actual=2.
Index: tests/exceptions/.expect/defaults-threads.txt
===================================================================
--- tests/exceptions/.expect/defaults-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/exceptions/.expect/defaults-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,10 @@
+Should be printed.
+jump catch handler.
+jump default handler.
+Catch unhandled_exception.
+cross terminate throw
+cross terminate default
+cross terminate catch
+cross resume throw
+cross resume default
+cross resume catch
Index: tests/exceptions/.expect/finally-threads.txt
===================================================================
--- tests/exceptions/.expect/finally-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/exceptions/.expect/finally-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,21 @@
+termination throw
+finally during unwind
+Exiting: termination inner finally
+termination catch
+finally after catch
+Exiting: termination outer finally
+
+resumption throw
+resumption catch
+finally after resume
+Exiting: resumption inner finally
+finally after catch
+Exiting: resumption outer finally
+
+walking out of try
+walking through finally
+Exiting: walking finally
+
+jumping out of try
+jumping through finally
+Exiting: jumping finally
Index: tests/exceptions/.expect/resume-threads.txt
===================================================================
--- tests/exceptions/.expect/resume-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/exceptions/.expect/resume-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,36 @@
+simple throw
+simple catch
+Exiting: simple catch clause
+end of try clause
+Exiting: simple try clause
+
+catch-all
+
+throwing child exception
+inner parent match
+
+caught yin as yin
+
+rethrow inner try
+caught throw, will rethrow
+Exiting: rethrowing catch clause
+caught rethrow
+Exiting: rethrow catch clause
+Exiting: rethrow inner try
+
+caught yin, will throw yang
+caught yang
+
+throwing first exception
+caught first exception
+throwing second exception
+caught second exception
+recaught first exception
+
+inner catch
+inner catch
+outer catch
+
+throw
+rethrow
+handle
Index: tests/exceptions/.expect/terminate-threads.txt
===================================================================
--- tests/exceptions/.expect/terminate-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/exceptions/.expect/terminate-threads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,34 @@
+simple throw
+Exiting: simple try clause
+simple catch
+Exiting: simple catch clause
+
+catch-all
+
+throwing child exception
+inner parent match
+
+caught yin as yin
+
+rethrow inner try
+Exiting: rethrow inner try
+caught throw, will rethrow
+Exiting: rethrowing catch clause
+caught rethrow
+Exiting: rethrow catch clause
+
+caught yin, will throw yang
+caught yang
+
+throwing first exception
+caught first exception
+throwing second exception
+caught second exception
+recaught first exception
+
+inner catch
+outer catch
+
+throw
+rethrow
+handle
Index: tests/exceptions/terminate.cfa
===================================================================
--- tests/exceptions/terminate.cfa	(revision 4c925cd31e0a0d5ba86584befde68164c77404b8)
+++ tests/exceptions/terminate.cfa	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -142,3 +142,2 @@
 	}
 }
-
Index: tests/exceptions/with-threads.hfa
===================================================================
--- tests/exceptions/with-threads.hfa	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/exceptions/with-threads.hfa	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,8 @@
+// Header used to force linking with libcfathread.
+
+// I know its "with threads" but a coroutine is enough to bring it all in.
+#include <coroutine.hfa>
+
+coroutine DummyCoroutine {};
+
+DummyCoroutine ignored_dummy_coroutine;
Index: tests/linking/.expect/exception-nothreads.txt
===================================================================
--- tests/linking/.expect/exception-nothreads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/linking/.expect/exception-nothreads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,1 @@
+no threads
Index: tests/linking/.expect/exception-withthreads.txt
===================================================================
--- tests/linking/.expect/exception-withthreads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/linking/.expect/exception-withthreads.txt	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,1 @@
+with threads
Index: tests/linking/exception-nothreads.cfa
===================================================================
--- tests/linking/exception-nothreads.cfa	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/linking/exception-nothreads.cfa	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,33 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// exception-nothreads.cfa --
+//
+// Author           : Andrew Beach
+// Created On       : Thr 13 16:12:00 2020
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr 13 16:49:00 2020
+// Update Count     : 0
+//
+
+#include <stdlib.hfa>
+#include <exception.hfa>
+
+TRIVIAL_EXCEPTION(ping);
+
+int main(void) {
+	try {
+		throwResume (ping){};
+	} catchResume (ping *) {
+		printf("%s threads\n", threading_enabled() ? "with" : "no");
+	}
+	return 0;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa nothreads.cfa" //
+// End: //
Index: tests/linking/exception-withthreads.cfa
===================================================================
--- tests/linking/exception-withthreads.cfa	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
+++ tests/linking/exception-withthreads.cfa	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -0,0 +1,34 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// exception-withthreads.cfa --
+//
+// Author           : Andrew Beach
+// Created On       : Thr 13 16:12:00 2020
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri 14 11:20:00 2020
+// Update Count     : 0
+//
+
+#include <stdlib.hfa>
+#include <exception.hfa>
+#include "../exceptions/with-threads.hfa"
+
+TRIVIAL_EXCEPTION(ping);
+
+int main(void) {
+	try {
+		throwResume (ping){};
+	} catchResume (ping *) {
+		printf("%s threads\n", threading_enabled() ? "with" : "no");
+	}
+	return 0;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa nothreads.cfa" //
+// End: //
Index: tests/linking/withthreads.cfa
===================================================================
--- tests/linking/withthreads.cfa	(revision 4c925cd31e0a0d5ba86584befde68164c77404b8)
+++ tests/linking/withthreads.cfa	(revision 5715d439df622d22c9e9975dcf841c7aaf7e01c5)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// nothreads.cfa --
+// withthreads.cfa --
 //
 // Author           : Thierry Delisle
