Search code examples
c++node.jsnode-addon-api

calling Napi::ThreadSafeFunction::Release() results in ELIFECYCLE 3221225477 (STATUS_ACCESS_VIOLATION)


A mention in the title I have some weird thread issues.

Basically I am wrapping PS2000 Api with node-addon-api like in the linked example.

As those api callbacks need "C" like functions, I trampolined those with something like:

CLASSNAME *trampoline[N] = {}
template<int I>f(...){
  trampoline[I]->tsfn.BlockingCall(&args, [](..., *args){
     //do stuff
     if(trampoline->calledCallbacksCount >= trampoline->estimatedCallbackCount){
            trampoline->tsfn.Release();
     }
  })
}
CALLBACK *fptr[N] = {
   f<0>, ..., f<N>
}

CLASSNAME::CLASSNAME(){
   trampoline[nextEmptyIndex] = this;
   this->callback = fptr[nextEmtyIndex];
}
CLASSNAME::read(){
   this->tsfn = Napi::ThreadSafeFunction::New(...)
   //...
   nativethread = std::thread([this]{
       //... start device stream & wait some time
       if(ps2000_get_streaming_last_values(this->deviceHandle, this->callback) == 0){
          // no callback
       }
       if(this->calledCallbacksCount >= this->estimatedCallbackCount){
            this->tsfn.Release();
       }
   }
}

void my_get_overview_buffers

(
   short **overviewBuffers,
   short overflow,
   unsigned long triggeredAt,
   short triggered,
   short auto_stop,
   unsigned long nValues
)

The api function ps2000_get_streaming_last_values can call the callback multiple times and the count of callbacks can be estimated by the length of **overviewBuffers (nValues).

When I leave out tsfn.Release() there is no error.

Also it returns napi_ok when using.

It feels like there is some kind of late callback into emptyness - but only when the thread is released...

I am at loss - someone has an idea?


Wait!

What happens to the memcpied *buffers that are passed into the jsCallback.Call({Napi::ArrayBuffer::New(env, *buffer, size)})

is this the access violation? how do you solve this then without not releasing tsfn?


I am working on Windows in VSCODE,

my launch json contains :

     {
        "name": "Debug",
        "type": "cppvsdbg",
        "request": "launch",
        "program": "node",
        "args": ["index.ts"],
        "stopAtEntry": false,
        "cwd": "${workspaceFolder}",
        "environment": [],
        "externalConsole": false
    }

but the debugger not triggering ...


Solution

  • The issue is not related to node-addon-api.

    It was a buffer overflow induced by the picoscope device gathering to much data due to a lag or w/e ultimatly leading to nValues > OverviewBufferSize which lead when copiing those buffers to out of range access and thus to access violations.

    Just handling those cases and enlarging the buffersize solved this.