* fix: nodeIntegrationInWorker not working in AudioWorklet
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* fix: deadlock on Windows when destroying non-AudioWorklet worker contexts
The previous change kept the WebWorkerObserver alive across
ContextWillDestroy so the worker thread could be reused for the next
context (AudioWorklet thread pooling, Chromium CL:5270028). This is
correct for AudioWorklet but wrong for PaintWorklet and other worker
types, which Blink does not pool — each teardown destroys the thread.
For those worker types, ~NodeBindings was deferred to the thread-exit
TLS callback. By that point set_uv_env(nullptr) had already run, so on
Windows the embed thread was parked in GetQueuedCompletionStatus with a
stale async_sent latch that swallowed the eventual WakeupEmbedThread()
from ~NodeBindings. uv_thread_join then blocked forever, deadlocking
renderer navigation. The worker-multiple-destroy crash case timed out
on win-x64/x86/arm64 as a result. macOS/Linux (epoll/kqueue) don't have
the latch and were unaffected.
Plumb is_audio_worklet from WillDestroyWorkerContextOnWorkerThread into
ContextWillDestroy. For non-AudioWorklet contexts, restore the
pre-existing behavior of calling lazy_tls->Set(nullptr) at the end of
the last-context cleanup so ~NodeBindings runs while the worker thread
is still healthy. AudioWorklet continues to keep the observer alive so
the next pooled context can share NodeBindings.
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* chore: address review feedback
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* fix: stop embed thread before destroying environments in worker teardown
FreeEnvironment (called via environments_.clear()) runs uv_run to drain
handle close callbacks. On Windows, both that uv_run and the embed
thread's PollEvents call GetQueuedCompletionStatus on the same IOCP
handle. IOCP completions are consumed by exactly one waiter, so the
embed thread can steal completions that FreeEnvironment needs, causing
uv_run to block indefinitely. On Linux/Mac epoll_wait/kevent can wake
multiple waiters for the same event so the race doesn't manifest.
Add NodeBindings::StopPolling() which cleanly joins the embed thread
without destroying handles or the loop, and allows PrepareEmbedThread +
StartPolling to restart it later. Call StopPolling() in
WebWorkerObserver::ContextWillDestroy before environments_.clear() so
FreeEnvironment's uv_run is the only thread touching the IOCP.
Split PrepareEmbedThread's handle initialization (uv_async_init,
uv_sem_init) from thread creation via a new embed_thread_prepared_ flag
so the handles survive across stop/restart cycles for pooled worklets
while the embed thread itself can be recreated.
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* chore: address outstanding feedback
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* chore: update patches
---------
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
fix: prevent use-after-free when destroying guest WebContents during event emission
Multiple event emission sites in WebContents destroy the underlying C++
object via a JavaScript event handler calling webContents.destroy(), then
continue to dereference the freed `this` pointer. This is exploitable
through <webview> guest WebContents because Destroy() calls `delete this`
synchronously for guests, unlike non-guests which safely defer deletion.
The fix has two layers:
1. A new `is_emitting_event_` flag is checked in Destroy() — when true,
guest deletion is deferred to a posted task instead of executing
synchronously. This is separate from `is_safe_to_delete_` (which
gates LoadURL re-entrancy) to avoid rejecting legitimate loadURL
calls from event handlers.
2. AutoReset<bool> guards on `is_emitting_event_` are added to
CloseContents, RenderViewDeleted, DidFinishNavigation, and
SetContentsBounds, preventing synchronous destruction while their
Emit() calls are on the stack.
Destroy() now requires both `is_safe_to_delete_` (navigation re-entrancy)
and `!is_emitting_event_` (event emission) to allow synchronous guest
deletion. The existing AutoReset guards on `is_safe_to_delete_` in
DidStartNavigation, DidRedirectNavigation, and ReadyToCommitNavigation
are also now effective for guests.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
#47171 migrated `std::deque` to `base::circular_deque` in
`shell/common/crash_keys.cc`. However, `CrashKeyString` wraps a
`crashpad::Annotation` that holds self-referential pointers and
registers itself in a process-global linked list. `circular_deque`
relocates elements on growth (via `VectorBuffer::MoveConstructRange`),
leaving those pointers dangling — causing missing crash keys or a hung
crashpad handler (especially on macOS). The `base/containers/README.md`
warns: "Since `base::deque` does not have stable iterators and it will
move the objects it contains, it may not be appropriate for all uses."
Reverts to `std::deque`, whose block-based layout never relocates
existing elements. Adds a regression test that registers 50 dynamic
crash keys and verifies they all survive a renderer crash.
Notes: Fixed crash keys being lost and the crash reporter hanging on
macOS when many dynamic crash keys were registered.
Made-with: Cursor
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Alexey Kozy <alexey@anysphere.co>
V8's second-pass weak callbacks run inside a
DisallowJavascriptExecutionScope: they may touch the V8 API but must
not invoke JS, directly or indirectly. Several Electron Wrappables
(WebContents in particular) emit JS events from their destructors,
so deleting synchronously inside SecondWeakCallback can crash with
"Invoke in DisallowJavascriptExecutionScope" when GC happens to
collect the JS wrapper during a foreground GC task — typically during
shutdown's uv_run drain after a leaked WebContentsView.
This was previously latent and timing-dependent (electron/electron#47420,
electron/electron#45416, podman-desktop/podman-desktop#12409). The
esbuild migration's keepNames option (which wraps every function/class
with an Object.defineProperty call) shifted heap layout enough to make
the spec/fixtures/crash-cases/webcontentsview-create-leak-exit case
reliably reproduce it on every run, giving a clean signal for the fix.
Both WrappableBase and DeprecatedWrappableBase SecondWeakCallback now
post the deletion via base::SequencedTaskRunner::GetCurrentDefault()
so the destructor (and any Emit it does) runs once V8 has left the GC
scope. Falls back to synchronous deletion if no task runner is
available (early/late process lifetime).
Fixeselectron/electron#47420.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
* fix: preserve staged update dir when pruning orphaned update dirs on macOS
The previous squirrel.mac patch cleaned up all staged update directories
before starting a new download. This kept disk usage bounded but broke
quitAndInstall() if called while a subsequent checkForUpdates() was in
flight — the already-staged bundle would be deleted out from under it.
This reworks the patch to read ShipItState.plist and preserve the
directory it references, deleting only truly orphaned update.XXXXXXX
directories. Disk footprint stays bounded (at most 2 dirs: staged +
in-progress) and quitAndInstall() remains safe mid-check.
Also adds test coverage for the quitAndInstall/checkForUpdates race and
a triple-stack scenario where 3 updates arrive without a restart.
Refs https://github.com/electron/electron/issues/50200
Co-authored-by: Samuel Attard <sattard@anthropic.com>
* chore: update patches
---------
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
trap handlers will be initialized once the user script starts
but before app#ready. Wasm compilation before that phase will
break trap handler registeration due to the check in
v8::internal::wasm::UpdateComputedInformation. For some reason
this issue was only visible in <= 39-x-y when pdf-reader.mjs
was being loaded, maybe some module loading logic changed in >= 40-x-y
which are based on Node.js v24.x. In either case, it is best to
align the loading of wasm module required for the tests in light
of changes to how we are registering the trap handlers for the
main process.
* feat: enable innerWidth and innerHeight for window open
* update comment for added special innerWidth and innerHeight
* update 100 min spec requirement handling
* update testing to include getContentSize
* update macOS min requirement handling
* adjust refactored consts
* update const values from nativewindowviews
* feat: Corner Smoothing CSS rule (Reland)
Reland of #45185
* Fix patch conflicts
* fixup! Fix patch conflicts
* Update expected image
The dashed border is subtly different. The new version is correct and the old one was incorrect.
This fixture has been calling process.exit() immediately after writing
to stdout and stderr, which the Node.js docs say is risky behavior:
> Calling process.exit() will force the process to exit as quickly as
> possible even if there are still asynchronous operations pending that
> have not yet completed fully, including I/O operations to
> process.stdout and process.stderr.
This fixture's been around for years without problems (AFAIK).
The writes are very small ('hello\n' and 'world') and finish quickly.
But recently I've been testing on a very slow CI machine. There, I see
this spec flaking when it expects stderr to be 'world' but it gets ''.
This PR changes the fixture to wait for stdout & stderr to flush
before calling process.exit().
* feat: ServiceWorkerMain
* refactor: disconnect remote
* handle version_info_ nullptr case
* initiate finish request when possible and enumerate errors
* explicit name for test method
* oops
* fix: wait for redundant version to stop before destroying
* docs: clarify when undefined is returned
* chore: remove extra semicolons
* build: test windows runner
* build: try build windows on windows?
* build: take win/cross changes
* build: use bash as default shell always
* build: configure git for windows build tools
* build: bash as default
* build: configure windows correctly
* build: use sha1sum
* build: force windows cipd init and python3 existence
* just pain
* build: restore cache on windows
* build: use build-tools gclient
* build: sync gclient vars to build windows job
* build: output depshash for debugging
* build: past sam was a silly goose
* build: depshash logging
* build: force lf endings for lock and DEPS
* build: platform strings are hard
* build: checkout on windows host
* sup
* no check
* idk
* sigh
* ...
* no double checkout
* build: yolo some stuff
* build: run gn-check for windows on linux hosts for speed
* use container...
* cry ?
* build: e d
* e d
* no log
* fix toolchain on windows cross check
* build: use powershell to add mksnapshot_args
* build: enable x86 and arm64 windows builds too
* clean up
* maybe not needed
* build: keep action around for post step
* build: configure git global on win
* build: ia32 zip manifest
* build: no patch depot_tools for tests
* build: get arm64 windows closer to working
* build: windows tar is ass
* 32 bit on 32 bit
* maybe bash
* build: set up nodejs
* correct windows sharding
* fix some spec runner stuff
* fix windows tests
* overwrite -Force
* sigh
* screen res
* wat
* logs
* ... more logs
* line endings will be the death of me
* remove 1080p force thing
* vsctools + logging
* disable some fullscreen tests on GHA
* no progress
* run all CI
* install visual studio on arm64
* windows hax for non windows
* maybe arm sdk
* clean up depshash logic
* build: use single check per platform
* ensure clean args
* fix loop
* remove debug
* update default build image sha for dispatch
* plzzzz
* one more try
* arm64 vctools
* sad
* build: fix non-dispatch windows gn check
* chore: debug datadog-ci location
* chore: update build-tools for newer toolchain
* chore: set path for datadog-ci
* try this
* chore: fixup gn check
* fixup gn-check some more
* fixup windows gn check
* chore: fixup windows gn check
* test: use cmd for Windows testing
* fixup use cmd for testing on Windows
* fixup windows GN check
* fixup npm config arch for x86
* Can we set test files via powershell
* fixup to set test files via powershell
* fixup set test files via powershell
* Don't check cross instance cache disk space on Windows
* Use separate step to set env variables for testing
* fixup Use separate step to set env variables for testing
* fixup Use separate step to set env variables for testing
* fixup Use separate step to set env variables for testing (AGAIN)
* use powershell if in powershell
* fixup use powershell if in powershell
* chore: remove no longer needed changes to depot_tools
xref: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/5669094
and https://chromium-review.googlesource.com/c/chromium/src/+/5844046
* chore: try using 7zip on Windows to extract tarball
* Revert "chore: try using 7zip on Windows to extract tarball"
This reverts commit c7432b6a37.
* test: debug failing tests on GHA windows
* fix: ftbfs when including simdjson in Node.js
(cherry picked from commit 48e44c40d6)
* chore: try to track down Windows testing hang
* use correct timeout
* try this
* see if this helps
* try to figure out why node is running
* shard tests to try to narrow down WOA lockup
* try to narrow down problem test
* Narrow down blocking test more
* do we need a combo to repro
* see if this cleans up the tests
* fixup navigator.usb test
* remove logging from problematic tests
* Revert "shard tests to try to narrow down WOA lockup"
This reverts commit a180658376.
* remove logging
* debug keyboard test
* add timeout for Windows since arm64 sometimes hangs
* see if this helps
* put back original timeout
* try to use screenCapture to get screenshots of what is going on on WOA
* try using electron screencapture to debug WOA hang
* chore: turn off privacy experience
* run screenshot on both shards
* fixup screencap
* try to narrow down hanging spec
* chore: cleanup servers left open
* cleanup tests
* Revert "try to narrow down hanging spec"
This reverts commit a0f959f538.
* cleanup test debugging
* fixup extensions spec
* cleanup unneeded items
* run wtf with 2 shards instead of 6
* Revert "run wtf with 2 shards instead of 6"
This reverts commit ca2d282129.
* debug windows version on woa
* dump more info
* Get detailed CPU info
* revert debugging
* use same args as AppVeyor WOA for GHA WOA
* fixup use same args as AppVeyor WOA for GHA WOA
* fixup use same args as AppVeyor WOA for GHA WOA
* try to track down which tests trigger hang
* one or more of these combinations should hang
* break up web contents spec to find hang
* further break down api-web-contents to find hang
* test: ensure all webContents are closed
* test: fix require is not defined error
* see if api-web-contents spec is now good
* test: ensure all webContents are closed
* Revert "try to track down which tests trigger hang"
This reverts commit 07298d6ffe.
* chore: use alternate location for windows toolchain
* Reapply "try to track down which tests trigger hang"
This reverts commit 0321f76d01.
* try to narrow down problem test
* fix TEST_SHARD env var
* no, really fix TEST_SHARD env var
* see if this fixes it
* test: cleanup any remaining windows and webcontents
* see if new cleanup helps
* dont destroy webcontents for now
* fixup dont destroy webcontents for now
* Only cleanup right before process.exit
* see if this fixes the hang
* actually destroy webcontents
* Revert "Reapply "try to track down which tests trigger hang""
This reverts commit cdee7de049.
* see if this helps
* Revert "see if this helps"
This reverts commit 9a15a69cf7.
* Is it all about the web contents?
* it is all about the webcontents
but which one?
* Narrow down problem webcontents test
* try to speed up git install on WOA
* disable problematic test on WOA
* remove debugging
* remove debugging from choco installs
* Revert "disable problematic test on WOA"
This reverts commit e060fb0839.
* Revert "remove debugging"
This reverts commit f18dd8b1a5.
* run against all the tests in the failing shard
* don't run visibility tests first
* remove debugging
* 3 is a magic number
* Revert "3 is a magic number"
This reverts commit 36b91ccf9f.
* match what Appveyor runs exactly
* Revert "match what Appveyor runs exactly"
This reverts commit 7260dd4322.
* chore: sort files alphabetically
* find out what spec is leaving stuff open
* chore: Checkout PR HEAD commit
instead of merge commit
* try using app.exit instead of process.exit
* test: cleanup BrowserWindows and webContents
* Revert "chore: sort files alphabetically"
This reverts commit d9e217ffb1.
* chore: use win32 to match process.platform
Needed for build-tools to download from PRs
* chore: cache yarn dir
* fixup cache yarn
* fixup use win32 to match process.platform
* fixup use win32 to match process.platform
* fixup cache yarn
* Add debugging for WOA hang
* Add debugging for failing keyboard lock test
* Revert "Add debugging for WOA hang"
This reverts commit 8df03d568d.
* try using process.kill
* add more debugging to keyboard.lock test
* Revert "Add debugging for failing keyboard lock test"
* remove debugging
* test: disable keyboard.lock on Windows
* test: disable fullscreen tests on Windows
* test: only force test suite exit on WOA
* fixup test: only force test suite exit on WOA
* cleanup tests
* extract yarn caching/install to action
* try using bash to run windows tests
* remove left over debugging
* standardize on 'win' for Windows builds
* use 'x86' for arch for manifest files
* fixup try using bash to run windows tests
* fixup use 'x86' for arch for manifest files
* standardize on 'win' for Windows builds
* fixup use 'x86' for arch for manifest files
* fixup try using bash to run windows tests
---------
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Charles Kerr <charles@charleskerr.com>