From: Vadim Zeitlin Date: Thu, 20 Sep 2012 23:00:44 +0000 (+0000) Subject: Rethrow abi::__forced_unwind in wxThread code under Unix. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/e02ea2030c4ee8c2d01c5823e2dc3d1ba7837acf?hp=9b9a7c3331eda5d674e3f67eb0add00df1bcf907 Rethrow abi::__forced_unwind in wxThread code under Unix. 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 --- diff --git a/configure b/configure index ab85cccdc2..82e9bfec5a 100755 --- 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 " @@ -20045,6 +20045,32 @@ fi 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 diff --git a/configure.in b/configure.in index 0ca7b1a007..c2e00d2cce 100644 --- a/configure.in +++ b/configure.in @@ -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 --------------------------------------------------------------------------- diff --git a/setup.h.in b/setup.h.in index bda2a49482..5f93e50dbf 100644 --- a/setup.h.in +++ b/setup.h.in @@ -1225,6 +1225,9 @@ /* Define if you have the header file. */ #undef HAVE_SYS_SELECT_H +/* Define if you have header file. */ +#undef HAVE_CXXABI_H + /* Define if fdopen is available. */ #undef HAVE_FDOPEN diff --git a/src/unix/threadpsx.cpp b/src/unix/threadpsx.cpp index ed33ff33c0..1bd5936523 100644 --- a/src/unix/threadpsx.cpp +++ b/src/unix/threadpsx.cpp @@ -54,6 +54,10 @@ #include #endif +#ifdef HAVE_CXXABI_H + #include +#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(); ) {