node-gyp icon indicating copy to clipboard operation
node-gyp copied to clipboard

Enabling C++ exceptions on Windows is hell

Open mmomtchev opened this issue 2 years ago • 3 comments

  • 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 avatar Sep 14 '23 14:09 mmomtchev

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.

mmomtchev avatar Sep 15 '23 13:09 mmomtchev

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.

erikjalevik avatar Sep 28 '23 06:09 erikjalevik

In case you haven't already read my profile, I am currently living in total isolation since I am being extorted by the French police and the French judiciary about a series of falsified criminal proceedings including false rape charges and sexual harassment. They are trying to cover up those affairs because they are linked to the personal problem of the man who is behind that affair and the fact that these have been organized with corruption of judicial officials. The French police came yesterday evening, without any official order and drew their guns in an attempt to further intimidate me. In order to show me that I have to shut up about that affair, people are simultaneously posting issues on my projects. The last series have been going for three days and every time I ask this question, I am getting two more - every time separated by more and more time - but still to be obvious. Yours is one of these. You don't happen to know anything?

mmomtchev avatar Sep 28 '23 17:09 mmomtchev