View | Details | Raw Unified | Return to bug 210022
Collapse All | Expand All

(-)devel/libcxxrt/Makefile (-3 / +2 lines)
Lines 1-8 Link Here
1
# $FreeBSD$
1
# $FreeBSD$
2
2
3
PORTNAME=	libcxxrt
3
PORTNAME=	libcxxrt
4
PORTVERSION=	20131225
4
PORTVERSION=	20160329
5
PORTREVISION=	3
6
CATEGORIES=	devel
5
CATEGORIES=	devel
7
6
8
MAINTAINER=	mokhi64@gmail.com
7
MAINTAINER=	mokhi64@gmail.com
Lines 12-18 Link Here
12
11
13
USE_GITHUB=	yes
12
USE_GITHUB=	yes
14
GH_ACCOUNT=	pathscale
13
GH_ACCOUNT=	pathscale
15
GH_TAGNAME=	2f150a6
14
GH_TAGNAME=	516a65c
16
15
17
USES=		cmake compiler:c++11-lang
16
USES=		cmake compiler:c++11-lang
18
USE_LDCONFIG=	yes
17
USE_LDCONFIG=	yes
(-)devel/libcxxrt/distinfo (-2 / +2 lines)
Lines 1-2 Link Here
1
SHA256 (pathscale-libcxxrt-20131225-2f150a6_GH0.tar.gz) = 70a89c34176d2bc683b5a3b84fea8d585bcf53c6b09d0efedbac3caf315b4fc1
1
SHA256 (pathscale-libcxxrt-20160329-516a65c_GH0.tar.gz) = 5d2b943fb8bcce453d3453246dd25242a01b2107631c52c90dbefff13fec1f65
2
SIZE (pathscale-libcxxrt-20131225-2f150a6_GH0.tar.gz) = 70243
2
SIZE (pathscale-libcxxrt-20160329-516a65c_GH0.tar.gz) = 73293
(-)devel/libcxxrt/files/patch-src_exception.cc (-48 lines)
Lines 1-48 Link Here
1
--- src/exception.cc.orig	2013-12-26 03:11:27 UTC
2
+++ src/exception.cc
3
@@ -304,13 +304,17 @@ static pthread_key_t eh_key;
4
 static void exception_cleanup(_Unwind_Reason_Code reason, 
5
                               struct _Unwind_Exception *ex)
6
 {
7
-	__cxa_free_exception(static_cast<void*>(ex));
8
+	// Exception layout:
9
+	// [__cxa_exception [_Unwind_Exception]] [exception object]
10
+	//
11
+	// __cxa_free_exception expects a pointer to the exception object
12
+	__cxa_free_exception(static_cast<void*>(ex + 1));
13
 }
14
 static void dependent_exception_cleanup(_Unwind_Reason_Code reason, 
15
                               struct _Unwind_Exception *ex)
16
 {
17
 
18
-	__cxa_free_dependent_exception(static_cast<void*>(ex));
19
+	__cxa_free_dependent_exception(static_cast<void*>(ex + 1));
20
 }
21
 
