Description
Problem description
I kept getting SIGABRT every like 100 times I closed my Electron app. I was able to narrow this down to the @grpc/grpc-js package. It happens when a worker thread is terminated just before a @grpc/grpc-js server tries to read on the stream.
It is potentially caused by the underlying http/2 module. But with just http/2 it'll result in a "FATAL ERROR:" (nodejs/node#38418 (comment)), which might be completely unrelated or maybe it masks the SIGABRT. Or the SIGABRT is caused by how @grpc/grpc-js is using http/2 (e.g. where did onread
go?) and not related to http/2 itself at all.
STREAM 22227: ondata
heartbeat request 1652
STREAM 22227: dest.write true
STREAM 22227: maybeReadMore read 0
STREAM 22227: read 0
STREAM 22227: need readable true
STREAM 22227: length less than watermark true
STREAM 22227: do read
TIMER 22227: process timer lists 4637
TIMER 22227: timeout callback 2000
WORKER 22227: [0] terminates Worker with ID 1
node[22227]: ../src/stream_base.cc:351:v8::MaybeLocal<v8::Value> node::StreamBase::CallJSOnreadMethod(ssize_t, v8::Local<v8::ArrayBuffer>, size_t, node::StreamBase::StreamBaseJSChecks): Assertion `onread->IsFunction()' failed.
TIMER 22227: 2000 list empty
1: 0xa222f0 node::Abort() [node]
2: 0xa2236e [node]
3: 0xaedd0a [node]
4: 0xa4380e node::http2::Http2StreamListener::OnStreamRead(long, uv_buf_t const&) [node]
5: 0xa4f66c node::http2::Http2Session::OnDataChunkReceived(nghttp2_session*, unsigned char, int, unsigned char const*, unsigned long, void*) [node]
6: 0x18a3d0d nghttp2_session_mem_recv [node]
7: 0xa4eb09 node::http2::Http2Session::ConsumeHTTP2Data() [node]
8: 0xa4ee5e node::http2::Http2Session::OnStreamRead(long, uv_buf_t const&) [node]
9: 0xafa168 node::LibuvStreamWrap::OnUvRead(long, uv_buf_t const*) [node]
10: 0x13a8bf7 [node]
11: 0x13a95b0 [node]
12: 0x13b0095 [node]
13: 0x139dc38 uv_run [node]
14: 0xada493 node::worker::Worker::Run() [node]
15: 0xadaf18 [node]
16: 0x7fa0cf30f609 [/lib/x86_64-linux-gnu/libpthread.so.0]
17: 0x7fa0cf236293 clone [/lib/x86_64-linux-gnu/libc.so.6]
Aborted (core dumped)
Reproduction steps
Repo is here https://github.com/Prinzhorn/electron-sigabrt
Please note that it does no longer require Electron at all (as the name suggests), it was stripped down.
Also HEAD does not use @grpc/grpc-js (because I stripped it away and uncovered the bug in http/2 module), you need to check out commit 45caa541d9d16bbeb1b7a9e31ebbd59e61381b7d
What the repo does is start a grpc server inside a worker thread and then bombard it with requests. The worker is terminated after 2s and this will reliable cause the whole process to SIGABRT if it happens at the right time.
git clone [email protected]:Prinzhorn/electron-sigabrt.git
cd electron-sigabrt/
git checkout 45caa541d9d16bbeb1b7a9e31ebbd59e61381b7d
npm i
# In two terminals (server will terminate after 2s automatically)
npm run server
npm run client
vokoscreen-2021-05-25_18-21-37.mp4
Environment
- OS name, version and architecture: Linux alex-desktop 5.8.0-53-generic Upgrade npm versions for every version of node in test scripts #60~20.04.1-Ubuntu SMP Thu May 6 09:52:46 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
- Node version v14.17.0 and v16.2.0
- Node installation method [e.g. nvm] nvm
- Package name and version [e.g. [email protected]] @grpc/grpc-js 1.3.2 (the repo's package.json still points to 1.3.0, it repros with 1.3.2 as well you can update the package.json)