-
Notifications
You must be signed in to change notification settings - Fork 459
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
src: fix a crashing issue in Error::ThrowAsJavaScriptException via NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS #975
Conversation
When terminating an environment (e.g., by calling worker.terminate), napi_throw, which is called by Error::ThrowAsJavaScriptException, returns napi_pending_exception, which is then incorrectly treated as a fatal error resulting in a crash.
Introduce the compile option `NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS` to dictate fix for crashing behavior.
napi-inl.h
Outdated
if (status == napi_pending_exception) { | ||
// The environment could be terminating. | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this block should be added here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
common.gypi
Outdated
@@ -15,6 +15,7 @@ | |||
} | |||
}] | |||
], | |||
'defines': [ 'NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS' ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be here by default right ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @mhdawson ,
So this relates to my comment on #902 (comment) where:
Not having the define in binding.gyp and using #define prior to #include <napi.h>: I was not able to opt-in.
You can see in commit a089697 the change to move the setting from binding.gyp
to #define
and now all of the builds fail.
I do not think it is possible to have a per-compilation unit setting for this feature, because the Error::ThrowAsJavaScriptException
is a compiled, exported symbol:
➜ test git:(swallow-unthrowable-exceptions) ✗ nm -C build/Release/binding_noexcept.node | grep ThrowAsJavaScriptException
00000000000024f0 t Napi::Error::ThrowAsJavaScriptException() const
So, when the first compilation unit uses it, it will be compiled with whatever preprocessor definitions are currently in scope.
cd7d47d
to
3ca4de5
Compare
- Move define to src - Correct fix implementation
3ca4de5
to
a089697
Compare
7ce3576
to
3f291f7
Compare
Hi @mhdawson and team. This PR is ready for review. As discussed in last week's meeting, the last commit contains (1) the implementation change and (2) creation of new test target. Just struggling with the CI. |
@legendecas I believe you are working on build system changes. Since this introduces new target, will possibly need to collaborate between the two PRs. |
@KevinEady, if the build changes were to refactor the testing so that it is easier to add a new config that we run the tests under, unless I'm remembering wrong, I think I already landed that. |
Hi @mhdawson , no the build changes were to create a new target that only compiles the single file with the |
@KevinEady got it. |
@KevinEady I'm wondering if this is still waiting on the other PR mentioned or if its ready to go? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'll just hold off landing this until the 4.0 release goes out. |
Actually thinking about it, I don't see the harm of it being in 4.x so landing now. |
When terminating an environment (e.g., by calling worker.terminate), napi_throw, which is called by Error::ThrowAsJavaScriptException, returns napi_pending_exception, which is then incorrectly treated as a fatal error resulting in a crash. PR-URL: #975 Reviewed-By: Nicola Del Gobbo <[email protected]> Reviewed-By: Gabriel Schulhof <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
Landed as 028107f |
@KevinEady I've landed but I am wondering about testing with the additional define. Should I see additional output when I run npm test or is that all hidden behind the scenes and I should only see one line for each test? |
Hi @mhdawson , There are two additional build targets (1, 2) and one test (1) that runs everything in the background via a separate node process: node-addon-api/test/error_terminating_environment.js Lines 47 to 64 in 3f291f7
|
@KevinEady re: I am wondering though if there is any real-world code that we can see if this fix actually solves the problem It was in one of my unreleased hobby projects in which I ran into this issue. It uses Node.js as an embedded library to provide scripting support for the end-user. As the scripts must be terminable (mainly for the same reasons as in web browsers), everything around them must be capable of handling it without crashing. I'm glad that this is now possible when using node-addon-api. I'm worried, though, that the opt-in nature of this fix will mean that most addons will needlessly keep crashing in the future as well. while (true) {
console.log(`I hope you're not planning on terminating me. :)`)
do_something_with_addon_a_fix_enabled()
do_something_with_addon_b_fix_disabled()
do_something_with_addon_c_fix_disabled()
do_something_with_addon_d_fix_disabled()
} |
When terminating an environment (e.g., by calling worker.terminate), napi_throw, which is called by Error::ThrowAsJavaScriptException, returns napi_pending_exception, which is then incorrectly treated as a fatal error resulting in a crash. PR-URL: nodejs#975 Reviewed-By: Nicola Del Gobbo <[email protected]> Reviewed-By: Gabriel Schulhof <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
When terminating an environment (e.g., by calling worker.terminate), napi_throw, which is called by Error::ThrowAsJavaScriptException, returns napi_pending_exception, which is then incorrectly treated as a fatal error resulting in a crash. PR-URL: nodejs#975 Reviewed-By: Nicola Del Gobbo <[email protected]> Reviewed-By: Gabriel Schulhof <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
When terminating an environment (e.g., by calling worker.terminate), napi_throw, which is called by Error::ThrowAsJavaScriptException, returns napi_pending_exception, which is then incorrectly treated as a fatal error resulting in a crash. PR-URL: nodejs/node-addon-api#975 Reviewed-By: Nicola Del Gobbo <[email protected]> Reviewed-By: Gabriel Schulhof <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
When terminating an environment (e.g., by calling worker.terminate), napi_throw, which is called by Error::ThrowAsJavaScriptException, returns napi_pending_exception, which is then incorrectly treated as a fatal error resulting in a crash. PR-URL: nodejs/node-addon-api#975 Reviewed-By: Nicola Del Gobbo <[email protected]> Reviewed-By: Gabriel Schulhof <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
When terminating an environment (e.g., by calling worker.terminate), napi_throw, which is called by Error::ThrowAsJavaScriptException, returns napi_pending_exception, which is then incorrectly treated as a fatal error resulting in a crash. PR-URL: nodejs/node-addon-api#975 Reviewed-By: Nicola Del Gobbo <[email protected]> Reviewed-By: Gabriel Schulhof <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
When terminating an environment (e.g., by calling worker.terminate), napi_throw, which is called by Error::ThrowAsJavaScriptException, returns napi_pending_exception, which is then incorrectly treated as a fatal error resulting in a crash. PR-URL: nodejs/node-addon-api#975 Reviewed-By: Nicola Del Gobbo <[email protected]> Reviewed-By: Gabriel Schulhof <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
When terminating an environment (e.g., by calling worker.terminate), napi_throw, which is called by Error::ThrowAsJavaScriptException, returns napi_pending_exception, which is then incorrectly treated as a fatal error resulting in a crash. In order to not terminate the Node process, define the preprocessor directive
NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS
.