Support for Electron 9
Environment
Tech stack:
- nan 2.14.0
- electron 9.1.2
- cmake-js 6.0.0
- cmake 3.17.0
Environment:
- Mac OS 10.15.5 (Reproduced on Windows 10 as well)
Premise
We're trying to update from Electron 5 to 9 and we have a native module that is causing issues. The module builds successfully with the following setup:
// Package.json
{
"scripts": {
"build": "cmake-js build -l verbose",
},
"cmake-js": {
"runtime": "electron",
"runtimeVersion": "9.1.2"
}
}
But when our Electron app launches it crashes after trying to access the native module with the following crash report:
Process: Electron [47212]
Path: /Users/USER/*/Electron.app/Contents/MacOS/Electron
Identifier: com.github.Electron
Version: 9.1.2 (9.1.2)
Code Type: X86-64 (Native)
Parent Process: ??? [47206]
Responsible: iTerm2 [80766]
User ID: 502
Date/Time: 2020-08-11 11:12:28.213 -0400
OS Version: Mac OS X 10.15.5 (19F101)
Report Version: 12
Bridge OS Version: 4.5 (17P5300)
...
Crashed Thread: 0 CrBrowserMain Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [47212]
Thread 0 Crashed:: CrBrowserMain Dispatch queue: com.apple.main-thread
0 license.node 0x0000000113c57a9f Nan::imp::FunctionCallbackWrapper(v8::FunctionCallbackInfo<v8::Value> const&) + 31
1 com.github.Electron.framework 0x00000001070a86df v8::internal::Accessors::MakeAccessor(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Name>, void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), void (*)(v8::Local<v8::Name>, v8::Local<v8::Value>, v8::PropertyCallbackInfo<v8::Boolean> const&)) + 16815
2 com.github.Electron.framework 0x00000001070a7c01 v8::internal::Accessors::MakeAccessor(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Name>, void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), void (*)(v8::Local<v8::Name>, v8::Local<v8::Value>, v8::PropertyCallbackInfo<v8::Boolean> const&)) + 14033
3 com.github.Electron.framework 0x00000001070a7292 v8::internal::Accessors::MakeAccessor(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Name>, void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), void (*)(v8::Local<v8::Name>, v8::Local<v8::Value>, v8::PropertyCallbackInfo<v8::Boolean> const&)) + 11618
4 com.github.Electron.framework 0x0000000107ada558 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 484152
...
After further testing we realized the nan's TravisCI config file only included Electron versions up to 8.2.3. After testing our app with this version everything ran flawlessly. So basically we're wondering what could cause this issue. Could anyone provide insight or perhaps confirm this is a nan issue?
Thanks
Stack trace on Windows is:
license.node!v8::internal::Internals::ReadRawField<unsigned short>(heap_object_ptr=577594250144183449, offset=12) Line 305
at C:\Users\danielo\.cmake-js\electron-x64\v9.1.2\include\node\v8-internal.h(305)
license.node!v8::internal::Internals::GetInstanceType(obj=1288625925157) Line 233
at C:\Users\danielo\.cmake-js\electron-x64\v9.1.2\include\node\v8-internal.h(233)
license.node!v8::Object::GetInternalField(index=1) Line 11339
at C:\Users\danielo\.cmake-js\electron-x64\v9.1.2\include\node\v8.h(11339)
license.node!Nan::imp::FunctionCallbackWrapper(info={...}) Line 171
at C:\Users\danielo\Unity\hub.native.license\node_modules\nan\nan_callbacks_12_inl.h(171)
electron.exe!v8::internal::FunctionCallbackArguments::Call(handler={...}) Line 159
at C:\projects\src\v8\src\api\api-arguments-inl.h(159)
electron.exe!v8::internal::`anonymous namespace'::HandleApiCallHelper<0>(isolate=0x0000012c00000000, function={...}, new_target, fun_data={...}, receiver={...}, args={...}) Line 113
at C:\projects\src\v8\src\builtins\builtins-api.cc(113)
electron.exe!v8::internal::Builtin_Impl_HandleApiCall(args, isolate=0x0000012c00000000) Line 145
at C:\projects\src\v8\src\builtins\builtins-api.cc(145)
electron.exe!v8::internal::Builtin_HandleApiCall(args_length=5, args_object=0x000000ea6f8fd7d0, isolate=0x0000012c00000000) Line 129
at C:\projects\src\v8\src\builtins\builtins-api.cc(129)
electron.exe!Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_ArgumentsAdaptorTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_ArgumentsAdaptorTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_ArgumentsAdaptorTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_ArgumentsAdaptorTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_ArgumentsAdaptorTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_InterpreterEntryTrampoline()
electron.exe!Builtins_JSEntryTrampoline()
electron.exe!Builtins_JSEntry()
[Inline Frame] electron.exe!v8::internal::GeneratedCode<unsigned long long,unsigned long long,unsigned long long,unsigned long long,unsigned long long,long long,unsigned long long **>::Call(args=1288627975469, args=1006894045136, args=1288490188800, args=1288625908265, args, args=0x00007ff7423d8700) Line 142
at C:\projects\src\v8\src\execution\simulator.h(142)
electron.exe!v8::internal::`anonymous namespace'::Invoke(isolate=0x0000012c0836752d, params) Line 367
at C:\projects\src\v8\src\execution\execution.cc(367)
electron.exe!v8::internal::Execution::Call(isolate=0x0000012c00000000, callable, receiver, argc=5, argv=0x000002dcba3a9320) Line 461
at C:\projects\src\v8\src\execution\execution.cc(461)
electron.exe!v8::Function::Call(context, recv={...}, argc=5, argv=0x000002dcba3a9320) Line 4994
at C:\projects\src\v8\src\api\api.cc(4994)
electron.exe!node::ExecuteBootstrapper(env=0x000002dcba3cd7d0, id, parameters, arguments=0x000000ea6f8ff080) Line 194
at C:\projects\src\third_party\electron_node\src\node.cc(194)
electron.exe!node::StartExecution(env=0x000002dcba3cd7d0, main_script_id=0x00007ff747374fe2) Line 387
at C:\projects\src\third_party\electron_node\src\node.cc(387)
[Inline Frame] electron.exe!std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char>>::__is_long() Line 1420
at C:\projects\src\buildtools\third_party\libc++\trunk\include\string(1420)
[Inline Frame] electron.exe!std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char>>::~basic_string() Line 2127
at C:\projects\src\buildtools\third_party\libc++\trunk\include\string(2127)
electron.exe!node::StartMainThreadExecution(env=0x000002dcba3cd7d0) Line 442
at C:\projects\src\third_party\electron_node\src\node.cc(442)
electron.exe!node::LoadEnvironment(env) Line 450
at C:\projects\src\third_party\electron_node\src\node.cc(450)
electron.exe!electron::NodeBindings::LoadEnvironment(env=0x000002dcba3cd7d0) Line 380
at C:\projects\src\electron\shell\common\node_bindings.cc(380)
electron.exe!electron::ElectronBrowserMainParts::PostEarlyInitialization() Line 343
at C:\projects\src\electron\shell\browser\electron_browser_main_parts.cc(343)
electron.exe!content::BrowserMainLoop::EarlyInitialization() Line 709
at C:\projects\src\content\browser\browser_main_loop.cc(709)
electron.exe!content::BrowserMainRunnerImpl::Initialize(parameters={...}) Line 108
at C:\projects\src\content\browser\browser_main_runner_impl.cc(108)
electron.exe!content::BrowserMain(parameters={...}) Line 43
at C:\projects\src\content\browser\browser_main.cc(43)
electron.exe!content::RunBrowserProcessMain(main_function_params={...}, delegate) Line 530
at C:\projects\src\content\app\content_main_runner_impl.cc(530)
electron.exe!content::ContentMainRunnerImpl::RunServiceManager(main_params={...}, start_service_manager_only=false) Line 980
at C:\projects\src\content\app\content_main_runner_impl.cc(980)
electron.exe!content::ContentMainRunnerImpl::Run(start_service_manager_only=false) Line 883
at C:\projects\src\content\app\content_main_runner_impl.cc(883)
electron.exe!service_manager::Main(params) Line 454
at C:\projects\src\services\service_manager\embedder\main.cc(454)
electron.exe!content::ContentMain(params) Line 19
at C:\projects\src\content\app\content_main.cc(19)
electron.exe!wWinMain(instance, , cmd, ) Line 210
at C:\projects\src\electron\shell\app\electron_main.cc(210)
[Inline Frame] electron.exe!invoke_main() Line 118
at d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(118)
electron.exe!__scrt_common_main_seh() Line 288
at d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288)
kernel32.dll!00007ffd0e9b6fd4()
ntdll.dll!00007ffd0f37cec1()
Symbols downloaded from here, otherwise we would only see the 1st four frames...
I ran into this same problem with my application. This needs to be fixed, but there is a workaround (not ideal) for Windows currently: Disable inline functions with /Od or /Ob0 - Reference: https://docs.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion?view=vs-2019
I have not had success with disabling similar stuff on macOS such as -O0 or -fno-inline-functions...so we really need a proper fix for these bad memory offsets that appear to be occurring with Electron 9.
I just spent some time testing different electron versions, and it does appear that this problem is not present on electron 8.5.0, but is still present on electron 10.
Also not 100% sure if this is a nan problem, or a core v8/chromium/electron problem.
I found this ticket: https://github.com/wilix-team/iohook/issues/241 which reports the same problem. Sounds like some compiler flag in cmake is causing it to crash (probably still due to bad code).
So just a followup here, I have migrated a sample project & my actual project from nan -> node-addon-api and now I am no longer facing these issues above. It seems that there is some conflict between nan and electron v9+...but I'm not sure nan is going to be getting long term support anymore.
I think the general idea is people should be moving off of nan and move towards node-addon-api...since this software is no longer receiving frequent updates.