diff mbox

[PR,libstdc++/51135] : Fix [4.7 Regression] SIGSEGV during exception cleanup on win32

Message ID CAEwic4ZXvBzKem-iXvEagvZP4eU=9thsyXbubQQwyeaeUM3pFQ@mail.gmail.com
State New
Headers show

Commit Message

Kai Tietz Dec. 8, 2011, 7:16 p.m. UTC
Hi,

this bug was caused by change of default-calling-convention of
__thiscall for class-member-functions on 32-bit IA windows target.
Issue is that that destructor pointer used default __cdecl
calling-convention instead.  This patch fix that.
As currently trunk is still broken for all SjLj targets (this clobber
patch really clobbered things ...) and so for 32-bit Windows native
too, it is necessary to disable - until this bug is fixed in compiler
(PR/51117)- for the unwind-sjlj.c file in libgcc the option
-fexceptions.

ChangeLog

2011-12-08  Kai Tietz  <ktietz@redhat.com>

	PR libstdc++/511135
	* libsupc++/cxxabi.h (_GLIBCXX_DESTRUCTOR_CALLCONVENTION): New
	macro.
	(__cxa_throw): Use it for destructor-argument.
	* eh_throw.cc (__cxa_throw): Likewise.
	* unwind-cxx.h (__cxa_exception): Use for member
	exceptionDestructor the _GLIBCXX_DESTRUCTOR_CALLCONVENTION macro.

Patch tested for i686-w64-mingw32, i686-pc-cygwin, x86_64-w64-mingw32,
and x86_64-unknown-linux-gnu.  Ok for apply?

Regards,
Kai

Comments

Jonathan Wakely Dec. 8, 2011, 8:22 p.m. UTC | #1
On Dec 8, 2011 7:16 PM, "Kai Tietz" wrote:
>
>        * unwind-cxx.h (__cxa_exception): Use for member
>        exceptionDestructor the _GLIBCXX_DESTRUCTOR_CALLCONVENTION macro.

I think "Use the _GLIBCXX_DESTRUCTOR_CALLCONVENTION macro for the
exceptionDestructor member" would make more sense.

However ...

> Index: gcc/libstdc++-v3/libsupc++/cxxabi.h
> ===================================================================
> --- gcc.orig/libstdc++-v3/libsupc++/cxxabi.h
> +++ gcc/libstdc++-v3/libsupc++/cxxabi.h
> @@ -51,6 +51,16 @@
>  #include <bits/cxxabi_tweaks.h>
>  #include <bits/cxxabi_forced.h>
>
> +// On 32-bit IA native windows target is the used calling-convention
> +// for class-member-functions of kind __thiscall.  As destructor is
> +// also of kind class-member-function, we need to specify for this
> +// target proper calling-convention on destructor-function-pointer.
> +#if defined (__MINGW32__) && defined (__i386__)
> +#define _GLIBCXX_DESTRUCTOR_CALLCONVENTION __thiscall
> +#else
> +#define _GLIBCXX_DESTRUCTOR_CALLCONVENTION
> +#endif

Could you define a typedef for void(*)(void*) and adapt that for
mingw32 instead of using the macro everywhere?

#if defined (__MINGW32__) && defined (__i386__)
typedef void (__thiscall *__cxxabi_dtor_type)(void*);
#else
typedef void (*__cxxabi_dtor_type)(void*);
#endif

(That would be my preference, but the maintainers of that code might disagree.)
Kai Tietz Dec. 8, 2011, 8:37 p.m. UTC | #2
2011/12/8 Jonathan Wakely <jwakely.gcc@gmail.com>:
> On Dec 8, 2011 7:16 PM, "Kai Tietz" wrote:
>>
>>        * unwind-cxx.h (__cxa_exception): Use for member
>>        exceptionDestructor the _GLIBCXX_DESTRUCTOR_CALLCONVENTION macro.
>
> I think "Use the _GLIBCXX_DESTRUCTOR_CALLCONVENTION macro for the
> exceptionDestructor member" would make more sense.

Thanks, I will add it to ChangeLog that way, if the macro variant is
selected by maintainer of that code.

