Index: libcfa/src/exception.c
===================================================================
--- libcfa/src/exception.c	(revision 918b90c2c118ccce3f17377dd84acdc610d18854)
+++ libcfa/src/exception.c	(revision 8ad57526fac65680cee486a070c56fdcbee2a28e)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jun 26 15:13:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue May 19 14:17:00 2020
-// Update Count     : 19
+// Last Modified On : Thr May 21 12:18:00 2020
+// Update Count     : 20
 //
 
@@ -237,7 +237,14 @@
 }
 
+static void __cfaehm_cleanup_default( exception_t ** except ) {
+	__cfaehm_delete_exception( *except );
+	*except = NULL;
+}
+
 // The exception that is being thrown must already be stored.
 static void __cfaehm_begin_unwind(void(*defaultHandler)(exception_t *)) {
-	if ( ! this_exception_context()->current_exception ) {
+	struct exception_context_t * context = this_exception_context();
+	struct _Unwind_Exception * storage = &this_exception_storage;
+	if ( NULL == context->current_exception ) {
 		printf("UNWIND ERROR missing exception in begin unwind\n");
 		abort();
@@ -245,5 +252,6 @@
 
 	// Call stdlibc to raise the exception
-	_Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
+	__cfadbg_print_safe(exception, "Begin unwinding (storage &p, context %p)\n", storage, context);
+	_Unwind_Reason_Code ret = _Unwind_RaiseException( storage );
 
 	// If we reach here it means something happened. For resumption to work we need to find a way
@@ -254,14 +262,16 @@
 	// the whole stack.
 
+	// We did not simply reach the end of the stack without finding a handler. This is an error.
+	if ( ret != _URC_END_OF_STACK ) {
+		printf("UNWIND ERROR %d after raise exception\n", ret);
+		abort();
+	}
+
 	// No handler found, go to the default operation.
-	if ( ret == _URC_END_OF_STACK ) {
-		__cfadbg_print_safe(exception, "Uncaught exception %p\n", &this_exception_storage);
-
-		defaultHandler( this_exception_context()->current_exception );
-	}
-
-	// We did not simply reach the end of the stack without finding a handler. This is an error.
-	printf("UNWIND ERROR %d after raise exception\n", ret);
-	abort();
+	__cfadbg_print_safe(exception, "Uncaught exception %p\n", storage);
+
+	__attribute__((cleanup(__cfaehm_cleanup_default)))
+	exception_t * exception = context->current_exception;
+	defaultHandler( exception );
 }
 
Index: tests/exceptions/.expect/defaults.txt
===================================================================
--- tests/exceptions/.expect/defaults.txt	(revision 8ad57526fac65680cee486a070c56fdcbee2a28e)
+++ tests/exceptions/.expect/defaults.txt	(revision 8ad57526fac65680cee486a070c56fdcbee2a28e)
@@ -0,0 +1,4 @@
+Should be printed.
+jump catch handler.
+jump default handler.
+Catch unhandled_exception.
Index: tests/exceptions/defaults.cfa
===================================================================
--- tests/exceptions/defaults.cfa	(revision 8ad57526fac65680cee486a070c56fdcbee2a28e)
+++ tests/exceptions/defaults.cfa	(revision 8ad57526fac65680cee486a070c56fdcbee2a28e)
@@ -0,0 +1,75 @@
+// Tests for providing new default operations.
+
+#include <string.h>
+#include <exception.hfa>
+
+DATA_EXCEPTION(log_message)(
+	char * msg;
+);
+
+void ?{}(log_message & this, char * msg) {
+	VTABLE_INIT(this, log_message);
+	this.msg = msg;
+}
+
+char * get_log_message(log_message * this) {
+	return this->msg;
+}
+
+VTABLE_INSTANCE(log_message)(get_log_message);
+
+// Logging messages don't have to be handled.
+void defaultResumptionHandler(log_message &) {}
+
+// And should never be used to terminate computation.
+void defaultTerminationHandler(log_message &) = void;
+
+void log_test(void) {
+	// We can catch log:
+	try {
+		throwResume (log_message){(char *)"Should be printed.\n"};
+	} catchResume (log_message * this) {
+		printf(this->virtual_table->msg(this));
+	}
+	// But we don't have to:
+	throwResume (log_message){(char *)"Should not be printed.\n"};
+}
+
+// I don't have a good use case for doing the same with termination.
+TRIVIAL_EXCEPTION(jump);
+void defaultTerminationHandler(jump &) {
+	printf("jump default handler.\n");
+}
+
+void jump_test(void) {
+	try {
+		throw (jump){};
+	} catch (jump * this) {
+		printf("jump catch handler.\n");
+	}
+	throw (jump){};
+}
+
+TRIVIAL_EXCEPTION(first);
+TRIVIAL_EXCEPTION(unhandled_exception);
+
+void unhandled_test(void) {
+	forall(dtype T | is_exception(T))
+	void defaultTerminationHandler(T &) {
+		throw (unhandled_exception){};
+	}
+	void defaultTerminationHandler(unhandled_exception &) {
+		abort();
+	}
+	try {
+		throw (first){};
+	} catch (unhandled_exception * t) {
+		printf("Catch unhandled_exception.\n");
+	}
+}
+
+int main(int argc, char * argv[]) {
+	log_test();
+	jump_test();
+	unhandled_test();
+}
