Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Possible crash: `Nan::ThrowError` called from `ClientWorker::Execute()`, which runs on the libuv threadpool

オープン 初心者向け
#62 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
79/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
cpp, node.js

調査の方向性

src/linux/BTSerialPortBindingServer.ccと、src/BTSerialPortBindingServer.hにあるClientWorkerの宣言を読みます。issueではExecute()と安全でない例外呼び出しが特定されています。Execute()から設定されたエラーをNANがどのように処理するかを確認し、示されているように呼び出しをSetErrorMessage()に置き換えます。エラーがコールバックに届き、Bluetoothハードウェアがなくてもプロセスが動作し続けることを確認します。

索引モデルが issue の本文から書いたものです。

説明

Nan::ThrowError called from ClientWorker::Execute(), which runs on the libuv threadpool

BTSerialPortBindingServer::ClientWorker is a Nan::AsyncWorker, so its
Execute() override runs on a libuv threadpool thread rather than the thread
that owns the V8 isolate. It raises a JavaScript exception from there:

// src/linux/BTSerialPortBindingServer.cc
void BTSerialPortBindingServer::ClientWorker::Execute(){
    if(mBaton == nullptr){
        return Nan::ThrowError("listen_baton_t is null!");
    }

Nan::ThrowError reaches v8::Isolate::ThrowException, which may only be
called on the isolate's own thread. The declaration confirms the context:

// src/BTSerialPortBindingServer.h
class ClientWorker : public Nan::AsyncWorker {
    void Execute() override;
    void HandleOKCallback() override;
};

Reproduction

The behaviour does not depend on Bluetooth hardware; it follows from raising a
V8 exception inside Execute(). A minimal addon with the same shape:

class ThrowingWorker : public Nan::AsyncWorker {
 public:
  explicit ThrowingWorker(Nan::Callback *cb) : Nan::AsyncWorker(cb) {}
  void Execute() override {
    return Nan::ThrowError("raised from the worker thread");
  }
  void HandleOKCallback() override {
    Nan::HandleScope scope;
    v8::Local<v8::Value> argv[] = { Nan::Null() };
    callback->Call(1, argv, async_resource);
  }
};
const addon = require('./build/Release/poc.node');
process.on('uncaughtException', e => console.log('[uncaughtException]', e && e.message));
addon.run(() => console.log('[callback] ran'));
setTimeout(() => console.log('[alive] process survived'), 1000);

Node v22.17.1, macOS arm64, nan 2.x:

worker body exit code output
Nan::ThrowError(...) 139 (SIGSEGV), 5/5 runs none; the callback never runs
SetErrorMessage(...) 0, 3/3 runs [callback] err = raised from the worker thread, [alive] process survived

Suggested fix

NAN provides SetErrorMessage() for exactly this: record the message in
Execute() and let NAN deliver it on the loop thread through
HandleErrorCallback().

 void BTSerialPortBindingServer::ClientWorker::Execute(){
     if(mBaton == nullptr){
-        return Nan::ThrowError("listen_baton_t is null!");
+        return SetErrorMessage("listen_baton_t is null!");
     }

The existing HandleOKCallback() stays as it is; NAN calls
HandleErrorCallback() instead when an error message has been set, and the
default implementation passes the message to the stored callback as an Error.

主要言語
C++
スター
205
フォーク
56
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

lsongdev/node-bluetooth のほかの issue

lsongdev/node-bluetooth の issue をすべて見る

似ている issue

C++ の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。