diff --git a/watchman/Logging.h b/watchman/Logging.h index 6585b5cbc811..c159728f671b 100644 --- a/watchman/Logging.h +++ b/watchman/Logging.h @@ -129,6 +129,14 @@ void logf(LogLevel level, fmt::string_view format_str, Args&&... args) { getLog().logf(level, format_str, std::forward(args)...); } +// Log only to stderr. This bypasses Logging / folly::Synchronized which +// might deadlock during exit. +template +void logf_stderr(fmt::string_view format_str, Args&&... args) { + auto msg = fmt::format(fmt::runtime(format_str), std::forward(args)...); + ignore_result(write(STDERR_FILENO, msg.data(), msg.size())); +} + #ifdef _WIN32 LONG WINAPI exception_filter(LPEXCEPTION_POINTERS excep); #endif diff --git a/watchman/SignalHandler.cpp b/watchman/SignalHandler.cpp index 8c88ec7513c7..d264af722d18 100644 --- a/watchman/SignalHandler.cpp +++ b/watchman/SignalHandler.cpp @@ -104,7 +104,7 @@ static void crash_handler(int signo, siginfo_t* si, void*) { } if (si) { - auto msg = fmt::format( + logf_stderr( "Terminating due to signal {} {} generated by pid={} uid={} {} ({})\n", signo, w_strsignal(signo), @@ -112,14 +112,12 @@ static void crash_handler(int signo, siginfo_t* si, void*) { si->si_uid, reason, uintptr_t(si->si_value.sival_ptr)); - ignore_result(write(STDERR_FILENO, msg.data(), msg.size())); } else { - auto msg = fmt::format( + logf_stderr( "Terminating due to signal {} {} {}\n", signo, w_strsignal(signo), reason); - ignore_result(write(STDERR_FILENO, msg.data(), msg.size())); } #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS_FD) @@ -141,20 +139,21 @@ static void crash_handler(int signo, siginfo_t* si, void*) { #endif namespace { -void terminationHandler() { +[[noreturn]] void terminationHandler() { auto eptr = std::current_exception(); if (eptr) { try { std::rethrow_exception(eptr); } catch (const std::exception& exc) { - log(ABORT, "std::terminate was called. Exception: ", exc.what(), ".\n"); + logf_stderr("std::terminate was called. Exception: {}\n", exc.what()); } catch (...) { - log(ABORT, + logf_stderr( "std::terminate was called. Exception is not a std::exception.\n"); } } else { - log(ABORT, "std::terminate was called. There is no current exception.\n"); + logf_stderr("std::terminate was called. There is no current exception.\n"); } + std::abort(); } } // namespace diff --git a/watchman/main.cpp b/watchman/main.cpp index 9cdde7a29114..cba82b0abb86 100644 --- a/watchman/main.cpp +++ b/watchman/main.cpp @@ -1106,13 +1106,11 @@ int main(int argc, char** argv) { try { return inner_main(argc, argv); } catch (const std::exception& e) { - log(ERR, - "Uncaught C++ exception: ", - folly::exceptionStr(e).toStdString(), - "\n"); + logf_stderr( + "Uncaught C++ exception: {}\n", folly::exceptionStr(e).toStdString()); return 1; } catch (...) { - log(ERR, "Uncaught C++ exception: ...\n"); + logf_stderr("Uncaught C++ exception: ...\n"); return 1; } }