From 5f8f6e909b42367c677590e2d0464400dff375fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Rolim?= Date: Wed, 9 Dec 2020 16:22:22 -0300 Subject: [PATCH 1/2] supertux/main: add try-catch block around locale initialization. Unfortunately, libstdc++'s locale implementation is platform specific (unlike libcxx, which has a single universal implementation), and its "generic" implementation, from 2003, claims to support only the "C" locale, and raises an exception if one tries to use a locale other than "C". We catch that exception and allow the application to proceed on such systems, even though it is very much not ideal. Also leave note for future code changes. Fixes #1564. --- src/supertux/main.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp index ad5e3fde69b..efd655855b0 100644 --- a/src/supertux/main.cpp +++ b/src/supertux/main.cpp @@ -563,10 +563,20 @@ Main::run(int argc, char** argv) _wfreopen(w_errpath.c_str(), L"a", stderr); #endif - // Create and install global locale - std::locale::global(boost::locale::generator().generate("")); - // Make boost.filesystem use it - boost::filesystem::path::imbue(std::locale()); + // Create and install global locale - this can fail on some situations: + // - with bad values for env vars (LANG, LC_ALL, ...) + // - targets where libstdc++ uses its generic locales code (https://gcc.gnu.org/legacy-ml/libstdc++/2003-02/msg00345.html) + // NOTE: when moving to C++ >= 17, keep the try-catch block, but use std::locale:global(std::locale("")); + try + { + std::locale::global(boost::locale::generator().generate("")); + // Make boost.filesystem use it + boost::filesystem::path::imbue(std::locale()); + } + catch(const std::runtime_error& err) + { + std::cout << "Warning: " << err.what() << std::endl; + } int result = 0; From 8036eb69cda3c2e6ed4f0753f6b3c691cbd90bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Rolim?= Date: Mon, 14 Dec 2020 23:45:52 -0300 Subject: [PATCH 2/2] supertux/error_handler: use the correct macro for identifying glibc. __GLIBCXX__ indicates that one is using libstdc++, not glibc. The correct macro for this is __GLIBC__. Also expand the comment about execinfo inclusion. --- src/supertux/error_handler.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/supertux/error_handler.cpp b/src/supertux/error_handler.cpp index a06dff1f1c9..b07e5517b08 100644 --- a/src/supertux/error_handler.cpp +++ b/src/supertux/error_handler.cpp @@ -16,9 +16,12 @@ #include "supertux/error_handler.hpp" -// apparently this is exclusive to glibc as of 2020, keep checking for -// llvm/msvc equivalent from time to time ~ Semphris -#ifdef __GLIBCXX__ +// execinfo.h as a built-in libc feature is exclusive to glibc as of 2020. +// On FreeBSD and musl systems, an external libexecinfo is available, but +// it has to be explicitly linked into the final executable. +// This is a *libc* feature, not a compiler one; furthermore, it's possible +// to verify its availability in CMakeLists.txt, if one is so inclined. +#ifdef __GLIBC__ #include #include #include @@ -29,7 +32,7 @@ bool ErrorHandler::m_handing_error = false; void ErrorHandler::set_handlers() { -#ifdef __GLIBCXX__ +#ifdef __GLIBC__ signal(SIGSEGV, handle_error); #endif } @@ -56,7 +59,7 @@ ErrorHandler::handle_error(int sig) void ErrorHandler::print_stack_trace() { -#ifdef __GLIBCXX__ +#ifdef __GLIBC__ void *array[10]; size_t size;