Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Electron crash in escape key event handler on MacOS #96492

Closed
pelmers opened this issue Apr 28, 2020 · 7 comments
Closed

Electron crash in escape key event handler on MacOS #96492

pelmers opened this issue Apr 28, 2020 · 7 comments
Assignees
Labels
freeze-slow-crash-leak VS Code crashing, performance, freeze and memory leak issues upstream Issue identified as 'upstream' component related (exists outside of VS Code) upstream-issue-linked This is an upstream issue that has been reported upstream webview Webview issues

Comments

@pelmers
Copy link
Contributor

pelmers commented Apr 28, 2020

  • VSCode Version: 1.43.2 and 1.44.2
  • OS Version: MacOS 10.15.3 and 10.14.6

A number of users of VS Code at Facebook have reported VS Code crashes when the escape key is hit. A similar issue is #92880, but that was closed without resolution.

Steps to Reproduce:
Unfortunately this is not very reliable for me, but I do have multiple stack traces for evidence that all point to the same exception:

  1. use editor normally (reported examples: open a terminal, open command palette, use vim extension)
  2. hit escape
  3. Electron crashes (Apple issue reporter opens)

Crash report (from VS Code 1.44):

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000069
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [74003]

VM Regions Near 0x69:
-->
    __TEXT                 0000000104a03000-0000000104a2c000 [  164K] r-x/rwx SM=COW  /Applications/VS Code @ FB - Insiders.app/Contents/MacOS/Electron

Thread 0 Crashed:: CrBrowserMain  Dispatch queue: com.apple.main-thread
0   com.github.Electron.framework       0x0000000106587325 0x104a38000 + 28635941
1   com.github.Electron.framework       0x0000000104b450fd 0x104a38000 + 1102077
2   com.github.Electron.framework       0x00000001065872e9 0x104a38000 + 28635881
3   com.github.Electron.framework       0x0000000106a32751 0x104a38000 + 33531729
4   com.github.Electron.framework       0x000000010690f8f6 0x104a38000 + 32340214
5   com.github.Electron.framework       0x0000000106875c41 0x104a38000 + 31710273
6   com.github.Electron.framework       0x000000010689c037 0x104a38000 + 31866935
7   com.github.Electron.framework       0x000000010508498f 0x104a38000 + 6605199
8   com.github.Electron.framework       0x00000001070b2057 0x104a38000 + 40345687
9   com.github.Electron.framework       0x00000001070b6e2e 0x104a38000 + 40365614
10  com.github.Electron.framework       0x00000001070b66b4 0x104a38000 + 40363700
11  com.github.Electron.framework       0x00000001070af093 0x104a38000 + 40333459
12  com.github.Electron.framework       0x00000001070af90a 0x104a38000 + 40335626
13  com.github.Electron.framework       0x00000001070c5cde 0x104a38000 + 40426718
14  com.github.Electron.framework       0x0000000106d9ad02 0x104a38000 + 37104898
15  com.github.Electron.framework       0x0000000106daac94 0x104a38000 + 37170324
16  com.github.Electron.framework       0x0000000106dab167 0x104a38000 + 37171559
17  com.github.Electron.framework       0x0000000106e077a3 0x104a38000 + 37549987
18  com.github.Electron.framework       0x0000000106d4334a 0x104a38000 + 36746058
19  com.github.Electron.framework       0x0000000106e0710f 0x104a38000 + 37548303
20  com.apple.CoreFoundation            0x00007fff2c8e3b21 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
21  com.apple.CoreFoundation            0x00007fff2c8e3ac0 __CFRunLoopDoSource0 + 103
22  com.apple.CoreFoundation            0x00007fff2c8e38d4 __CFRunLoopDoSources0 + 209
23  com.apple.CoreFoundation            0x00007fff2c8e2740 __CFRunLoopRun + 1272
24  com.apple.CoreFoundation            0x00007fff2c8e1bd3 CFRunLoopRunSpecific + 499
25  com.apple.HIToolbox                 0x00007fff2b43765d RunCurrentEventLoopInMode + 292
26  com.apple.HIToolbox                 0x00007fff2b43739d ReceiveNextEventCommon + 600
27  com.apple.HIToolbox                 0x00007fff2b437127 _BlockUntilNextEventMatchingListInModeWithFilter + 64
28  com.apple.AppKit                    0x00007fff29aa7ba4 _DPSNextEvent + 990
29  com.apple.AppKit                    0x00007fff29aa6380 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
30  com.apple.AppKit                    0x00007fff29a9809e -[NSApplication run] + 658
31  com.github.Electron.framework       0x0000000106e07fac 0x104a38000 + 37552044
32  com.github.Electron.framework       0x0000000106e06ad8 0x104a38000 + 37546712
33  com.github.Electron.framework       0x0000000106dab648 0x104a38000 + 37172808
34  com.github.Electron.framework       0x0000000106d7f6c7 0x104a38000 + 36992711
35  com.github.Electron.framework       0x0000000106584fb3 0x104a38000 + 28626867
36  com.github.Electron.framework       0x0000000106586512 0x104a38000 + 28632338
37  com.github.Electron.framework       0x0000000106582266 0x104a38000 + 28615270
38  com.github.Electron.framework       0x0000000106440772 0x104a38000 + 27297650
39  com.github.Electron.framework       0x000000010644038e 0x104a38000 + 27296654
40  com.github.Electron.framework       0x0000000108555e29 0x104a38000 + 61988393
41  com.github.Electron.framework       0x00000001055e98d4 0x104a38000 + 12261588
42  com.github.Electron.framework       0x0000000104a3ad14 AtomMain + 84
43  com.facebook.fbvscode-insiders      0x0000000104a039e0 0x104a03000 + 2528
44  libdyld.dylib                       0x00007fff63f877fd start + 1

