aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/libcxxrt/patches/pr41.2-fix-trace-format.patch
blob: a70c234b4f4fa264cd25ab3172b4766845dcdbc9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
--- contrib/libs/cxxsupp/libcxxrt/exception.cc	(index)
+++ contrib/libs/cxxsupp/libcxxrt/exception.cc	(working tree)
@@ -312,9 +312,44 @@ static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c)
 	return _URC_CONTINUE_UNWIND;
 }
 
+static void terminate_with_diagnostics() {
+    __cxa_eh_globals *globals = __cxa_get_globals();
+    __cxa_exception *ex = globals->caughtExceptions;
+
+    if (ex != nullptr) {
+		fprintf(stderr, "uncaught exception:\n    address -> %p\n", (void*)ex);
+		ex = realExceptionFromException(ex);
+
+		const __class_type_info *e_ti = 
+			static_cast<const __class_type_info*>(&typeid(std::exception));
+		const __class_type_info *throw_ti = 
+			dynamic_cast<const __class_type_info*>(ex->exceptionType);
+
+		if (throw_ti) {
+			void* ptr = ex + 1;
+
+			if (throw_ti->__do_upcast(e_ti, &ptr)) {
+				std::exception* e = static_cast<std::exception*>(ptr);
+
+				if (e) {
+					fprintf(stderr, "    what() -> \"%s\"\n", e->what());
+				}
+			}
+		}
+
+		size_t bufferSize = 128;
+		char *demangled = static_cast<char*>(malloc(bufferSize));
+		const char *mangled = ex->exceptionType->name();
+		int status;
+		demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status);
+		fprintf(stderr, "    type -> %s\n", status == 0 ? demangled : mangled);
+		if (status == 0) { free(demangled); }
+	}
+    abort();
+}
 
 /** The global termination handler. */
-static atomic<terminate_handler> terminateHandler = abort;
+static atomic<terminate_handler> terminateHandler = terminate_with_diagnostics;
 /** The global unexpected exception handler. */
 static atomic<unexpected_handler> unexpectedHandler = std::terminate;