]> git.saurik.com Git - wxWidgets.git/commitdiff
Rethrow abi::__forced_unwind in wxThread code under Unix.
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 20 Sep 2012 23:00:44 +0000 (23:00 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 20 Sep 2012 23:00:44 +0000 (23:00 +0000)
We must always rethrow the special abi::__forced_unwind exception when
handling exception in threads under Linux as the NPTL simply terminates the
process at first opportunity if this exception is not rethrown.

See http://udrepper.livejournal.com/21541.html for more details.

Closes #14626.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72531 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

configure
configure.in
setup.h.in
src/unix/threadpsx.cpp

index ab85cccdc20bcfb8e1d0ec5fe672e4fc329d9d46..82e9bfec5a13c4619c45289ce24ba032d42bc3d1 100755 (executable)
--- a/configure
+++ b/configure
@@ -2809,6 +2809,37 @@ $as_echo "$ac_res" >&6; }
 
 } # ac_fn_c_check_header_compile
 
+# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_cxx_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_compile
+
 # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
 # --------------------------------------------
 # Tries to find the compile-time value of EXPR in a program that includes
@@ -2992,37 +3023,6 @@ rm -f conftest.val
 
 } # ac_fn_c_compute_int
 
-# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES
-# ---------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_cxx_check_header_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_cxx_check_header_compile
-
 # ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES
 # ---------------------------------------------
 # Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -20032,7 +20032,7 @@ case "${host}" in
 esac
 
 if test "$USE_UNIX" = 1 ; then
-    for ac_header in sys/select.h
+        for ac_header in sys/select.h
 do :
   ac_fn_c_check_header_compile "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default
 "
 
 done
 
+
+            ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    for ac_header in cxxabi.h
+do :
+  ac_fn_cxx_check_header_compile "$LINENO" "cxxabi.h" "ac_cv_header_cxxabi_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_cxxabi_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CXXABI_H 1
+_ACEOF
+
+fi
+
+done
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
 fi
 
 
index 0ca7b1a007034f026fcc9cd58df16b394c5950e4..c2e00d2cce198a0ff52a2d38aff2da610bd13162 100644 (file)
@@ -1591,9 +1591,15 @@ case "${host}" in
   ;;
 esac
 
-dnl POSIX needs this for select(), but old systems don't have it
 if test "$USE_UNIX" = 1 ; then
+    dnl POSIX needs this for select(), but old systems don't have it
     AC_CHECK_HEADERS([sys/select.h],,, [AC_INCLUDES_DEFAULT()])
+
+    dnl Header defining C++ ABI is currently only available with g++ but test
+    dnl for it unconditionally in case it becomes supported by other compilers.
+    AC_LANG_PUSH(C++)
+    AC_CHECK_HEADERS([cxxabi.h],,, [AC_INCLUDES_DEFAULT()])
+    AC_LANG_POP()
 fi
 
 dnl ---------------------------------------------------------------------------
index bda2a49482f2382deb21e090e86be8ae218e609c..5f93e50dbfdbed2ce349ebd785b4729664b42403 100644 (file)
 /* Define if you have the <sys/select.h> header file.  */
 #undef HAVE_SYS_SELECT_H
 
+/* Define if you have <cxxabi.h> header file. */
+#undef HAVE_CXXABI_H
+
 /* Define if fdopen is available.  */
 #undef HAVE_FDOPEN
 
index ed33ff33c027d7ac347c603edaa41795bd2b7cd1..1bd59365237fb632701342768d921ae593010f54 100644 (file)
     #include <thread.h>
 #endif
 
+#ifdef HAVE_CXXABI_H
+    #include <cxxabi.h>
+#endif
+
 // we use wxFFile under Linux in GetCPUCount()
 #ifdef __LINUX__
     #include "wx/ffile.h"
@@ -857,6 +861,18 @@ void *wxThreadInternal::PthreadStart(wxThread *thread)
                        wxT("Thread %p Entry() returned %lu."),
                        THR_ID(pthread), wxPtrToUInt(pthread->m_exitcode));
         }
+#ifdef HAVE_CXXABI_H
+        // When using common C++ ABI under Linux we must always rethrow this
+        // special exception used to unwind the stack when the thread was
+        // cancelled, otherwise the thread library would simply terminate the
+        // program, see http://udrepper.livejournal.com/21541.html
+        catch ( abi::__forced_unwind& )
+        {
+            wxCriticalSectionLocker lock(thread->m_critsect);
+            pthread->SetState(STATE_EXITED);
+            throw;
+        }
+#endif // HAVE_CXXABI_H
         wxCATCH_ALL( wxTheApp->OnUnhandledException(); )
 
         {