[Bug]: Using ThreadSafeFunction in child window causes assertion violation
Preflight Checklist
- [X] I have read the Contributing Guidelines for this project.
- [X] I agree to follow the Code of Conduct that this project adheres to.
- [X] I have searched the issue tracker for a bug report that matches the one I want to file, without success.
Electron Version
18.0.0
What operating system are you using?
Windows
Operating System Version
Windows 10 Pro 19044.1645
What arch are you using?
x64
Last Known Working Electron version
16.2.3
Expected Behavior
Assuming the N-API module is correctly implemented in context-aware matter the render process does not crash.
Actual Behavior
Crash log observed in the console:
C:\Windows\system32\cmd.exe [39088]: ../../third_party/electron_node/src/api/callback.cc:68: Assertion `(Environment::GetCurrent(isolate)) == (env)' failed.
1: 00007FF7DD474AA6 node::Buffer::New+50438
2: 00007FF7DD4747E9 node::Buffer::New+49737
3: 00007FF7DD416A01 node::CallbackScope::CallbackScope+593
4: 00007FF7DD4167ED node::CallbackScope::CallbackScope+61
5: 00007FF7DE02CDB9 node::AsyncResource::CallbackScope::CallbackScope+89
6: 00007FF7DD9D5DDC node_api_get_module_file_name+4092
7: 00007FF7DD48802C uv_run+492
8: 00007FF7DBB8DFB8 node::FreeArrayBufferAllocator+23608
9: 00007FF7DEFA11E8 cppgc::internal::WriteBarrier::DijkstraMarkingBarrierRangeSlow+3187976
10: 00007FF7DF06A492 Cr_z_crc32+629122
11: 00007FF7DD4A30E2 uv_sleep+93074
12: 00007FF7DD4ACBEA uv_sleep+132762
13: 00007FF7DCEE2C45 uv_timer_get_repeat+6778117
14: 00007FF7DD34F202 IsSandboxedProcess+3875010
15: 00007FF7DBC87ECC v8::metrics::LongTaskStats::LongTaskStats+496028
16: 00007FF7DBC889AD v8::metrics::LongTaskStats::LongTaskStats+498813
17: 00007FF7DBC84F3C v8::metrics::LongTaskStats::LongTaskStats+483852
18: 00007FF7DBC852B0 v8::metrics::LongTaskStats::LongTaskStats+484736
19: 00007FF7DBA27F1D std::__1::__vector_base<v8::CpuProfileDeoptFrame,std::__1::allocator<v8::CpuProfileDeoptFrame>>::__vector_base<v8::CpuProfileDeoptFrame,std::__1::allocator<v8::CpuProfileDeoptFrame> >+46541
20: 00007FF7DF3BD8A2 Cr_z_crc32+4115858
21: 00007FF96F727034 BaseThreadInitThunk+20
22: 00007FF96F8C2651 RtlUserThreadStart+33
Testcase Gist URL
No response
Additional Information
I have created a separate reproduction repo with N-API module and a small electron application: https://github.com/martinzak-zaber/electron-crash-repro
Preconditions
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
Basic Repro
The crash can only be observed in a child window that is opened using window.open function on the same domain and loads the same native module. The app crashes after a native module calls BlockingCall on ThreadSafeFunction created using child's Napi::Env. From all my understanding the native module is context-aware and works properly with Napi::Env. Sync calls do not seem to be affected.
Workaround
We have come up with two workarounds. The first is to set nativeWindowOpen to false. This is only possible on electron < 18. The second is to return deny in setWindowOpenHandler and still open the window manually using the provided URL. This works universally.
Notes
The crash does not occur if all the native work is done in preload script (as is perhaps for a lot of applications). The preload script is run only once in that scenario.
I am not 100% confident that this is a bug. I don't have a deep understanding of how v8 isolate and node_env should work in parent-child windows. Perhaps the native module is not correctly implemented.
You may wonder why we use nodeIntegration and contextIsolation.
It's because our application is strictly desktop and only loads local assets. Using our native node.js library directly makes our development rather convenient.
Thank you, the electron team, and all the contributors for maintaining the amazing ecosystem.
Any news on this @codebytere ? We are facing the same issue when using some native modules in native popup windows.
Disabling the native windows doesn't help with us. Running on Windows 10 with Electron 18.3.9 The crash we got is:
../../third_party/electron_node/src/api/callback.cc:68: Assertion `(Environment::GetCurrent(isolate)) == (env)' failed.
1: 00007FF78C0753E6 node::Buffer::New+50438
2: 00007FF78C075129 node::Buffer::New+49737
3: 00007FF78C017341 node::CallbackScope::CallbackScope+593
4: 00007FF78C01712D node::CallbackScope::CallbackScope+61
5: 00007FF78CC2D999 node::AsyncResource::CallbackScope::CallbackScope+89
6: 00007FF78C5DBBA9 node_api_get_module_file_name+1993
7: 00007FF78C71194F uv_signal_start_oneshot+1407
8: 00007FF78C08897C uv_run+492
9: 00007FF78A77F788 node::FreeArrayBufferAllocator+23624
10: 00007FF78DBA0E88 cppgc::internal::WriteBarrier::DijkstraMarkingBarrierRangeSlow+3156648
11: 00007FF78DC6A182 Cr_z_crc32+629202
12: 00007FF78C0A03E2 uv_sleep+79170
13: 00007FF78C0A9EEA uv_sleep+118858
14: 00007FF78BADCE15 uv_fs_get_result+6787749
15: 00007FF78BF4A482 IsSandboxedProcess+3878434
16: 00007FF78A87985C v8::metrics::LongTaskStats::LongTaskStats+496028
17: 00007FF78A87A33D v8::metrics::LongTaskStats::LongTaskStats+498813
18: 00007FF78A8768CC v8::metrics::LongTaskStats::LongTaskStats+483852
19: 00007FF78A876C40 v8::metrics::LongTaskStats::LongTaskStats+484736
20: 00007FF78A61832D std::__1::__vector_base<v8::CpuProfileDeoptFrame,std::__1::allocator<v8::CpuProfileDeoptFrame> >::__vector_base<v8::CpuProfileDeoptFrame,std::__1::allocator<v8::CpuProfileDeoptFrame> >+47581
21: 00007FF78DFBD122 Cr_z_crc32+4114802
22: 00007FFC1E2E7034 BaseThreadInitThunk+20
23: 00007FFC1E7A2651 RtlUserThreadStart+33
crash reason: Wappler process crashed.
Renderer process crashed - see https://www.electronjs.org/docs/tutorial/application-debugging for potential debugging information.
Disabling the native windows doesn't help with us. Running on Windows 10 with Electron 18.3.9
The nativeWindowOpen workaround only works for Electron < 18 (see description). The denying of the window open is what we currently use on Electron 18.
window.webContents.setWindowOpenHandler(details => {
// This is a hack that avoid windows sharing a JS context (see window.opener).
// We used to rely on nativeWindowOpen property that was removed from electron.
// We had made changes to support multiple contexts but some electron assertion fails.
// See https://github.com/electron/electron/issues/33868 .
this.createWindow({ url: details.url });
return ({ action: 'deny' });
});
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the latest version of Electron or in the beta—please include it with your comment!
bump. not stale.
It looks like this bug has been biting VSCode for some time now (Windows 7, 10 and Linux). My report is here https://github.com/microsoft/vscode/issues/130320#issuecomment-1207158020 and still seeing it with latest VSCode 1.75.0
1: 0000000140CDC8F6 node::Buffer::New+50054
2: 0000000140CDC639 node::Buffer::New+49353
3: 0000000140CBFE12 node::EmitAsyncDestroy+248898
4: 0000000141320707 uv_dlerror+646871
5: 00000001422C484E v8::EmbedderStateScope::~EmbedderStateScope+104286
6: 0000000142790C3C cppgc::internal::WriteBarrier::DijkstraMarkingBarrierRangeSlow+2094508
7: 00000000C00CEB32

