Author: tkreuzer
Date: Sat Aug 25 22:19:02 2012
New Revision: 57159
URL:
http://svn.reactos.org/svn/reactos?rev=57159&view=rev
Log:
[PSEH2]
PSEH2 uses a special mechanism to deal with nested try blocks inside the same function.
Instead of pushing a second exception registration record on the exception list, it uses
an internal pointer to handle the different try-levels.
But when a function using SEH is inlined, the resulting code will push 2 registration
frames on the stack. Now it happens with GCC 4.7.1 that these frames get shuffled on the
stack, putting one for the inner try on a higher stack address. This is something that
RtlUnwind regards as a bug and throws a STATUS_INVALID_UNWIND_TARGET exception. This was
the reason for the crashing PSEH2_TEST, when compiled with GCC 4.7.1.
To fix this, I added a mechanism that will prevent functions using SEH from being
inlined.
Modified:
trunk/reactos/include/reactos/libs/pseh/pseh2.h
Modified: trunk/reactos/include/reactos/libs/pseh/pseh2.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/pseh/…
==============================================================================
--- trunk/reactos/include/reactos/libs/pseh/pseh2.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/libs/pseh/pseh2.h [iso-8859-1] Sat Aug 25 22:19:02 2012
@@ -108,6 +108,14 @@
#ifdef __cplusplus
}
+#endif
+
+/* Prevent gcc from inlining functions that use SEH. */
+#if ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7))
+extern inline __attribute__((always_inline)) __attribute__((returns_twice)) void
_SEH_DontInline() {}
+#define __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS() _SEH_DontInline();
+#else
+#define __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS()
#endif
/* A no-op side effect that scares GCC */
@@ -246,6 +254,7 @@
auto __SEH_DECLARE_FINALLY(_SEHFinally);
#define _SEH2_TRY \
+ __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS() \
__SEH_BEGIN_SCOPE \
{ \
__SEH_SCOPE_LOCALS; \