nodejs / nodejs/node-gyp

Enabling C++ exceptions on Windows is hell

Open
#2,903 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Windows
Dominant language
Python
Stars
10.7k
Forks
1.9k
Avg merge
1d 4h
Merged PRs (30d)
5

Description

  • Node Version: v18.13.0
  • Platform: Windows
  • Compiler: MSVC 2022
  • Module: node-magickwand

By default, node-gyp builds without C++ and stack unwinding on all platforms. However as node-addon-api includes excellent C++ exception support, many users tend to rely on it. Currently, when it comes to MSVC, it is very easy to produce a terrible disaster. node-gyp includes a _HAS_EXCEPTIONS=0 macro. There are parts of the MSVC C++ runtime that when built with _HAS_EXCEPTIONS=0 produce std::exception objects with different sizeof compared to when building with _HAS_EXCEPTIONS=1. ImageMagick in particular makes use of the #pragma pack directive - which might be a necessary condition (I haven't been able to reproduce the problem without it - but it might be possible). This means that binaries built this way will be mostly working with some very subtle and rather hard to find memory alignment problems that require lots of hair-pulling to sort out.

It seems that the authors of node-addon-api have recognized this problem because they include the file node_modules\node-addon-api\except.gypi which contains the exact required options needed to produce a correct binary. That file is not documented anywhere and I will create shortly another issue there. Including this file in the target_defaults section is currently the only way to produce a correct binary. If one decides to simply add himself:

"defines": [
  "_HAS_EXCEPTIONS=1"
]

node-gyp will silently win and it will place its own _HAS_EXCEPTIONS=0 afterwards on the command-line. By including the file both macros remain there too, but in the correct order.

Needlessly to say, this is a very fragile and rather vicious system. Ideally, what is needed is an official switch to enable exceptions that works on all platforms. Or at least something less prone to horrible errors.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with node-gyp's target_defaults handling and compare it with node_modules\node-addon-api\except.gypi, especially the ordering of _HAS_EXCEPTIONS=0 and _HAS_EXCEPTIONS=1. Add an official exception-enabling switch that works across platforms and avoids conflicting compiler definitions; verify the behavior with Windows and MSVC builds.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, node.js, python
Domain
build-system, devtools, operating-systems
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.