From 973d37af62a31734df6eb1d4b84f4271ce42194d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 22 May 2023 13:30:47 -0700 Subject: [PATCH 1/2] Make FML_LOG safe from static initialization --- fml/logging.cc | 5 +++-- fml/logging_unittests.cc | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/fml/logging.cc b/fml/logging.cc index 5a0280e0f0c25..61b4b5cf27858 100644 --- a/fml/logging.cc +++ b/fml/logging.cc @@ -123,8 +123,9 @@ LogMessage::~LogMessage() { fx_logger_log_with_source(fx_log_get_logger(), fx_severity, nullptr, file_, line_, stream_.str().c_str()); #else - std::cerr << stream_.str(); - std::cerr.flush(); + // Don't use std::cerr here, because it may not be initialized properly yet. + fprintf(stderr, "%s", stream_.str().c_str()); + fflush(stderr); #endif if (severity_ >= LOG_FATAL) { diff --git a/fml/logging_unittests.cc b/fml/logging_unittests.cc index a64d33e52f3fb..30d3df18e2b14 100644 --- a/fml/logging_unittests.cc +++ b/fml/logging_unittests.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include + #include "flutter/fml/build_config.h" #include "flutter/fml/log_settings.h" #include "flutter/fml/logging.h" @@ -19,6 +21,39 @@ namespace fml { namespace testing { +class MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled { + public: + MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled() { + SegfaultCatcher catcher; + // If this line causes a segfault, FML is using a method of logging that is + // not safe from static initialization on your platform. + FML_LOG(INFO) + << "This log exists to verify that static logging from FML works."; + } + + private: + struct SegfaultCatcher { + typedef void (*sighandler_t)(int); + + SegfaultCatcher() { + handler = ::signal(SIGSEGV, SegfaultHandler); + FML_CHECK(handler != SIG_ERR); + } + + ~SegfaultCatcher() { FML_CHECK(::signal(SIGSEGV, handler) != SIG_ERR); } + + static void SegfaultHandler(int signal) { + fprintf(stderr, + "FML failed to handle logging from static initialization.\n"); + exit(signal); + } + + sighandler_t handler; + }; +}; + +static MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled fml_log_static_check_; + int UnreachableScopeWithoutReturnDoesNotMakeCompilerMad() { KillProcess(); // return 0; <--- Missing but compiler is fine. From d0080813c38ad59bd22dd20086ed77f41b3bf581 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 22 May 2023 16:05:07 -0700 Subject: [PATCH 2/2] Skip Fuchsia --- fml/logging_unittests.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fml/logging_unittests.cc b/fml/logging_unittests.cc index 30d3df18e2b14..b418397640378 100644 --- a/fml/logging_unittests.cc +++ b/fml/logging_unittests.cc @@ -21,6 +21,7 @@ namespace fml { namespace testing { +#ifndef OS_FUCHSIA class MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled { public: MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled() { @@ -53,6 +54,7 @@ class MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled { }; static MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled fml_log_static_check_; +#endif // !defined(OS_FUCHSIA) int UnreachableScopeWithoutReturnDoesNotMakeCompilerMad() { KillProcess();