C++ C+中Node.js/Nan回调上的不常见Segfault+;插件

C++ C+中Node.js/Nan回调上的不常见Segfault+;插件,c++,node.js,segmentation-fault,libuv,node.js-nan,C++,Node.js,Segmentation Fault,Libuv,Node.js Nan,我正在使用Nan库制作一个NodeJS插件,我遇到了一个问题,调用回调(在javascript端创建并传递给插件以异步执行)将导致segfault,但大约每10000次运行一次 每件事的运作方式都有相当多的复杂性,但我希望有人能看到我错过的东西,或者能够弄清楚发生了什么 C++回调函数是由JavaScript回调创建的: auto nodeFunc = val.As<v8::Function>(); auto nodeCb = std::make_shared<

我正在使用Nan库制作一个NodeJS插件,我遇到了一个问题,调用回调(在javascript端创建并传递给插件以异步执行)将导致segfault,但大约每10000次运行一次

每件事的运作方式都有相当多的复杂性,但我希望有人能看到我错过的东西,或者能够弄清楚发生了什么

C++回调函数是由JavaScript回调创建的:

   auto nodeFunc = val.As<v8::Function>();
   auto nodeCb   = std::make_shared<Nan::Callback>(nodeFunc);

   auto callback = [nodeCb] (std::string err, std::string val) -> void {
        Nan::HandleScope     scope;
        v8::Local<v8::Value> argv[2];

       if (err.length() == 0) {
            auto isolate = v8::Isolate::GetCurrent();
            auto json    = v8::JSON::Parse(isolate, Nan::New(val).ToLocalChecked());
            auto object  = json.ToLocalChecked();
            argv[0] = Nan::Null();
            argv[1] = object;
        } else {
            argv[0] = Nan::Error(err.c_str());
            argv[1] = Nan::Null();
        }

        try {
            nodeCb->Call(2, argv);
        } catch (std::exception& ex) {
            std::cout << ex.what() << std::endl;
            Nan::ThrowReferenceError(ex.what());
        }
    };
编辑:我已经创建了一个小得多的测试程序,看看是否可以找出bug的来源,我发现我可以通过将回调共享指针更改为常规指针来防止它,在
nodebc->Call(2,argv)
行之后立即删除它


这两者之间是否存在语义差异,可能导致这种情况?

使用
shared\u ptr
包装回调是可疑的:

std::make_shared<Nan::Callback>(nodeFunc);
std::使_共享(nodeFunc);
我认为
V8
不希望引用以这种方式处理

Nan::Callback
本身包含一个用于存储函数值的持久性,因此您不必担心持久性

…在我写完这个答案后,我才注意到你的编辑。
shared_ptr
V8
内部句柄和引用混合使用有潜在危险

如果您打算存储回调并立即删除它,那么重构代码以供使用可能会对您有所帮助

std::make_shared<Nan::Callback>(nodeFunc);