From c19fc2f502122608e5286f9f2e1ba2cee3042adc Mon Sep 17 00:00:00 2001 From: Ben Konyi Date: Tue, 8 Oct 2019 15:13:08 -0700 Subject: [PATCH] Unblock SIGPROF on flutter_tester start (#12813) Fixes https://github.com/flutter/flutter/issues/35140 --- shell/testing/tester_main.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index 52f6b1559..c1560e982 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -22,6 +22,10 @@ #include "third_party/dart/runtime/include/bin/dart_io_api.h" #include "third_party/dart/runtime/include/dart_api.h" +#if defined(OS_POSIX) +#include +#endif // defined(OS_POSIX) + namespace flutter { // Checks whether the engine's main Dart isolate has no pending work. If so, @@ -71,9 +75,31 @@ class ScriptCompletionTaskObserver { FML_DISALLOW_COPY_AND_ASSIGN(ScriptCompletionTaskObserver); }; +// Processes spawned via dart:io inherit their signal handling from the parent +// process. As part of spawning, the spawner blocks signals temporarily, so we +// need to explicitly unblock the signals we care about in the new process. In +// particular, we need to unblock SIGPROF for CPU profiling to work on the +// mutator thread in the main isolate in this process (threads spawned by the VM +// know about this limitation and automatically have this signal unblocked). +static void UnblockSIGPROF() { +#if defined(OS_POSIX) + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGPROF); + pthread_sigmask(SIG_UNBLOCK, &set, NULL); +#endif // defined(OS_POSIX) +} + int RunTester(const flutter::Settings& settings, bool run_forever) { const auto thread_label = "io.flutter.test"; + // Necessary if we want to use the CPU profiler on the main isolate's mutator + // thread. + // + // OSX WARNING: avoid spawning additional threads before this call due to a + // kernel bug that may enable SIGPROF on an unintended thread in the process. + UnblockSIGPROF(); + fml::MessageLoop::EnsureInitializedForCurrentThread(); auto current_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();