Symbolicated trace:

content::BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback(bool*, content::WebContents*) (in Electron Framework) (browser_plugin_embedder.cc:216)
electron::WebViewManager::ForEachGuest(content::WebContents*, base::RepeatingCallback<bool (content::WebContents*)> const&) (in Electron Framework) (web_view_manager.cc:72)
content::BrowserPluginEmbedder::HandleKeyboardEvent(content::NativeWebKeyboardEvent const&) (in Electron Framework) (browser_plugin_embedder.cc:179)
non-virtual thunk to content::WebContentsImpl::HandleKeyboardEvent(content::NativeWebKeyboardEvent const&) (in Electron Framework) (web_contents_impl.cc:2384)
content::RenderWidgetHostImpl::OnKeyboardEventAck(content::EventWithLatencyInfo<content::NativeWebKeyboardEvent> const&, content::InputEventAckSource, content::InputEventAckState) (in Electron Framework) (render_widget_host_impl.cc:2120)
content::InputRouterImpl::KeyboardEventHandled(content::EventWithLatencyInfo<content::NativeWebKeyboardEvent> const&, base::OnceCallback<void (content::EventWithLatencyInfo<content::NativeWebKeyboardEvent> const&, content::InputEventAckSource, content::InputEventAckState)>, content::InputEventAckSource, ui::LatencyInfo const&, content::InputEventAckState, base::Optional<ui::DidOverscrollParams> const&, base::Optional<cc::TouchAction> const&) (in Electron Framework) (input_router_impl.cc:562)
base::internal::Invoker<base::internal::BindState<void (content::InputRouterImpl::*)(content::EventWithLatencyInfo<content::NativeWebKeyboardEvent> const&, base::OnceCallback<void (content::EventWithLatencyInfo<content::NativeWebKeyboardEvent> const&, content::InputEventAckSource, content::InputEventAckState)>, content::InputEventAckSource, ui::LatencyInfo const&, content::InputEventAckState, base::Optional<ui::DidOverscrollParams> const&, base::Optional<cc::TouchAction> const&), base::WeakPtr<content::InputRouterImpl>, content::EventWithLatencyInfo<content::NativeWebKeyboardEvent>, base::OnceCallback<void (content::EventWithLatencyInfo<content::NativeWebKeyboardEvent> const&, content::InputEventAckSource, content::InputEventAckState)> >, void (content::InputEventAckSource, ui::LatencyInfo const&, content::InputEventAckState, base::Optional<ui::DidOverscrollParams> const&, base::Optional<cc::TouchAction> const&)>::RunOnce(base::internal::BindStateBase*, content::InputEventAckSource, ui::LatencyInfo const&, content::InputEventAckState, base::Optional<ui::DidOverscrollParams> const&, base::Optional<cc::TouchAction> const&) (in Electron Framework) (bind_internal.h:641)
content::mojom::WidgetInputHandler_DispatchEvent_ForwardToCallback::Accept(mojo::Message*) (in Electron Framework) (input_handler.mojom.cc:2051)
mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message*) (in Electron Framework) (interface_endpoint_client.cc:549)
mojo::internal::MultiplexRouter::ProcessIncomingMessage(mojo::internal::MultiplexRouter::MessageWrapper*, mojo::internal::MultiplexRouter::ClientCallBehavior, base::SequencedTaskRunner*) (in Electron Framework) (multiplex_router.cc:0)
mojo::internal::MultiplexRouter::Accept(mojo::Message*) (in Electron Framework) (multiplex_router.cc:602)
mojo::Connector::DispatchMessage(mojo::Message) (in Electron Framework) (connector.cc:514)
mojo::Connector::ReadAllAvailableMessages() (in Electron Framework) (connector.cc:589)
mojo::SimpleWatcher::OnHandleReady(int, unsigned int, mojo::HandleSignalsState const&) (in Electron Framework) (simple_watcher.cc:293)
base::TaskAnnotator::RunTask(char const*, base::PendingTask*) (in Electron Framework) (task_annotator.cc:142)
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::sequence_manager::LazyNow*, bool*) (in Electron Framework) (heap_profiler.h:93)
non-virtual thunk to base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() (in Electron Framework) (thread_controller_with_message_pump_impl.cc:270)
base::MessagePumpCFRunLoopBase::RunWork() (in Electron Framework) (message_pump_mac.mm:0)
base::mac::CallWithEHFrame(void () block_pointer) (in Electron Framework) + 10
base::MessagePumpCFRunLoopBase::RunWorkSource(void*) (in Electron Framework) (message_pump_mac.mm:466)
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
__CFRunLoopDoSource0 + 103
__CFRunLoopDoSources0 + 209
__CFRunLoopRun + 1272
CFRunLoopRunSpecific + 499
RunCurrentEventLoopInMode + 292
ReceiveNextEventCommon + 600
_BlockUntilNextEventMatchingListInModeWithFilter + 64
_DPSNextEvent + 990
-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
-[NSApplication run] + 658
base::MessagePumpNSApplication::DoRun(base::MessagePump::Delegate*) (in Electron Framework) (message_pump_mac.mm:0)
base::MessagePumpCFRunLoopBase::Run(base::MessagePump::Delegate*) (in Electron Framework) (message_pump_mac.mm:189)
non-virtual thunk to base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool, base::TimeDelta) (in Electron Framework) (thread_controller_with_message_pump_impl.cc:0)
base::RunLoop::Run() (in Electron Framework) (run_loop.cc:158)
content::BrowserMainLoop::RunMainMessageLoopParts() (in Electron Framework) (browser_main_loop.cc:1029)
content::BrowserMainRunnerImpl::Run() (in Electron Framework) (browser_main_runner_impl.cc:150)
content::BrowserMain(content::MainFunctionParams const&) (in Electron Framework) (browser_main.cc:47)
content::ContentMainRunnerImpl::RunServiceManager(content::MainFunctionParams&, bool) (in Electron Framework) (content_main_runner_impl.cc:556)
content::ContentMainRunnerImpl::Run(bool) (in Electron Framework) (content_main_runner_impl.cc:0)
service_manager::Main(service_manager::MainParams const&) (in Electron Framework) (main.cc:423)
content::ContentMain(content::ContentMainParams const&) (in Electron Framework) (content_main.cc:19)
AtomMain + 84
0x000009e0 (in Electron Framework)
start + 1
@vscodebot
Copy link

