From df45564cf0ad3b591d4eb8cc2354093bcb7df14c Mon Sep 17 00:00:00 2001 From: dexX7 Date: Fri, 27 Mar 2015 01:07:49 +0100 Subject: [PATCH 1/3] Initialization: set fallback locale as environment variable The scope of `std::locale::global` appears to be smaller than `setenv("LC_ALL", ...)` and insufficient to fix messed up locale settings for the whole application. --- src/util.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index a03f55c910c..4fea18b3068 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -713,18 +713,19 @@ void RenameThread(const char* name) void SetupEnvironment() { + std::locale loc("C"); // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale // may be invalid, in which case the "C" locale is used as fallback. #if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) try { - std::locale(""); // Raises a runtime error if current locale is invalid + loc = std::locale(""); // Raises a runtime error if current locale is invalid } catch (const std::runtime_error&) { - std::locale::global(std::locale("C")); + setenv("LC_ALL", "C", 1); } #endif // The path locale is lazy initialized and to avoid deinitialization errors // in multithreading environments, it is set explicitly by the main thread. - boost::filesystem::path::imbue(std::locale()); + boost::filesystem::path::imbue(loc); } void SetThreadPriority(int nPriority) From 7494e0915b1b6ab0d68b77a2f9140e365e41cef8 Mon Sep 17 00:00:00 2001 From: dexX7 Date: Wed, 25 Mar 2015 12:09:17 +0100 Subject: [PATCH 2/3] Initialization: setup environment before starting tests The environment is prepared by the main thread to guard against invalid locale settings and to prevent deinitialization issues of Boost path, which can result in app crashes. --- src/test/test_bitcoin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 5269e3bda7e..30626267ffa 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -30,6 +30,7 @@ struct TestingSetup { boost::thread_group threadGroup; TestingSetup() { + SetupEnvironment(); fPrintToDebugLog = false; // don't want to write to debug.log file fCheckBlockIndex = true; SelectParams(CBaseChainParams::UNITTEST); From 323de27f4b6a9673902cb414c3b0e3879b1366e7 Mon Sep 17 00:00:00 2001 From: dexX7 Date: Fri, 27 Mar 2015 01:33:34 +0100 Subject: [PATCH 3/3] Initialization: setup environment before starting QT tests The environment is prepared by the main thread to guard against invalid locale settings. --- src/qt/test/test_main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index f2161c2f793..7d7282db171 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -6,6 +6,7 @@ #include "config/bitcoin-config.h" #endif +#include "util.h" #include "uritests.h" #ifdef ENABLE_WALLET @@ -27,6 +28,7 @@ Q_IMPORT_PLUGIN(qkrcodecs) // This is all you need to run all the tests int main(int argc, char *argv[]) { + SetupEnvironment(); bool fInvalid = false; // Don't remove this, it's needed to access