uNetworking / uWebSockets.js

μWebSockets for Node.js back-ends :metal:
Apache License 2.0
7.85k stars 570 forks source link

segfault: ws.send( SharedArrayBuffer ) #495

Closed tcf909 closed 3 years ago

tcf909 commented 3 years ago

Hello,

When trying to pass a raw SharedArrayBuffer to ws.send() I get a segfault. I see the API doesn't support this exact class. To work around the issue I wrap the SharedArrayBuffer using new Uint8Array().

I'm not sure what the exact ramifications are in the C code with regard to accepting a SharedArrayBuffer (directly or in disguise). Hoping you can clarify the API and either accept the raw SharedArrayBuffer (like you do the ArrayBuffer), or if this could lead to some really bad issues in the C code, don't accept a typed array backed by a SharedArrayBuffer at all.

I also noticed the segfault error message doesn't convey the issue. I saw you spent some time updating error messages and type checking at some point. Thought this issue would help on that front as well.

Either way, clarification would be appreciated.

Thanks again for the awesome work!

uv loop at [0x7000061d7af8] has open handles:
[0x105546560] poll (active)
    Close callback: 0x7000ffffffff 
    Data: 0x0 
[0x1053d0550] poll (active)
    Close callback: 0x654d646576696501 
    Data: 0x0 
uv loop at [0x7000061d7af8] has 2 open handles in total
/Users/tc.ferguson/.nvm/versions/node/v14.16.0/bin/node[69056]: ../src/debug_utils.cc:322:void node::CheckedUvLoopClose(uv_loop_t *): Assertion `0 && "uv_loop_close() while having open handles"' failed.
 1: 0x1012e4da5 node::Abort() (.cold.1) [/Users/tc.ferguson/.nvm/versions/node/v14.16.0/bin/node]
 2: 0x1000a6239 node::Abort() [/Users/tc.ferguson/.nvm/versions/node/v14.16.0/bin/node]
 3: 0x1000a60a1 node::Assert(node::AssertionInfo const&) [/Users/tc.ferguson/.nvm/versions/node/v14.16.0/bin/node]
 4: 0x100030e8e node::CheckedUvLoopClose(uv_loop_s*) [/Users/tc.ferguson/.nvm/versions/node/v14.16.0/bin/node]
 5: 0x1001459f6 node::worker::WorkerThreadData::~WorkerThreadData() [/Users/tc.ferguson/.nvm/versions/node/v14.16.0/bin/node]
 6: 0x100142351 node::worker::Worker::Run() [/Users/tc.ferguson/.nvm/versions/node/v14.16.0/bin/node]
 7: 0x100145b7f node::worker::Worker::StartThread(v8::FunctionCallbackInfo<v8::Value> const&)::$_3::__invoke(void*) [/Users/tc.ferguson/.nvm/versions/node/v14.16.0/bin/node]
 8: 0x7fff2037c950 _pthread_start [/usr/lib/system/libsystem_pthread.dylib]
 9: 0x7fff2037847b thread_start [/usr/lib/system/libsystem_pthread.dylib]

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
ghost commented 3 years ago

This is not a segfault it is an assertion failure in libuv. That's a huge difference.

uWS.App().listen(new SharedArrayBuffer(1024), () => {}) Uncaught 'Text and data can only be passed by String, ArrayBuffer or TypedArray.'

It works like it should, you are simply not handling exceptions properly

hst-m commented 3 years ago

I was going to mention this earlier but the open handles error in this issue is caused by the same thing as this other issue https://github.com/uNetworking/uWebSockets.js/issues/465 where an uncaught JS error causes the worker thread to exit, and uWS still has uv loop handlers open. But the underlying JS error Text and data can only be passed by String, ArrayBuffer or TypedArray looks like can be fixed by updating this uWS.js file Utilities.h and add this type check: isSharedArrayBuffer(value)

tcf909 commented 3 years ago

Perfect. I really appreciate the guidance. It is exactly what I needed.