vscodebot bot commented Apr 28, 2020

(Experimental duplicate detection)
Thanks for submitting this issue. Please also check if it is already covered by an existing one, like:

@pelmers
Copy link
Contributor Author

pelmers commented Apr 28, 2020

Note that this stack trace is different from the one attached in #92192 (comment), also referenced in #92420

@deepak1556
Copy link
Contributor

@pelmers thanks for the report, based on it the root cause is same as the other issues you have linked to.

Just to confirm, is this crash seen with an internal build of VSCode at Facebook, if so do you build with OSS electron releases https://www.electronjs.org/releases/stable ?

@deepak1556 deepak1556 added freeze-slow-crash-leak VS Code crashing, performance, freeze and memory leak issues info-needed Issue requires more information from poster webview Webview issues labels Apr 29, 2020
@pelmers
Copy link
Contributor Author

pelmers commented Apr 29, 2020

Just to confirm, is this crash seen with an internal build of VSCode at Facebook, if so do you build with OSS electron releases https://www.electronjs.org/releases/stable ?

Yes, it's an internal build of VS Code, however it does use OSS Electron releases (the differences from OSS VS Code are mostly cosmetic, e.g. the welcome page)

@deepak1556
Copy link
Contributor

Thanks for confirming, the fix for this landed in an internal build of electron and I didn't upstream it yet.

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Tue, 17 Mar 2020 14:36:38 -0700
Subject: fix: ensure guest-embedder map is updated when webview is removed

