两次调用某个回调函数会导致分段错误:Nan [英] Invoking some callback function twice leads to Segmentation fault: Nan
问题描述
我正在编写 C++ 插件,使用 nbind - GitHub 链接 和 Nan - GitHub 链接 用于异步调用回调.当我只调用一次回调时,它工作得很好.但是当我调用回调两次时,它会给出 Segmentation fault (core dumped)
.使用 gdb
找不到错误.下面是 JS 和 C++ 代码(使用 node-gyp configure build
编译):
I am writing C++ addon using nbind - GitHub link for most thing and Nan - GitHub link for calling callbacks asynchronous. When I invoke callback only once, it works perfect. But When I invoke callback twice it gives Segmentation fault (core dumped)
. Couldn't find error using gdb
. Here is JS and C++ codes(compiling using node-gyp configure build
):
//main.js code
var nbind = require('nbind');
var lib = nbind.init().lib;
lib.HeaderExample.callJS(function(a) {
console.log("result" + a);
});
lib.HeaderExample.startThread();
lib.HeaderExample.startThread();
C++插件代码
//c++ code
class CallbackRunner : public Nan::AsyncWorker {
public:
CallbackRunner(Nan::Callback *callback)
: AsyncWorker(callback) {}
void Execute () {}
void HandleOKCallback () {
std::cout << "running HandleOKCallback in thread " << std::this_thread::get_id() << std::endl;
Nan::HandleScope scope;
v8::Local<v8::Value> argv[] = {
Nan::New<v8::Number>(10)
};
callback->Call(1, argv);
}
};
class HeaderExample {
public:
static void callJS(nbind::cbFunction &callback) {
std::cout << "running callJS in thread " << std::this_thread::get_id() << std::endl;
m_onInitialisationStarted = new nbind::cbFunction(callback);
Nan::Callback *callbackNan = new Nan::Callback(m_onInitialisationStarted->getJsFunction());
runner = new CallbackRunner(callbackNan);
}
static void startThread() {
std::cout << "it is here";
std::thread threadS(some);
threadS.join();
}
static void some() {
std::cout << "running some in thread: " << std::this_thread::get_id() << std::endl;
if(runner){
AsyncQueueWorker(runner);
}
}
inline static nbind::cbFunction *m_onInitialisationStarted = 0;
inline static CallbackRunner *runner;
};
推荐答案
你的类使用 AsyncQueueWorker
来调用 CallbackRunner
,但是 AsyncQueueWorker
调用AsyncExecuteComplete
回调完成后,依次调用worker->Destroy()
.查看 nan.h
中的 AsyncQueueWorker
代码:
Your class uses AsyncQueueWorker
to invoke the CallbackRunner
, but AsyncQueueWorker
calls AsyncExecuteComplete
after the callback is done, which in turn calls worker->Destroy()
. See the AsyncQueueWorker
code from nan.h
:
inline void AsyncExecute (uv_work_t* req) {
AsyncWorker *worker = static_cast<AsyncWorker*>(req->data);
worker->Execute();
}
inline void AsyncExecuteComplete (uv_work_t* req) {
AsyncWorker* worker = static_cast<AsyncWorker*>(req->data);
worker->WorkComplete();
worker->Destroy();
}
inline void AsyncQueueWorker (AsyncWorker* worker) {
uv_queue_work(
uv_default_loop()
, &worker->request
, AsyncExecute
, reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
);
}
worker->Destroy()
将删除 CallbackRunner
类,以及您提供给其构造函数的 Nan::Callback
.这就是您在第二次尝试调用此回调时遇到分段错误的原因.
worker->Destroy()
will delete the CallbackRunner
class, along with the Nan::Callback
that you fed to its constructor. That is the reason why you get a segmentation fault when attempting to call this callback a second time.
您最好将类基于 Nan::AsyncProgressQueueWorker
而不是 Nan::AsyncWorker
.AsyncProgressQueueWorker
继承了 AsyncWorker
,它允许你像 AsyncWorker
一样从主线程调度工作,但它为你提供了一个 ExecutionProgress
允许您在原始计划作业运行时使用任何线程任意次数回调主线程的类.
You might be better off basing your class on Nan::AsyncProgressQueueWorker
instead of Nan::AsyncWorker
. AsyncProgressQueueWorker
inherits AsyncWorker
and it allows you to schedule work from the main thread just as AsyncWorker
does, but it provides you with an ExecutionProgress
class that allows you to use any thread to call back into the main thread any number of times while the original scheduled job is running.
Nan::AsyncProgressQueueWorker
在 2.8.0
这篇关于两次调用某个回调函数会导致分段错误:Nan的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!