From 4656bd0a6a26e3e60707406cac920c74d45b90de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Neunh=C3=B6ffer?= Date: Fri, 13 Sep 2019 12:27:30 +0200 Subject: [PATCH] Fix a shutdown busy loop after main if two exceptions collide. (#9982) --- arangod/RestServer/arangod.cpp | 5 +++++ lib/Basics/files.cpp | 18 ++++++++++++++++++ lib/Basics/operating-system.h | 9 +++++++++ 3 files changed, 32 insertions(+) diff --git a/arangod/RestServer/arangod.cpp b/arangod/RestServer/arangod.cpp index 7a1c6e5756..d59a48bd3b 100644 --- a/arangod/RestServer/arangod.cpp +++ b/arangod/RestServer/arangod.cpp @@ -330,6 +330,11 @@ namespace arangodb { // arangodb::application_features::ApplicationServer::server->beginShutdown(); int main(int argc, char* argv[]) { +#ifdef __linux__ + // Do not delete this! See lib/Basics/operating-system.h for details. + ThrowSomeException(); +#endif + std::string workdir(arangodb::basics::FileUtils::currentDirectory().result()); #ifdef __linux__ #if USE_ENTERPRISE diff --git a/lib/Basics/files.cpp b/lib/Basics/files.cpp index 1e1863571c..8ededb704c 100644 --- a/lib/Basics/files.cpp +++ b/lib/Basics/files.cpp @@ -2642,3 +2642,21 @@ bool TRI_GETENV(char const* which, std::string& value) { return true; #endif } + +////////////////////////////////////////////////////////////////////////////// +/// @brief bug fix for some race on libmusl and static linking +////////////////////////////////////////////////////////////////////////////// + +// The following function just throws an exception and catches it. This is +// used on Linux for the case that we link statically and the underlying +// C-library is libmusl. This configuration has a bug in libgcc which +// triggers a shutdown busy loop (after main), provided the very first +// exception being thrown in the life of the process happens in two threads +// at the same time. By throwing right at the beginning of main() when the +// process is still single-threaded, we circumvent this problem. +#ifdef __linux__ +void ThrowSomeException() { + try { throw 42; } catch(int const&) {}; +} +#endif + diff --git a/lib/Basics/operating-system.h b/lib/Basics/operating-system.h index 57a9b3631a..46b4efd306 100644 --- a/lib/Basics/operating-system.h +++ b/lib/Basics/operating-system.h @@ -671,6 +671,15 @@ #define TRI_uid_t uid_t #define TRI_gid_t gid_t +// The following function just throws an exception and catches it. This is +// used on Linux for the case that we link statically and the underlying +// C-library is libmusl. This configuration has a bug in libgcc which +// triggers a shutdown busy loop (after main), provided the very first +// exception being thrown in the life of the process happens in two threads +// at the same time. By throwing right at the beginning of main() when the +// process is still single-threaded, we circumvent this problem. +void ThrowSomeException(); + #endif // -----------------------------------------------------------------------------