There are use cases of webview where the container holding the webview is not
actually destroyed first, instead just webview gets removed from DOM, in such
situations the browser process map is not updated accordingly and holds reference
to stale guest contents, and any window operations like scroll, resize or keyboard
events that has to chain through browser embedder will lead to UAF crash.

Ref: https://github.com/microsoft/vscode/issues/92420

diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js
index 1bbf487159b46edb4c89791dab0ea270837357c3..10e0ebf85f67591b983d9778391979f4de01d3c3 100644
--- a/lib/browser/guest-view-manager.js
+++ b/lib/browser/guest-view-manager.js
@@ -254,6 +254,9 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
 // Remove an guest-embedder relationship.
 const detachGuest = function (embedder, guestInstanceId) {
   const guestInstance = guestInstances[guestInstanceId]
+
+  if (!guestInstance) return
+
   if (embedder !== guestInstance.embedder) {
     return
   }
@@ -336,6 +339,10 @@ handleMessage('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embed
   }
 })
 
+handleMessage('ELECTRON_GUEST_VIEW_MANAGER_DETACH_GUEST', function (event, guestInstanceId) {
+  return detachGuest(event.sender, guestInstanceId)
+})
+
 // this message is sent by the actual <webview>
 ipcMainInternal.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event, focus, guestInstanceId) {
   const guest = getGuest(guestInstanceId)
diff --git a/lib/renderer/web-view/guest-view-internal.ts b/lib/renderer/web-view/guest-view-internal.ts
index 551e6f8539e0e516ee1dde488de8a6677f9e50e8..da43ee42fd633df1ad0763508143995a30886017 100644
--- a/lib/renderer/web-view/guest-view-internal.ts
+++ b/lib/renderer/web-view/guest-view-internal.ts
@@ -110,9 +110,14 @@ export function attachGuest (
   invoke('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params)
 }
 
+export function detachGuest (guestInstanceId: number) {
+  return invokeSync('ELECTRON_GUEST_VIEW_MANAGER_DETACH_GUEST', guestInstanceId)
+}
+
 export const guestViewInternalModule = {
   deregisterEvents,
   createGuest,
   createGuestSync,
-  attachGuest
+  attachGuest,
+  detachGuest
 }
diff --git a/lib/renderer/web-view/web-view-element.ts b/lib/renderer/web-view/web-view-element.ts
index cdb81308e22d29961dfc21a58df47b4dacb78639..22574c505088bd74ed8b8e6949987289303da896 100644
--- a/lib/renderer/web-view/web-view-element.ts
+++ b/lib/renderer/web-view/web-view-element.ts
@@ -66,6 +66,9 @@ const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof
         return
       }
       guestViewInternal.deregisterEvents(internal.viewInstanceId)
+      if (internal.guestInstanceId) {
+        guestViewInternal.detachGuest(internal.guestInstanceId)
+      }
       internal.elementAttached = false
       this.internalInstanceId = 0
       internal.reset()

@deepak1556
Copy link
Contributor

I will upstream it today, that should help fix the crash on your end.

@deepak1556 deepak1556 added upstream Issue identified as 'upstream' component related (exists outside of VS Code) and removed info-needed Issue requires more information from poster labels Apr 29, 2020
@pelmers
Copy link
Contributor Author

pelmers commented Apr 29, 2020

Excellent, thanks for the quick response and fix!

@deepak1556 deepak1556 added the upstream-issue-linked This is an upstream issue that has been reported upstream label Apr 30, 2020
@pelmers pelmers closed this as completed Apr 22, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Jun 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
freeze-slow-crash-leak VS Code crashing, performance, freeze and memory leak issues upstream Issue identified as 'upstream' component related (exists outside of VS Code) upstream-issue-linked This is an upstream issue that has been reported upstream webview Webview issues
Projects
None yet
Development

No branches or pull requests

2 participants