22
 /**
23
@@ -340,7 +344,8 @@ static void thread_cleanup(void* thread_
24
 		if (info->foreign_exception_state != __cxa_thread_info::none)
25
 		{
26
 			_Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(info->globals.caughtExceptions);
27
-			e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
28
+			if (e->exception_cleanup)
29
+				e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
30
 		}
31
 		else
32
 		{
33
@@ -1270,12 +1275,13 @@ extern "C" void __cxa_end_catch()
34
 	
35
 	if (ti->foreign_exception_state != __cxa_thread_info::none)
36
 	{
37
-		globals->caughtExceptions = 0;
38
 		if (ti->foreign_exception_state != __cxa_thread_info::rethrown)
39
 		{
40
 			_Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ti->globals.caughtExceptions);
41
-			e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
42
+			if (e->exception_cleanup)
43
+				e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
44
 		}
45
+		globals->caughtExceptions = 0;
46
 		ti->foreign_exception_state = __cxa_thread_info::none;
47
 		return;
48
 	}
(-)devel/libcxxrt/files/patch-test_CMakeLists.txt (-24 lines)
Lines 1-24 Link Here
1
--- test/CMakeLists.txt.orig	2013-12-26 03:11:27 UTC
2
+++ test/CMakeLists.txt
3
@@ -23,6 +23,11 @@ add_executable(cxxrt-test-shared ${CXXTE
4
 set_property(TARGET cxxrt-test-shared PROPERTY LINK_FLAGS -nodefaultlibs)
5
 target_link_libraries(cxxrt-test-shared cxxrt-shared pthread dl c)
6
 
7
+include_directories(${CMAKE_SOURCE_DIR}/src)
8
+add_executable(cxxrt-test-foreign-exceptions test_foreign_exceptions.cc)
9
+set_property(TARGET cxxrt-test-foreign-exceptions PROPERTY LINK_FLAGS "-nodefaultlibs -Wl,--wrap,_Unwind_RaiseException")
10
+target_link_libraries(cxxrt-test-foreign-exceptions cxxrt-static gcc_s pthread dl c)
11
+
12
 add_test(cxxrt-test-static-test
13
          ${CMAKE_CURRENT_SOURCE_DIR}/run_test.sh
14
          ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cxxrt-test-static
15
@@ -35,6 +40,9 @@ add_test(cxxrt-test-shared-test
16
          ${CMAKE_CURRENT_BINARY_DIR}/expected_output.log
17
          ${CMAKE_CURRENT_BINARY_DIR}/test-shared-output.log)
18
 
19
+add_test(cxxrt-test-foreign-exceptions
20
+         ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cxxrt-test-foreign-exceptions)
21
+
22
 set(valgrind "valgrind -q")
23
 
24
 if(TEST_VALGRIND)
(-)devel/libcxxrt/files/patch-test_test__foreign__exceptions.cc (-128 lines)
Lines 1-128 Link Here
1
--- test/test_foreign_exceptions.cc.orig	2016-05-29 13:30:15 UTC
2
+++ test/test_foreign_exceptions.cc
3
@@ -0,0 +1,125 @@
4
+#include <cstdio>
5
+#include <cstdlib>
6
+#include "unwind.h"
7
+
8
+#define EXCEPTION_CLASS(a,b,c,d,e,f,g,h) \
9
+	((static_cast<uint64_t>(a) << 56) +\
10
+	 (static_cast<uint64_t>(b) << 48) +\
11
+	 (static_cast<uint64_t>(c) << 40) +\
12
+	 (static_cast<uint64_t>(d) << 32) +\
13
+	 (static_cast<uint64_t>(e) << 24) +\
14
+	 (static_cast<uint64_t>(f) << 16) +\
15
+	 (static_cast<uint64_t>(g) << 8) +\
16
+	 (static_cast<uint64_t>(h)))
17
+
18
+// using ld --wrap=_Unwind_RaiseException hook feature
19
+extern "C" _Unwind_Reason_Code __real__Unwind_RaiseException (_Unwind_Exception *e);
20
+extern "C" _Unwind_Reason_Code __wrap__Unwind_RaiseException (_Unwind_Exception *e);
21
+
22
+extern "C" _Unwind_Reason_Code __wrap__Unwind_RaiseException (_Unwind_Exception *e)
23
+{
24
+	// clobber exception class forcing libcxx own exceptions to be treated
25
+	// as foreign exception within libcxx itself
26
+	e->exception_class = EXCEPTION_CLASS('F','O','R','E','I','G','N','\0');
27
+	__real__Unwind_RaiseException(e);
28
+}
29
+
30
+_Unwind_Exception global_e;
31
+
32
+enum test_status {
33
+	PENDING, PASSED, FAILED
34
+};
35
+
36
+const char test_status_str[][8] = {
37
+	"PENDING", "PASSED", "FAILED"
38
+};
39
+
40
+test_status test1_status = PENDING;
41
+test_status test2_status = PENDING;
42
+test_status test3_status = PENDING;
43
+
44
+void test2_exception_cleanup(_Unwind_Reason_Code code, _Unwind_Exception *e)
45
+{
46
+	fputs("(2) exception_cleanup called\n", stderr);
47
+	if (e != &global_e) {
48
+		fprintf(stderr, "(2) ERROR: unexpected ptr: expecting %p, got %p\n", &global_e, e);
49
+		test2_status = FAILED;
50
+	}
51
+	if (test2_status == PENDING)
52
+		test2_status = PASSED;
53
+}
54
+
55
+struct test3_exception
56
+{
57
+	static int counter;
58
+	~test3_exception()
59
+	{
60
+		counter++;
61
+		fputs("(3) exception dtor\n", stderr);
62
+	}
63
+};
64
+int test3_exception::counter = 0;
65
+
66
+int main()
67
+{
68
+	///////////////////////////////////////////////////////////////
69
+	fputs("(1) foreign exception, exception_cleanup=nullptr\n", stderr);
70
+	try
71
+	{
72
+		global_e.exception_class = 0;
73
+		global_e.exception_cleanup = 0;
74
+		__real__Unwind_RaiseException(&global_e);
75
+	}
76
+	catch (...)
77
+	{
78
+	}
79
+	test1_status = PASSED;
80
+	fputs("(1) PASS\n", stderr);
81
+
82
+	///////////////////////////////////////////////////////////////
83
+	fputs("(2) foreign exception, exception_cleanup present\n", stderr);
84
+	try
85
+	{
86
+		global_e.exception_class = 0;
87
+		global_e.exception_cleanup = test2_exception_cleanup;
88
+		__real__Unwind_RaiseException(&global_e);
89
+	}
90
+	catch (...)
91
+	{
92
+	}
93
+	fprintf(stderr, "(2) %s\n", test_status_str[test2_status]);
94
+
95
+	///////////////////////////////////////////////////////////////
96
+	fputs("(3) C++ exception in foreign environment\n", stderr);
97
+	int counter_expected;
98
+	try
99
+	{
100
+		// throw was rigged such that the runtime treats C++ exceptions
101
+		// as foreign ones
102
+		throw test3_exception();
103
+	}
104
+	catch (test3_exception&)
105
+	{
106
+		fputs("(3) ERROR: wrong catch\n", stderr);
107
+		test3_status = FAILED;
108
+	}
109
+	catch (...)
110
+	{
111
+		fputs("(3) catch(...)\n", stderr);
112
+		counter_expected = test3_exception::counter + 1;
113
+		// one more dtor immediately after we leave catch
114
+	}
115
+	if (test3_status == PENDING && test3_exception::counter != counter_expected) {
116
+		fputs("(3) ERROR: exception dtor didn't run\n", stderr);
117
+		test3_status = FAILED;
118
+	}
119
+	if (test3_status == PENDING)
120
+		test3_status = PASSED;
121
+	fprintf(stderr, "(3) %s\n", test_status_str[test3_status]);
122
+
123
+	///////////////////////////////////////////////////////////////
124
+	if (test1_status == PASSED && test2_status == PASSED && test3_status == PASSED)
125
+		return EXIT_SUCCESS;
126
+	else
127
+		return EXIT_FAILURE;
128
+}

Return to bug 210022