From b3123a2fd1e77cbdceb5ee7a70e796063b5ee5b9 Mon Sep 17 00:00:00 2001
From: Jacques Germishuys <jacques.germishuys@gmail.com>
Date: Tue, 30 Jul 2019 09:55:11 +0100
Subject: [PATCH] Problem: __try and __except isn't universally supported on
 windows

Solution: Manually push/pop an exception registration record.
Only set the thread name with a debugger present
---
 src/thread.cpp | 40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/src/thread.cpp b/src/thread.cpp
index b14d70757..3675899be 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -32,6 +32,10 @@
 #include "thread.hpp"
 #include "err.hpp"
 
+#ifdef ZMQ_HAVE_WINDOWS
+#include <winnt.h>
+#endif
+
 bool zmq::thread_t::get_started () const
 {
     return _started;
@@ -113,10 +117,22 @@ struct thread_info_t
 #pragma pack(pop)
 }
 
+typedef struct _MY_EXCEPTION_REGISTRATION_RECORD
+{
+    struct _MY_EXCEPTION_REGISTRATION_RECORD *Next;
+    void *Handler;
+} MY_EXCEPTION_REGISTRATION_RECORD;
+
+static EXCEPTION_DISPOSITION NTAPI continue_execution (EXCEPTION_RECORD *rec,
+	void *frame, CONTEXT *ctx, void *disp)
+{
+	return ExceptionContinueExecution;
+}
+
 void zmq::thread_t::
   applyThreadName () // to be called in secondary thread context
 {
-    if (!_name[0])
+    if (!_name[0] || !IsDebuggerPresent())
         return;
 
     thread_info_t thread_info;
@@ -125,17 +141,19 @@ void zmq::thread_t::
     thread_info._thread_id = -1;
     thread_info._flags = 0;
 
-#pragma warning(push)
-#pragma warning(disable : 6320 6322)
-    __try {
-        DWORD MS_VC_EXCEPTION = 0x406D1388;
+    NT_TIB *tib = ((NT_TIB*)NtCurrentTeb());
+
+    MY_EXCEPTION_REGISTRATION_RECORD rec;
+    rec.Next = (MY_EXCEPTION_REGISTRATION_RECORD *)tib->ExceptionList;
+    rec.Handler = continue_execution;
+
+    // push our handler, raise, and finally pop our handler
+    tib->ExceptionList = (_EXCEPTION_REGISTRATION_RECORD *)&rec;
+    DWORD MS_VC_EXCEPTION = 0x406D1388;
         RaiseException (MS_VC_EXCEPTION, 0,
-                        sizeof (thread_info) / sizeof (ULONG_PTR),
-                        (ULONG_PTR *) &thread_info);
-    }
-    __except (EXCEPTION_CONTINUE_EXECUTION) {
-    }
-#pragma warning(pop)
+            sizeof (thread_info) / sizeof (ULONG_PTR),
+            (ULONG_PTR *) &thread_info);
+    tib->ExceptionList = (_EXCEPTION_REGISTRATION_RECORD *)(((MY_EXCEPTION_REGISTRATION_RECORD *)tib->ExceptionList)->Next);
 }
 
 #elif defined ZMQ_HAVE_VXWORKS
