[Libreoffice-commits] core.git: 2 commits - bridges/source cppuhelper/Module_cppuhelper.mk

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Aug 9 13:55:54 UTC 2018


 bridges/source/cpp_uno/msvc_win32_intel/except.cxx  |   66 ++++++++++++++++++--
 bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx |   57 ++++++++++++++++-
 bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx   |    6 -
 cppuhelper/Module_cppuhelper.mk                     |    2 
 4 files changed, 117 insertions(+), 14 deletions(-)

New commits:
commit 654bd1ab45a0f24571f029fcd247cf28db575871
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Tue Aug 7 18:03:00 2018 +0200
Commit:     Stephan Bergmann <sbergman at redhat.com>
CommitDate: Thu Aug 9 15:55:39 2018 +0200

    No need for CppunitTest_cppuhelper_qa_misc to be a subsequentcheck
    
    Change-Id: I5b27c4803a9927ff9e2be084e7abbae7fdf94f55
    Reviewed-on: https://gerrit.libreoffice.org/58696
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/cppuhelper/Module_cppuhelper.mk b/cppuhelper/Module_cppuhelper.mk
index 296b85daf3f9..10d51758d662 100644
--- a/cppuhelper/Module_cppuhelper.mk
+++ b/cppuhelper/Module_cppuhelper.mk
@@ -19,11 +19,11 @@ $(eval $(call gb_Module_add_targets,cppuhelper,\
 $(eval $(call gb_Module_add_check_targets,cppuhelper,\
 	CppunitTest_cppuhelper_cppu_ifcontainer \
 	CppunitTest_cppuhelper_cppu_unourl \
+	CppunitTest_cppuhelper_qa_misc \
 ))
 
 # CppunitTest_cppuhelper_qa_weak depends on module bridges
 $(eval $(call gb_Module_add_subsequentcheck_targets,cppuhelper,\
-	CppunitTest_cppuhelper_qa_misc \
 	CppunitTest_cppuhelper_qa_weak \
 ))
 
commit 8313116f962ac87e103ea22aafb58700b8c695da
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Wed Aug 8 12:42:32 2018 +0200
Commit:     Stephan Bergmann <sbergman at redhat.com>
CommitDate: Thu Aug 9 15:55:28 2018 +0200

    Don't use internal __CxxDetectRethrow: it has side effects
    
    Since the __CxxDetectRethrow may increment __ProcessingThrow, which then
    must be decremented in __CxxUnregisterExceptionObject, and the latter does
    many other funny things with exception handling CRT machinery, we cannot
    use those internal functions (neither alone, nor together), or we end up
    breaking runtime's expectations: the runtime code checks __ProcessingThrow
    left and right, expecting its non-0 value to indicate "we are unwinding...
    possibly called from a dtor()". In this case, e.g., std::current_exception
    returns nullptr inside catch block.
    
    This creates our own copy of __CxxDetectRethrow, which does not mangle the
    global state, and just performs the same checks. This is a dirty hack, and
    it relies on current layout of the exception description layout - so must
    be synchronized in the event of changes!
    
    Change-Id: I2c475fbc2468073b796c7e9d0f4dfcd315896489
    Reviewed-on: https://gerrit.libreoffice.org/58730
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
index 3ce8f5c50db9..7af24e97c868 100644
--- a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
@@ -23,16 +23,16 @@
 #include <typeinfo.h>
 #include <signal.h>
 
-#include "rtl/alloc.h"
-#include "rtl/strbuf.hxx"
-#include "rtl/ustrbuf.hxx"
+#include <rtl/alloc.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
 #include <sal/log.hxx>
 #include <osl/mutex.hxx>
 
-#include "com/sun/star/uno/Any.hxx"
+#include <com/sun/star/uno/Any.hxx>
 #include <unordered_map>
 #include "msci.hxx"
-#include "except.hxx"
+#include <except.hxx>
 
 
 #pragma pack(push, 8)
@@ -468,6 +468,60 @@ void msci_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
     RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 3, arFilterArgs );
 }
 
