C++ C+中Node.js/Nan回调上的不常见Segfault+;插件
我正在使用Nan库制作一个NodeJS插件,我遇到了一个问题,调用回调(在javascript端创建并传递给插件以异步执行)将导致segfault,但大约每10000次运行一次 每件事的运作方式都有相当多的复杂性,但我希望有人能看到我错过的东西,或者能够弄清楚发生了什么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<
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);