I can confirm this is still happening in Electron 19. It also happens on MacOS.
I am running electron with golden layout and a native module that's supposedly context-aware.
Whenever a thread-safe function is called in a new window it crashes:
../../third_party/electron_node/src/api/callback.cc:74:node::InternalCallbackScope::InternalCallbackScope(node::Environment *, Local<v8::Object>, const node::async_context &, int): Assertion (Environment::GetCurrent(isolate)) == (env) failed.
I have this on my setup.ts
private _setupSecurityAndPermissions(): void {
this._mainWindow.webContents.setWindowOpenHandler(details => {
if (
!details.url.includes(this._customScheme) &&
!details.url.startsWith('http://localhost')
) {
return { action: 'deny' }
}
return {
action: 'allow',
overrideBrowserWindowOptions: {
frame: true,
parent: this._mainWindow,
alwaysOnTop: true,
minimizable: false,
webPreferences: {
contextIsolation: false,
sandbox: false,
nodeIntegration: true,
nodeIntegrationInWorker: true,
preload: Path.join(Electron.app.getAppPath(), 'build', 'src', 'preload.js')
}
}
}
})
Electron.session.defaultSession.setPermissionRequestHandler(
(webContents, permission, callback, details) => {
callback(true)
}
)
}
@gpetrov @ninjadev64 Were you able to fix this?
this seems to be related to the parent window passed on overrideBrowserWindowOptions @codebytere
When specified a crash occurs on MacOS, like:
When parent is omitted that no crash occurs.
I'm having a very similar issue with an iframe
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
nodeIntegrationInSubFrames: true,
},
the error I get is the same : electron_node\src\api\callback.cc:74: Assertion '(Environment::GetCurrent(isolate)) == (env)' failed.
is there a workaround?
I'm having a very similar issue with an iframe
webPreferences: { nodeIntegration: true, contextIsolation: false, nodeIntegrationInSubFrames: true, },the error I get is the same :
electron_node\src\api\callback.cc:74: Assertion '(Environment::GetCurrent(isolate)) == (env)' failed.is there a workaround?
Same issue for my app.
Hi @codebytere
- Is the below crash related to the same root cause?
- I got that crash when closing the child window that is created via
window.openand theoverrideBrowserWindowOptionshas these valuescontextIsolation: false and nodeIntegration: false,on electronv28.2.5and that Child window doesn't use any native modules!! - FYI the main browser window has this
webPreferences: {contextIsolation: false,nodeIntegration: false,sandbox: false,
C:\Windows\system32\cmd.exe [32400]: ..\..\third_party\electron_node\src\api\callback.cc:74: Assertion `(Environment::GetCurrent(isolate)) == (env)' failed.
1: 00007FF6BDB78506 node::SetTracingController+86134
2: 00007FF6BDB780DC node::SetTracingController+85068
3: 00007FF6BDBF6086 node::CallbackScope::CallbackScope+502
4: 00007FF6BDBF5ECD node::CallbackScope::CallbackScope+61
5: 00007FF6BEA7DBE4 node::AsyncResource::CallbackScope::CallbackScope+84
6: 00007FF6BE349CC4 node_api_get_module_file_name+3716
7: 00007FF6BDBFAE88 uv_run+792
8: 00007FF6BDBC741C node::loader::ModuleWrap::Initialize+164380
9: 00007FF6BDBC7D42 node::loader::ModuleWrap::Initialize+166722
10: 00007FF6BDBF340A node::FreeEnvironment+186
11: 00007FF6BBD2FE95 v8::Extension::auto_enable+981
12: 00007FF6BBD4FB29 v8::Extension::auto_enable+131177
13: 00007FF6BDA4572F uv_fs_get_system_error+1556319
14: 00007FF6BECDB607 uv_version_string+2480503
15: 00007FF6BE68A1AD uv_stream_set_blocking+3246445
16: 00007FF6BDFBA699 GetHandleVerifier+3731625
17: 00007FF6BDFDD80C GetHandleVerifier+3875356
18: 00007FF6BE039F9B GetHandleVerifier+4254123
19: 00007FF6BFD6180B cppgc::internal::WriteBarrier::DijkstraMarkingBarrierRangeSlow+4512667
20: 00007FF6BFE27757 Cr_z_adler32+623271
21: 00007FF6BFE2FD03 Cr_z_adler32+657491
22: 00007FF6BDC3A5A9 GetHandleVerifier+61369
23: 00007FF6BD55FC48 uv_os_getpid+181320
24: 00007FF6BDA312E0 uv_fs_get_system_error+1473296
25: 00007FF6BBE3D862 v8::internal::StrongRootAllocatorBase::StrongRootAllocatorBase+542194
26: 00007FF6BBE3E6D9 v8::internal::StrongRootAllocatorBase::StrongRootAllocatorBase+545897
27: 00007FF6BBE3A9E0 v8::internal::StrongRootAllocatorBase::StrongRootAllocatorBase+530288
28: 00007FF6BBE3AB5D v8::internal::StrongRootAllocatorBase::StrongRootAllocatorBase+530669
29: 00007FF6BBB7CBC5 std::__Cr::vector<v8::CpuProfileDeoptInfo,std::__Cr::allocator<v8::CpuProfileDeoptInfo> >::vector<v8::CpuProfileDeoptInfo,std::__Cr::allocator<v8::CpuProfileDeoptInfo> >+60933
30: 00007FF6C0218642 Cr_z_adler32+4755858
31: 00007FFFCB72257D BaseThreadInitThunk+29
32: 00007FFFCC6CAA58 RtlUserThreadStart+40