+namespace
+{
+// This function does the same check as __CxxDetectRethrow from msvcrt (see its
+// crt/src/vcruntime/mgdframe.cpp). But it does not alter the global state, i.e. it does not
+// increment __ProcessingThrow, and so does not break following exception handling. We rely on the
+// definition of EHExceptionRecord, PER_IS_MSVC_EH and PER_PTHROW, that are current as of msvcrt
+// 2017 (14.14.26428).
+bool __DetectRethrow(void* ppExcept)
+{
+    struct EHExceptionRecord
+    {
+        DWORD ExceptionCode;
+        DWORD ExceptionFlags;
+        struct _EXCEPTION_RECORD* ExceptionRecord;
+        PVOID ExceptionAddress;
+        DWORD NumberParameters;
+        struct EHParameters
+        {
+            DWORD magicNumber;
+            PVOID pExceptionObject;
+            PVOID pThrowInfo;
+        } params;
+    };
+
+    constexpr auto PER_IS_MSVC_EH = [](EHExceptionRecord* p) {
+        constexpr DWORD EH_EXCEPTION_NUMBER = ('msc' | 0xE0000000); // The NT Exception # that msvcrt uses
+        constexpr DWORD EH_MAGIC_NUMBER1 = 0x19930520;              // latest magic # in thrown object
+        constexpr DWORD EH_MAGIC_NUMBER2 = 0x19930521;              // latest magic # in func info for exception specs
+        constexpr DWORD EH_MAGIC_NUMBER3 = 0x19930522;              // latest magic #
+        constexpr DWORD EH_EXCEPTION_PARAMETERS = 3;                // Number of parameters in exception record for x86
+
+        return p->ExceptionCode == EH_EXCEPTION_NUMBER
+               && p->NumberParameters == EH_EXCEPTION_PARAMETERS
+               && (p->params.magicNumber == EH_MAGIC_NUMBER1
+                   || p->params.magicNumber == EH_MAGIC_NUMBER2
+                   || p->params.magicNumber == EH_MAGIC_NUMBER3);
+    };
+
+    constexpr auto PER_PTHROW = [](EHExceptionRecord* p) {
+        return p->params.pThrowInfo;
+    };
+
+    EHExceptionRecord* pExcept;
+    if (!ppExcept)
+        return false;
+    pExcept = *(EHExceptionRecord**)ppExcept;
+    if (PER_IS_MSVC_EH(pExcept) && PER_PTHROW(pExcept) == nullptr)
+    {
+        return true;
+    }
+    return false;
+}
+}
+
 int msci_filterCppException(
     EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
 {
@@ -478,7 +532,7 @@ int msci_filterCppException(
     if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
         return EXCEPTION_CONTINUE_SEARCH;
 
-    bool rethrow = __CxxDetectRethrow( &pRecord );
+    const bool rethrow = __DetectRethrow(&pRecord);
     assert(pRecord == pPointers->ExceptionRecord);
 
     if (rethrow && pRecord == pPointers->ExceptionRecord)
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
index 86753103a751..c03716151bbc 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
@@ -782,6 +782,61 @@ void mscx_raiseException(
     RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 4, arFilterArgs);
 }
 
+namespace
+{
+// This function does the same check as __CxxDetectRethrow from msvcrt (see its
+// crt/src/vcruntime/mgdframe.cpp). But it does not alter the global state, i.e. it does not
+// increment __ProcessingThrow, and so does not break following exception handling. We rely on the
+// definition of EHExceptionRecord, PER_IS_MSVC_EH and PER_PTHROW, that are current as of msvcrt
+// 2017 (14.14.26428).
+bool __DetectRethrow(void* ppExcept)
+{
+    struct EHExceptionRecord
+    {
+        DWORD ExceptionCode;
+        DWORD ExceptionFlags;
+        struct _EXCEPTION_RECORD* ExceptionRecord;
+        PVOID ExceptionAddress;
+        DWORD NumberParameters;
+        struct alignas(8) EHParameters
+        {
+            DWORD magicNumber;
+            PVOID pExceptionObject;
+            PVOID pThrowInfo;
+            PVOID pThrowImageBase;
+        } params;
+    };
+
+    constexpr auto PER_IS_MSVC_EH = [](EHExceptionRecord* p) {
+        constexpr DWORD EH_EXCEPTION_NUMBER = ('msc' | 0xE0000000); // The NT Exception # that msvcrt uses
+        constexpr DWORD EH_MAGIC_NUMBER1 = 0x19930520;              // latest magic # in thrown object
+        constexpr DWORD EH_MAGIC_NUMBER2 = 0x19930521;              // latest magic # in func info for exception specs
+        constexpr DWORD EH_MAGIC_NUMBER3 = 0x19930522;              // latest magic #
+        constexpr DWORD EH_EXCEPTION_PARAMETERS = 4;                // Number of parameters in exception record for AMD64
+
+        return p->ExceptionCode == EH_EXCEPTION_NUMBER
+               && p->NumberParameters == EH_EXCEPTION_PARAMETERS
+               && (p->params.magicNumber == EH_MAGIC_NUMBER1
+                   || p->params.magicNumber == EH_MAGIC_NUMBER2
+                   || p->params.magicNumber == EH_MAGIC_NUMBER3);
+    };
+
+    constexpr auto PER_PTHROW = [](EHExceptionRecord* p) {
+        return p->params.pThrowInfo;
+    };
+
+    EHExceptionRecord* pExcept;
+    if (!ppExcept)
+        return false;
+    pExcept = *(EHExceptionRecord**)ppExcept;
+    if (PER_IS_MSVC_EH(pExcept) && PER_PTHROW(pExcept) == nullptr)
+    {
+        return true;
+    }
+    return false;
+}
+}
+
 int mscx_filterCppException(
     EXCEPTION_POINTERS * pPointers,
     uno_Any * pUnoExc,
@@ -796,7 +851,7 @@ int mscx_filterCppException(
     if (pRecord == nullptr || pRecord->ExceptionCode != MSVC_ExceptionCode)
         return EXCEPTION_CONTINUE_SEARCH;
 
-    bool rethrow = __CxxDetectRethrow( &pRecord );
+    const bool rethrow = __DetectRethrow(&pRecord);
     assert(pRecord == pPointers->ExceptionRecord);
 
     if (rethrow && pRecord == pPointers->ExceptionRecord)
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx b/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
index f2ccfbf4ab44..078fd23fd11f 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
@@ -47,11 +47,5 @@ void mscx_raiseException(
 
 }
 
-//TODO: Work around missing __CxxDetectRethrow in clang-cl for now (predefined
-// in cl, <www.geoffchappell.com/studies/msvc/language/predefined/index.html>):
-#if defined __clang__
-extern "C" int __cdecl __CxxDetectRethrow(void *);
-#endif
-
 #endif
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list