ARTICLE AD BOX
I am working on an Electron project with node-api (for C++ addons). The app crashes, even after a full-build. The problem that I am facing occurs within the C++ template addon that I have made.
I have added extensive logging in order to figure out where the error occurs, and narrowed it down to the helloFunc = Napi::Function::New(env, HelloWorld); call within [addon.cpp] (because the "Creating helloFunc..." log appears in the terminal, but the "Created helloFunc." log doesn't).
However, the try/catch blocks that I added around this line aren't logging anything, so I assume some memory access error is occuring at the OS-level, and the Napi::Object Init function is abruptly ending at the relevant line, so all later lines containing the std::cout logs aren't running.
In regards to this, my question is: Why is the line `Napi::Function::New(env, HelloWorld)` even causing a memory access error?
Any answer that explains either (a) the detailed debugging steps for my case or (b) the origin of the error within the code suffices. I don't need both points to be delved into. The replier can decide which one he finds more useful to me - I myself just don't know, and I don't want to choose the wrong answer format and leave with useless information.
In a previous iteration of this question, it was suggested to me that I "use a debugger" to figure out what is going wrong. In regards to this suggestion, I must say: That's exactly what I tried to do using C++ logs! But since the error seems to not be handled by the C++, doing so tells me nothing about the error. And I have no clue how to debug at a lower level in this scenario, which ties into my question.
All relevant files in my project are below:
[addon.cpp]
#include <napi.h> #include <iostream> Napi::String HelloWorld(const Napi::CallbackInfo& info) { std::cout << "[C++] " << "Getting environment..." << std::endl; // Is not run Napi::Env env = info.Env(); std::string helloWorld = "Hello from C++!"; return Napi::String::New(env, helloWorld); } Napi::Object Init(Napi::Env env, Napi::Object exports) { Napi::Function helloFunc; try { std::cout << "[C++] " << "Creating helloFunc..." << std::endl; helloFunc = Napi::Function::New(env, HelloWorld); std::cout << "[C++] " << "Created helloFunc." << std::endl; } catch (...) { } exports.Set("hello", helloFunc); return exports; } NODE_API_MODULE(addon, Init)[CMakeLists.txt]
cmake_minimum_required(VERSION 3.15) project(my_native_addon) execute_process( COMMAND node -p "require('path').dirname(require.resolve('node-addon-api'))" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE NODE_ADDON_API_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) include_directories(${NODE_ADDON_API_DIR}) include_directories(${CMAKE_JS_INC}) # Enable C++ exceptions for node-addon-api add_definitions(-DNAPI_CPP_EXCEPTIONS) # Enable C++ exception handling if(MSVC) add_compile_options(/EHsc) else() add_compile_options(-fexceptions) endif() # Set source files set(CMAKE_JS_SRC "native/addon.cpp") # Build the library add_library(${PROJECT_NAME} SHARED ${CMAKE_JS_SRC}) set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node") target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})[package.json]
{ "scripts": { "ng": "ng", "build": "ng build", "build-native": "cmake-js rebuild --runtime=electron --runtime-version=40.6.1", "build-angular": "ng build --base-href ./", "start-electron": "electron electron/main.js", "full-build": "npm run build-native && npm run build-angular && npm run start-electron" }, "packageManager": "[email protected]", "dependencies": { "node-addon-api": "^8.5.0", }, "devDependencies": { "@electron/rebuild": "^4.0.3", "cmake-js": "^8.0.0", "electron": "40.6.1", "electron-builder": "^26.8.1", } }[main.js]
const { app, BrowserWindow, ipcMain } = require('electron'); const path = require('path'); console.log("Starting Electron App..."); let addon; const addonPath = path.join(__dirname, '../build/Release/my_native_addon.node'); addon = require(addonPath); console.log("Native addon loaded successfully!"); try { app.whenReady().then(() => { ipcMain.handle('get-hello-message', () => { if (addon) { return addon.hello(); } return "Addon not loaded"; }); }) } catch (err) { console.error("Failed to start Electron app:", err); }