> However ...
>
>> Index: gcc/libstdc++-v3/libsupc++/cxxabi.h
>> ===================================================================
>> --- gcc.orig/libstdc++-v3/libsupc++/cxxabi.h
>> +++ gcc/libstdc++-v3/libsupc++/cxxabi.h
>> @@ -51,6 +51,16 @@
>>  #include <bits/cxxabi_tweaks.h>
>>  #include <bits/cxxabi_forced.h>
>>
>> +// On 32-bit IA native windows target is the used calling-convention
>> +// for class-member-functions of kind __thiscall.  As destructor is
>> +// also of kind class-member-function, we need to specify for this
>> +// target proper calling-convention on destructor-function-pointer.
>> +#if defined (__MINGW32__) && defined (__i386__)
>> +#define _GLIBCXX_DESTRUCTOR_CALLCONVENTION __thiscall
>> +#else
>> +#define _GLIBCXX_DESTRUCTOR_CALLCONVENTION
>> +#endif
>
> Could you define a typedef for void(*)(void*) and adapt that for
> mingw32 instead of using the macro everywhere?
>
> #if defined (__MINGW32__) && defined (__i386__)
> typedef void (__thiscall *__cxxabi_dtor_type)(void*);
> #else
> typedef void (*__cxxabi_dtor_type)(void*);
> #endif
>
> (That would be my preference, but the maintainers of that code might disagree.)

Well, sure.  Might be even a more clear way to have here an explicit
type-name indicating arguments kind.  But code-maintainer should tell,
what variant is preferred here.

Kai
diff mbox

Patch

Index: gcc/libstdc++-v3/libsupc++/cxxabi.h
===================================================================
--- gcc.orig/libstdc++-v3/libsupc++/cxxabi.h
+++ gcc/libstdc++-v3/libsupc++/cxxabi.h
@@ -51,6 +51,16 @@ 
 #include <bits/cxxabi_tweaks.h>
 #include <bits/cxxabi_forced.h>

+// On 32-bit IA native windows target is the used calling-convention
+// for class-member-functions of kind __thiscall.  As destructor is
+// also of kind class-member-function, we need to specify for this
+// target proper calling-convention on destructor-function-pointer.
+#if defined (__MINGW32__) && defined (__i386__)
+#define _GLIBCXX_DESTRUCTOR_CALLCONVENTION __thiscall
+#else
+#define _GLIBCXX_DESTRUCTOR_CALLCONVENTION
+#endif
+
 #ifdef __cplusplus
 namespace __cxxabiv1
 {
@@ -596,7 +606,8 @@  namespace __cxxabiv1

   // Throw the exception.
   void
-  __cxa_throw(void*, std::type_info*, void (*) (void *))
+  __cxa_throw(void*, std::type_info*,
+	      void (_GLIBCXX_DESTRUCTOR_CALLCONVENTION *) (void *))
   __attribute__((__noreturn__));

   // Used to implement exception handlers.
Index: gcc/libstdc++-v3/libsupc++/eh_throw.cc
===================================================================
--- gcc.orig/libstdc++-v3/libsupc++/eh_throw.cc
+++ gcc/libstdc++-v3/libsupc++/eh_throw.cc
@@ -59,7 +59,8 @@  __gxx_exception_cleanup (_Unwind_Reason_

 extern "C" void
 __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
-			 void (*dest) (void *))
+			 void (_GLIBCXX_DESTRUCTOR_CALLCONVENTION *dest)
+			      (void *))
 {
   // Definitely a primary.
   __cxa_refcounted_exception *header
Index: gcc/libstdc++-v3/libsupc++/unwind-cxx.h
===================================================================
--- gcc.orig/libstdc++-v3/libsupc++/unwind-cxx.h
+++ gcc/libstdc++-v3/libsupc++/unwind-cxx.h
@@ -51,7 +51,7 @@  struct __cxa_exception
 {
   // Manage the exception object itself.
   std::type_info *exceptionType;
-  void (*exceptionDestructor)(void *);
+  void (_GLIBCXX_DESTRUCTOR_CALLCONVENTION *exceptionDestructor)(void *);

   // The C++ standard has entertaining rules wrt calling set_terminate
   // and set_unexpected in the middle of the exception cleanup process.