diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index 52f6b15590f6c..c1560e982b207 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();