Skip to content

MSVC needs -D _HAS_EXCEPTIONS=1 for exceptions to work properly #85

Closed

Description

@mika-fischer

This should be added to the instructions in the README.

'conditions': [
    ['OS=="win"', { 'defines': [ '_HAS_EXCEPTIONS=1' ] }]
]

Activity

  1. jasongin commented on Jul 21, 2017

    @jasongin
    Member

    Why? Can you explain what problem you're seeing without that define? There are tests of the exception behavior that seem to work fine without it.

    As far as I know, _HAS_EXCEPTIONS=1 is the default for MSVC. Some projects may override it to 0. But in that case, they'd probably want 'NAPI_DISABLE_CPP_EXCEPTIONS instead.

  2. mika-fischer commented on Jul 21, 2017

    @mika-fischer
    Author

    Things work to some degree without it but there are subtle memory errors. I don't understand exactly what this flag causes but the effect is that objects are freed too early when handling an exception.

    For instance try this with _HAS_EXCEPTIONS=0 and _HAS_EXCEPTIONS=1:

    try
    {
        throw std::runtime_error(std::string("abc"));
    }
    catch (std::exception& e)
    {
        std::cout << "'" << e.what() << "'" << std::endl;
    }
    

    For me with MSVC 2015 this reliably prints '' with _HAS_EXCEPTIONS=0. But I've also encountered garbage memory in other cases. Needless to say this was a huge pain to debug and thus I think it should be much more prominently documented.

    The define comes from nodejs itself: https://github.com/nodejs/node/blob/master/common.gypi#L273

    See also nodejs/node-gyp#939 which led me to the solution.

  3. jasongin commented on Jul 21, 2017

    @jasongin
    Member

    Interesting. Thanks for the details. And I didn't realize node common.gypi set _HAS_EXCEPTIONS=0. I agree then it should be added to the README.

  4. NickNaso commented on Jan 31, 2020

    @NickNaso
    Member

    Hi @DBJDBJ,
    thanks for reporting the paper about performance on error handling. node-addon-api allow you to enable or disable the exception mechanism.
    It is documented on the following sections:

    If you enable the exceptions you will have a little overhead and it could be acceptable or not.

    I'm closing this because now the error handling for node-addon-api is documented like how it's possible to enable or disable the exception mechanism.

  5. DBJDBJ commented on Jan 31, 2020

    @DBJDBJ

    If you enable the exceptions you will have a little overhead and it could be acceptable or not

    Many thanks for the quick comment. I appreciate the answer.

    I might be so bold to think we (the native node.js community and customers) do require a bit more precise size and performance results than "you will have a little overhead..." ... has anyone (tasked by node team) measured the impact of exceptions recently? on the 3 key platforms with the 3 key compilers. I am trying to stay high level here. :)

  6. zbjornson commented on Sep 1, 2021

    @zbjornson

    @NickNaso This issue was closed but the documentation was never updated. Here's a simple example that doesn't catch correctly without "defines": ["_HAS_EXCEPTIONS=1"]:

    #include<new>
    
    Napi::Value test(const Napi::CallbackInfo& info) {
       Napi::Env env = info.Env();
       try {
          uint64_t* ptr = new uint64_t[0xFFFFFFFFFFFFUL];
          delete[] ptr;
       } catch(const std::bad_alloc& ba) {
          throw Napi::Error::New(env, ba.what());
       } catch(...) {
          throw Napi::Error::New(env, "This shouldn't be the one that catches");
       }
       return Napi::Number::New(env, 0);
    }
    
    Napi::Object Init(Napi::Env env, Napi::Object exports) {
    	exports.Set(Napi::String::New(env, "test"), Napi::Function::New(env, test));
    	return exports;
    }
    
    NODE_API_MODULE(xxx, Init)
  7. NickNaso commented on Sep 1, 2021

    @NickNaso
    Member

    Hi @zbjornson,
    sorry I made a mistake on closing the issue. Now i'm preparing a PR to solve the problem. Thanks for your feedback.

  8. DBJDBJ commented on Sep 2, 2021

    @DBJDBJ

    Ok here is what precisely happens if one compiles with -D_HAS_EXCEPTIONS=0, on Windows.

    _CPPUNWIND becomes 0. Keywords try,throw, catch cease to exist and WIN32 SEH aka "Structured Exceptions Handling" is being used everywhere like for example in MS STL.

    This is primarily the side effect of using cl.exe (MSVC compiler) with the /kernel switch, to create kernel-mode DLL's.

    May thanks ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions