diff --git a/libcxxabi/src/cxa_exception_storage.cpp b/libcxxabi/src/cxa_exception_storage.cpp --- a/libcxxabi/src/cxa_exception_storage.cpp +++ b/libcxxabi/src/cxa_exception_storage.cpp @@ -92,6 +92,11 @@ // to the Itanium ABI and is taken advantage of in several places in // libc++abi. __cxa_eh_globals *__cxa_get_globals_fast() { + // If threads are disabled at runtime, revert to single-threaded implementation. + if (!std::__libcpp_is_threading_api_enabled()) { + static __cxa_eh_globals eh_globals; + return &eh_globals; + } // First time through, create the key. if (0 != std::__libcpp_execute_once(&flag_, construct_)) abort_message("execute once failure in __cxa_get_globals_fast()"); diff --git a/libcxxabi/test/test_exception_storage.pass.cpp b/libcxxabi/test/test_exception_storage.pass.cpp --- a/libcxxabi/test/test_exception_storage.pass.cpp +++ b/libcxxabi/test/test_exception_storage.pass.cpp @@ -45,7 +45,19 @@ #endif int main() { -#ifndef _LIBCXXABI_HAS_NO_THREADS +#ifdef _LIBCXXABI_HAS_NO_THREADS + size_t thread_globals; + thread_code(&thread_globals); + // Check that __cxa_get_globals() is not NULL. + return (thread_globals == 0) ? 1 : 0; +#else // !_LIBCXXABI_HAS_NO_THREADS + // If threads are disabled at runtime, revert to single-threaded test. + if (!std::__libcpp_is_threading_api_enabled()) { + thread_code((void*)thread_globals); + // Check that __cxa_get_globals() is not NULL. + return (thread_globals[0] == 0) ? 1 : 0; + } + // Make the threads, let them run, and wait for them to finish for ( int i = 0; i < NUMTHREADS; ++i ) std::__libcpp_thread_create ( threads + i, thread_code, (void *) (thread_globals + i)); @@ -68,10 +80,5 @@ } } return retVal; -#else // _LIBCXXABI_HAS_NO_THREADS - size_t thread_globals; - thread_code(&thread_globals); - // Check that __cxa_get_globals() is not NULL. - return (thread_globals == 0) ? 1 : 0; #endif // !_LIBCXXABI_HAS_NO_THREADS }