ref-napi: crash in v8::ArrayBuffer::GetBackingStore
steps to reprouce:
gireesh@p1:~/mq/rec1$ node -v
v14.15.4
gireesh@p1:~/mq/rec1$ cat rec.js
var ref = require('ref-napi');
var st = require('ref-struct-di')(ref);
var at = require('ref-array-di')(ref);
var rt = st({
asid: at(ref.types.char,1024),
os: st({ptr: ref.refType(ref.types.void)})
})
var idx = 0
const r = new rt()
r.os.ptr = Buffer.alloc(10)
setInterval(() => {
ref.reinterpret(r.os.ptr, 0, 'utf8');
if (++idx % 1000 === 0) console.log(`${idx}th iteration`)
r.os.ptr = Buffer.alloc(10)
},1)
gireesh@p1:~/mq/rec1$ node rec
1000th iteration
#
# Fatal error in , line 0
# Check failed: result.second.
#
#
#
#FailureMessage Object: 0x7ffd839cc040
1: 0xa71261 [node]
2: 0x19d3254 V8_Fatal(char const*, ...) [node]
3: 0xe5b549 v8::internal::GlobalBackingStoreRegistry::Register(std::shared_ptr<v8::internal::BackingStore>) [node]
4: 0xba6a98 v8::ArrayBuffer::GetBackingStore() [node]
5: 0x9c1be0 napi_get_typedarray_info [node]
6: 0x7fea6e5ef0ef [/home/gireesh/mq/rec1/node_modules/ref-napi/prebuilds/linux-x64/node.napi.node]
7: 0x7fea6e5f15bb [/home/gireesh/mq/rec1/node_modules/ref-napi/prebuilds/linux-x64/node.napi.node]
8: 0x7fea6e5f7ceb Napi::details::CallbackData<void (*)(Napi::CallbackInfo const&), void>::Wrapper(napi_env__*, napi_callback_info__*) [/home/gireesh/mq/rec1/node_modules/ref-napi/prebuilds/linux-x64/node.napi.node]
9: 0x9b8c6f [node]
10: 0xbe571b [node]
11: 0xbe6cc6 [node]
12: 0xbe7346 v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [node]
13: 0x14012d9 [node]
Illegal instruction (core dumped)
gireesh@p1:~/mq/rec1$
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 1
- Comments: 35 (8 by maintainers)
Commits related to this issue
- src: keep reference buffer alive longer Keep a buffer written by WritePointer alive until the finalizers for the buffer to which the pointer has been run have been executed: Refs: https://github.com... — committed to mhdawson/ref-napi by mhdawson 3 years ago
- src: keep reference buffer alive longer (#55) * src: keep reference buffer alive longer Keep a buffer written by WritePointer alive until the finalizers for the buffer to which the pointer has b... — committed to node-ffi-napi/ref-napi by mhdawson 3 years ago
- Use fixed versions of ref-napi and dependencies Refs: https://github.com/node-ffi-napi/ref-napi/issues/54 — committed to Qantas94Heavy/node-ffi-napi by Qantas94Heavy 2 years ago
- Use fixed versions of ref-napi and dependencies Refs: https://github.com/node-ffi-napi/ref-napi/issues/54 — committed to Qantas94Heavy/node-ffi-napi by Qantas94Heavy 2 years ago
- Use fixed versions of ref-napi and dependencies Refs: https://github.com/node-ffi-napi/ref-napi/issues/54 — committed to Qantas94Heavy/node-ffi-napi by Qantas94Heavy 2 years ago
Fyi, my branches have the full implementation with separate structures. All tests pass, though it might not be 100% compatible:
https://github.com/alphacep/ref-napi https://github.com/alphacep/node-ffi-napi
please let me know if you are interested to merge or we can just have a new packages inside this project.
Hi everyone. Any updates on this? Seems that @nshmyrev proposed a solution. I think that he can make a fork but this will be not as useful for community because everyone ends up fixing same bugs in their own implementation.
@addaleax do you have plans and time to look into this issue?
Ok the same thing but using node-addon-api versus dropping down into node-api c calls:
I’m going to open a PR and discussion on whether it is the right fix can continue there.
I’m also having this exact issue.
I haven’t seen a node ffi implementation working well since Node 12.x with the lxe pull request, tonight I thought I can finally switch to a higher NodeJS version by using ffi-napi instead of node-ffi but no luck…hopefully the proposed pull request above is accepted.
Simplified version that crashes quickly:
Created PR: https://github.com/node-ffi-napi/ref-napi/pull/55
After incrementally adding a bunch of instrumentation it looked be related to WritePointer being called as that seemed to be what was always on the stack when the crash occurred. (EDIT I see Gireesh pointed that out above, but I’d started down the instrumentation path before then).
In writePointer
_attach tries to avoid the buffer to which the pointer refers being freed before the buffer to which the pointer was written. However I seem to remember @addaleax mentioning that it was difficult to ensure that the cleanup for the buffer to which the pointer was written was complete before the reference buffer was freed. Currently it only ensures that both buffers become eligible to be collected and their finalizes run at the same time but does not ensure which order that will happen.
This patch will ensure that the buffer to which the pointer refers will only become eligible to be collected AFTER the finalizers for the buffer to which the pointer was written have been run. It seems to avoid the crash:
There are other places that use _attach so this might not be the full fix, but I thought I’d post share what I’ve figured out so far.
Thank you, Tim. I could take a look on PR a bit later but if you could help and pull the changes it would be much faster.
Since my maintenance of this package is mostly unpaid, and this would unfortunately be a larger rewrite, it’s not at the top of my agenda. @nshmyrev’s proposed solution conceptually works, and if there is a PR at some point, I’d be happy to take a look.
I’m also looking for a fix for this problem.
Forgive my ignorance, but is there a reason that breaking changes can’t be made along with a major semver bump?
Well, no other way with the current design. It could be another package like ref-napi-ng if you care about backward compatibility. At least people will be able to use FFI.
I started the implementation here, almost there, few bits with strings left:
https://github.com/alphacep/ref-napi/commit/b2d32a8264aa1010220667dbeca066d505a4de9e
@nshmyrev I’ll get to this when I can. If you have a good understanding of what’s happening, you can also open a PR, which would speed things up a bit.
Hi
we still see the crash with ref-napi 3.0.2
The code we use looks like this, it essentially creates an object and releases it afterwards:
I’ll try to simplify code probably. The crash is not stable it occurs at different iterations, so likely a threading issue. The backtrace looks like this:
The backingstore trace is attached too.
bs.log
Still looking on this issue, but maybe you have some ideas. I don’t think the patch above solved the problem.
@prabhatmishra33 I see this on the stack in the issue you posted
6: 0x7f268814b0ef [/app/node_modules/ref-napi/prebuilds/linux-x64/node.napi.node]so its possible.Since it’s in production it might be hard to try the change in #55, but that would be the best way to confirm one way or the other.