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

Panicking in a Channel::send closure crashes Node #845

Closed
kjvalencik opened this issue Jan 19, 2022 · 1 comment
Closed

Panicking in a Channel::send closure crashes Node #845

kjvalencik opened this issue Jan 19, 2022 · 1 comment

Comments

@kjvalencik
Copy link
Member

Repro

use neon::prelude::*;

#[neon::main]
fn main(mut cx: ModuleContext) -> NeonResult<()> {
    cx.export_function("crash", |mut cx| {
        cx.channel().send::<(), _>(|_| panic!("Oh, no!"));
        Ok(cx.undefined())
    })
}
require(".").crash();

Expected

As of Neon 0.10, panicking in a Channel::send closure will trigger in an uncaughtException.

Actual

The process crashes with a C++ error.

> thread '<unnamed>' panicked at 'Oh, no!', test/futures/src/lib.rs:64:40
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Uncaught:
[Error: A panic occurred while executing a `neon::event::Channel::send` callback] {
  panic: [Error: Oh, no!]
}
> node[25182]: ../src/node_util.cc:242:static void node::util::WeakReference::DecRef(const FunctionCallbackInfo<v8::Value> &): Assertion `(weak_ref->reference_count_) >= (1)' failed.
 1: 0x106604815 node::Abort() (.cold.1) [../node/16.13.2/bin/node]
 2: 0x105303b09 node::Abort() [../node/16.13.2/bin/node]
 3: 0x105303941 node::Assert(node::AssertionInfo const&) [../node/16.13.2/bin/node]
 4: 0x105399dc6 node::util::WeakReference::DecRef(v8::FunctionCallbackInfo<v8::Value> const&) [../node/16.13.2/bin/node]
 5: 0x1054ed4a9 v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo) [../node/16.13.2/bin/node]
 6: 0x1054ecf76 v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) [../node/16.13.2/bin/node]
 7: 0x1054ec6ef v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [../node/16.13.2/bin/node]
 8: 0x105d5d5f9 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit [../node/16.13.2/bin/node]

Explanation

There is a bug in Node that crashes the process when attempting to trigger an uncaughtException with napi_fatal_exception from the context of an error domain.

Since Node-API implicitly wraps napi_threadsafe_function callbacks in an error domain and threadsafe functions are the backing provider of Channel::send, panicking in a neon::event::Channel::send callback crashes the process on all current versions of Node.

Possible Mitigations

  • Disable uncaughtException triggering which trades a crash for a silent error
  • Try to trigger the exception from outside an error domain. Possibly with setImmediate?
  • Wait for a fix from Node
@kjvalencik
Copy link
Member Author

Fixed.

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

No branches or pull requests

1 participant