From 5aa25109b8ac55f1ab5648ab01c4678fdacdd611 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 26 Sep 2021 19:24:30 +0200 Subject: [PATCH] Work around Boost.Process invalid locale bug/crash This should not be causing any issues, but it seems like some people skip the locale setup step in the Arch installation guide and then end up with a distro without any locales, with invalid locales, or with a non-generated locale. glibc and libstd++ fall back to the C locale when this happens, but Boost.Process triggers one of the edge cases where this doesn't happen. https://github.com/boostorg/process/pull/179 fixes this in Boost.Process, but it will be a while until this is in every distro's copy of Boost. https://svn.boost.org/trac10/changeset/72855 --- CHANGELOG.md | 4 ++++ src/plugin/utils.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95cdcf7c..4ff995bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,10 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Fixed +- Worked around a [bug](https://svn.boost.org/trac10/changeset/72855) in + Boost.Process that would cause yabridge to crash with + `locale::facet::_S_create_c_locale name not valid` when (part of) the current + locale is invalid. - Fixed _New Sonic Arts' Vice_ plugin freezing when loading the plugin. This happened because the plugin tried to spawn new threads and perform drawing calls when changing the sample rate or block size from the audio thread. We're diff --git a/src/plugin/utils.cpp b/src/plugin/utils.cpp index 7fb7d1b3..247d8ff4 100644 --- a/src/plugin/utils.cpp +++ b/src/plugin/utils.cpp @@ -16,6 +16,8 @@ #include "utils.h" +#include + #include #include #include @@ -369,6 +371,31 @@ boost::filesystem::path generate_group_endpoint( } std::vector get_augmented_search_path() { + // HACK: `std::locale("")` would return the current locale, but this + // overload is implementation specific, and libstdc++ returns an error + // when this happens and one of the locale variables (or `LANG`) is + // set to a locale that doesn't exist. Because of that, you should use + // the default constructor instead which does fall back gracefully + // when using an invalid locale. Boost.Process sadly doesn't seem to + // do this, so some intervention is required. We can remove this once + // the PR linked below is merged into Boost proper and included in + // most distro's copy of Boost (which will probably take a while): + // + // https://svn.boost.org/trac10/changeset/72855 + // + // https://github.com/boostorg/process/pull/179 + try { + std::locale(""); + } catch (const std::runtime_error&) { + // We normally avoid modifying the current process' environment and + // instead use `boost::process::environment` to only modify the + // environment of launched child processes, but in this case we do need + // to fix this + // TODO: We don't have access to the logger here, so we can't inform the + // user that their locale is broken when this happens + setenv("LC_ALL", "C", true); // NOLINT(concurrency-mt-unsafe) + } + std::vector search_path = boost::this_process::path();