From d2c95a28bbbaddb2e31dad1a0690f85f7895db32 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 18:02:14 +0200 Subject: [PATCH] fix: add back fallback wasm-trap handling (#47345) * fix: add back fallback wasm-trap handling Refs https://chromium-review.googlesource.com/c/chromium/src/+/5372409 This change sets up wasm-trap handling for the case where content_shell has not enabled crash reporting but moves the responsibility to ElectronRendererClient. The default ContentRendererClient assumes that crash reporting is enabled (crashpad enabled by default) and does not set up its own handler. Co-authored-by: Shelley Vohr * chore: fix build Co-authored-by: deepak1556 --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Shelley Vohr Co-authored-by: deepak1556 --- patches/chromium/.patches | 1 - ...le_freezing_flags_after_init_in_node.patch | 30 ---------- shell/renderer/electron_renderer_client.cc | 58 +++++++++++++++++++ shell/renderer/electron_renderer_client.h | 3 + 4 files changed, 61 insertions(+), 31 deletions(-) delete mode 100644 patches/chromium/disable_freezing_flags_after_init_in_node.patch diff --git a/patches/chromium/.patches b/patches/chromium/.patches index e49e542bf3ca..471d0813543a 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -79,7 +79,6 @@ introduce_ozoneplatform_electron_can_call_x11_property.patch make_gtk_getlibgtk_public.patch custom_protocols_plzserviceworker.patch feat_filter_out_non-shareable_windows_in_the_current_application_in.patch -disable_freezing_flags_after_init_in_node.patch short-circuit_permissions_checks_in_mediastreamdevicescontroller.patch chore_add_electron_deps_to_gitignores.patch chore_modify_chromium_handling_of_mouse_events.patch diff --git a/patches/chromium/disable_freezing_flags_after_init_in_node.patch b/patches/chromium/disable_freezing_flags_after_init_in_node.patch deleted file mode 100644 index 39e2e7efaf50..000000000000 --- a/patches/chromium/disable_freezing_flags_after_init_in_node.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jeremy Rose -Date: Mon, 20 Jun 2022 14:53:37 -0700 -Subject: disable freezing flags after init in node - -This was introduced in -https://chromium-review.googlesource.com/c/chromium/src/+/3687671. - -When running node in the renderer, flags are updated after initialization, so -freezing the flags in Blink causes node initialization to fail. - -If possible, it would be ideal to do this without a patch. -https://bugs.chromium.org/p/v8/issues/detail?id=12887 suggests that there may -at some point be an API to "unfreeze" the flags, or we may be able to refactor -node initialization to not update flags after V8 initialization. - -diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc -index 7a20f5199bd6cb5d13f31ec5db3e3cc03821bc3a..22167f808cb7b27d5b2a8e517cdeee63205ab9ad 100644 ---- a/content/renderer/render_process_impl.cc -+++ b/content/renderer/render_process_impl.cc -@@ -212,6 +212,9 @@ RenderProcessImpl::RenderProcessImpl() - v8::V8::SetFlagsFromString(kSABPerContextFlag, sizeof(kSABPerContextFlag)); - } - -+ // Freezing flags after init conflicts with node in the renderer. -+ v8::V8::SetFlagsFromString("--no-freeze-flags-after-init"); -+ - if (base::FeatureList::IsEnabled(features::kWebAssemblyTrapHandler)) { - content::GetContentClient()->renderer()->SetUpWebAssemblyTrapHandler(); - } diff --git a/shell/renderer/electron_renderer_client.cc b/shell/renderer/electron_renderer_client.cc index 5757c2c76cad..4316faca17cc 100644 --- a/shell/renderer/electron_renderer_client.cc +++ b/shell/renderer/electron_renderer_client.cc @@ -6,6 +6,7 @@ #include +#include "base/base_switches.h" #include "base/command_line.h" #include "base/containers/contains.h" #include "base/debug/stack_trace.h" @@ -26,6 +27,13 @@ #include "third_party/blink/renderer/core/execution_context/execution_context.h" // nogncheck #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" // nogncheck +#if BUILDFLAG(IS_LINUX) && (defined(ARCH_CPU_X86_64) || defined(ARCH_CPU_ARM64)) +#define ENABLE_WEB_ASSEMBLY_TRAP_HANDLER_LINUX +#include "components/crash/core/app/crashpad.h" +#include "content/public/common/content_switches.h" +#include "v8/include/v8-wasm-trap-handler-posix.h" +#endif + namespace electron { ElectronRendererClient::ElectronRendererClient() @@ -36,6 +44,14 @@ ElectronRendererClient::ElectronRendererClient() ElectronRendererClient::~ElectronRendererClient() = default; +void ElectronRendererClient::PostIOThreadCreated( + base::SingleThreadTaskRunner* io_thread_task_runner) { + // Freezing flags after init conflicts with node in the renderer. + // We do this here in order to avoid having to patch the ctor in + // content/renderer/render_process_impl.cc. + v8::V8::SetFlagsFromString("--no-freeze-flags-after-init"); +} + void ElectronRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { new ElectronRenderFrameObserver(render_frame, this); @@ -230,6 +246,48 @@ void ElectronRendererClient::WillDestroyWorkerContextOnWorkerThread( } } +void ElectronRendererClient::SetUpWebAssemblyTrapHandler() { +// See CL:5372409 - copied from ShellContentRendererClient. +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) + // Mac and Windows use the default implementation (where the default v8 trap + // handler gets set up). + ContentRendererClient::SetUpWebAssemblyTrapHandler(); + return; +#elif defined(ENABLE_WEB_ASSEMBLY_TRAP_HANDLER_LINUX) + const bool crash_reporter_enabled = + crash_reporter::GetHandlerSocket(nullptr, nullptr); + + if (crash_reporter_enabled) { + // If either --enable-crash-reporter or --enable-crash-reporter-for-testing + // is enabled it should take care of signal handling for us, use the default + // implementation which doesn't register an additional handler. + ContentRendererClient::SetUpWebAssemblyTrapHandler(); + return; + } + + const bool use_v8_default_handler = + base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kDisableInProcessStackTraces); + + if (use_v8_default_handler) { + // There is no signal handler yet, but it's okay if v8 registers one. + v8::V8::EnableWebAssemblyTrapHandler(/*use_v8_signal_handler=*/true); + return; + } + + if (base::debug::SetStackDumpFirstChanceCallback( + v8::TryHandleWebAssemblyTrapPosix)) { + // Crashpad and Breakpad are disabled, but the in-process stack dump + // handlers are enabled, so set the callback on the stack dump handlers. + v8::V8::EnableWebAssemblyTrapHandler(/*use_v8_signal_handler=*/false); + return; + } + + // As the registration of the callback failed, we don't enable trap + // handlers. +#endif // defined(ENABLE_WEB_ASSEMBLY_TRAP_HANDLER_LINUX) +} + node::Environment* ElectronRendererClient::GetEnvironment( content::RenderFrame* render_frame) const { if (!injected_frames_.contains(render_frame)) diff --git a/shell/renderer/electron_renderer_client.h b/shell/renderer/electron_renderer_client.h index 5471f872eb39..1cabd0a546a1 100644 --- a/shell/renderer/electron_renderer_client.h +++ b/shell/renderer/electron_renderer_client.h @@ -38,6 +38,8 @@ class ElectronRendererClient : public RendererClientBase { void UndeferLoad(content::RenderFrame* render_frame); // content::ContentRendererClient: + void PostIOThreadCreated( + base::SingleThreadTaskRunner* io_thread_task_runner) override; void RenderFrameCreated(content::RenderFrame*) override; void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override; void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override; @@ -45,6 +47,7 @@ class ElectronRendererClient : public RendererClientBase { v8::Local context) override; void WillDestroyWorkerContextOnWorkerThread( v8::Local context) override; + void SetUpWebAssemblyTrapHandler() override; node::Environment* GetEnvironment(content::RenderFrame* frame) const;