-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dart:ffi not working with Isolate.spawn #48532
Comments
You need to provide more information. Right now the only thing we can see is that there is some null pointer dereference. There can be many different reasons why your code is crashing. |
@mraleph thanks a lot for your quick response. Basically, the data flow is as follows:user code <---dart object---> lib (as a flutter plugin) which calls Isolate.spawn() <---dart object---> spawned isolate which uses dart:ffi to call c++ code <---json---> c++ code which runs heavy task, and also invokes callbacks from spawned isolate. The code which calls Isolate.spawn() is as follows:
If dart:ffi works fine with isolates, I may need look more into c++ code.BTW, my c++ code uses dart api to release dart object as follows:
|
//cc @aam |
|
One thing I could think about is that reusing something like a FFI trampoline between two isolates might result in a strange issues due to how this is implemented right now. e.g. the following will break in strange ways: void callback() {
}
final callbackPtr = Pointer.fromFunction<Void Function()>(callback);
void isolateMain() {
if (clibrary_needs_init())
init_clibrary(callbackPtr);
} e.g. if you spawn But it is hard to say if this a problem or not without seeing stack trace from your SIGSEGV and/or poking around in the debugger to understand where exactly the crash occurs. |
Callbacks into an isolate can only be invoked when being the mutator thread from that isolate (either by doing an ffi call from that isolate, or by using the Dart API to enter the isolate). This is a known limitation. Asynchronous callbacks would not have this limitation, when we get around to implementing those: The known workaround is to use ports for the callbacks rather than ffi callback trampolines. See documentation in the first post in the above issue.
@mraleph, how do you propose addressing this known limitation? Always calling to a trampoline which blocks until there's no more mutator running in the isolate and then run it? That is basically what we would do for async callbacks. |
Maybe this is the key to this problem. I'm going to try long running isolate solution, and will give feedback here soon.
|
It still does NOT work stably, even if initialize the native code once in the spawned isolate and remove all callbacks. I have created a minimal repo(isolate-spawn-demo) to reproduce this:
Meanwhile, It works stably if call ffi in the main isolate. Just show the button in example/lib/main.dart and run again(Don't hot reload):
BTW. the native code is just a v8 hello-world program, see here. |
@xuchaoqian My guess would be the following (without looking at this in the debugger). It's the same thing I warned about in my very first comment: V8 uses TLS (thread local storage) to associate Your current code enters You can try to change your code to enter isolate in Script::Script() {
auto isolate = Runtime::GetInstance()->GetIsolate();
v8::Isolate::Scope isolate_scope(isolate);
// ...
} I think this will likely fix the issue. There is a feature request to allow creating isolates pinned to a specific thread (#46943) but we have not yet have a chance to figure out how it would look like, so right now you have to be very careful using libraries like V8 which rely on TLS for certain things. |
@mraleph Still does NOT work correctly. BUT you inspired me just now! I should NOT use Isolate.spawn in my case, but should use thread in native code directly instead. I will have a try in this way, and give feedback here soon. |
Sorry for late reply. It took me some time to completely rewrite this flutter plugin. Now it works perfectly to use the solution: combine the benefits of native threads and native port. Thank you for your awesome works on dart vm and dart:ffi. @mraleph @dcharkes @aam I still have some questions about resource management as follows: 1. Is it safe to malloc native memory on the [dart side] (use String.toNativeUtf8() method) and call the free() function on the [cpp side]?Dart side
Cpp side
2. Is it safe to malloc native memory on the [cpp side] (use malloc() function) and call malloc.free() method on the [dart side]?It's a little tricky to transfer pointers from cpp side to dart side: Cpp side
Dart side
|
(Note: this is becoming off topic, feel free to open new issues for things not imediately related to RE 1 & 2: Yes. As long as you're not on Windows. On Windows
This is by design. Your code looks exactly as expected. We want to make |
@dcharkes I've learned a lot. Thank you! |
We implemented a flutter plugin which uses dart:ffi package to call c++ code.
It works well without Isolate.spawn. But it crashed after moving the code to spawned Isolate.
So, does Isolate.spawn not support dart:ffi?
The error message as following:
My developer tools as following:
The text was updated successfully, but these errors were encountered: