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

Enabling C++ exceptions on Windows is hell #2903

Open
mmomtchev opened this issue Sep 14, 2023 · 3 comments
Open

Enabling C++ exceptions on Windows is hell #2903

mmomtchev opened this issue Sep 14, 2023 · 3 comments
Labels

Comments

@mmomtchev
Copy link

mmomtchev commented Sep 14, 2023

  • 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.

@mmomtchev
Copy link
Author

Definitely related to one of the members of the structure being #pragma packed. Still, it would be nice if this define didn't get included unless exceptions are actually disabled.

@erikjalevik
Copy link

I had a similar problem on Mac, where when moving the flags enabling exceptions up to the target_defaults section, they were not respected. Despite "cflags!": [ "-fno-exceptions" ], "cflags_cc!": [ "-fno-exceptions" ] in my binding.gyp file, the compiler was being invoked with -fno-exceptions.

Including except.gypi fixes it, however that file includes a spurious 'MACOSX_DEPLOYMENT_TARGET': '10.7', which is incorrect for my build. I tried overriding this in the target_defaults but no cigar, it has to be overridden on the target level. Which is slightly annoying as I have several targets.

@mmomtchev

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants