Closed fzyzcjy closed 6 months ago
I briefly looked at it, seems that the error is caused by fatal runtime error: failed to initiate panic, error 3
with:
2023-08-19T03:58:25.7349373Z ==5084== Process terminating with default action of signal 6 (SIGABRT)
2023-08-19T03:58:25.7349798Z ==5084== at 0x49EEA7C: __pthread_kill_implementation (pthread_kill.c:44)
2023-08-19T03:58:25.7350214Z ==5084== by 0x49EEA7C: __pthread_kill_internal (pthread_kill.c:78)
2023-08-19T03:58:25.7350867Z ==5084== by 0x49EEA7C: pthread_kill@@GLIBC_2.34 (pthread_kill.c:89)
2023-08-19T03:58:25.7351202Z ==5084== by 0x499A475: raise (raise.c:26)
2023-08-19T03:58:25.7351779Z ==5084== by 0x49807F2: abort (abort.c:79)
2023-08-19T03:58:25.7352129Z ==5084== by 0x5F4BFC6: std::sys::unix::abort_internal (mod.rs:350)
2023-08-19T03:58:25.7352483Z ==5084== by 0x5F4887C: rust_panic (panicking.rs:742)
2023-08-19T03:58:25.7352879Z ==5084== by 0x5F48711: std::panicking::rust_panic_with_hook (panicking.rs:713)
2023-08-19T03:58:25.7353318Z ==5084== by 0x5E28809: std::panicking::begin_panic::{{closure}} (panicking.rs:611)
2023-08-19T03:58:25.7353777Z ==5084== by 0x5E27DCC: std::sys_common::backtrace::__rust_end_short_backtrace (backtrace.rs:150)
2023-08-19T03:58:25.7354219Z ==5084== by 0x5E28746: std::panicking::begin_panic (panicking.rs:610)
2023-08-19T03:58:25.7354668Z ==5084== by 0x59E28C0: flutter_rust_bridge_example_pure_dart::api::handle_sync_return (api.rs:345)
2023-08-19T03:58:25.7355239Z ==5084== by 0x5A2E947: flutter_rust_bridge_example_pure_dart::bridge_generated::wire_handle_sync_return_impl::{{closure}} (bridge_generated.rs:502)
2023-08-19T03:58:25.7355866Z ==5084== by 0x5A82E57: <flutter_rust_bridge::handler::ThreadPoolExecutor<EH> as flutter_rust_bridge::handler::Executor>::execute_sync (handler.rs:249)
then since it fails to panic, it aborts (stop the whole process).
related source code: https://github.com/rust-lang/rust/blob/5e9d3d8a03fadf1877286528e5c9d0c056ac82b5/library/std/src/panicking.rs#L780
7c7
< Get:7 http://azure.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [894 kB]
---
> Get:7 http://azure.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [889 kB]
10,16c10,16
< Get:10 http://azure.archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [714 kB]
< Get:11 http://azure.archive.ubuntu.com/ubuntu jammy-updates/restricted Translation-en [114 kB]
< Get:12 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [969 kB]
< Get:13 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe Translation-en [211 kB]
< Get:14 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 c-n-f Metadata [21.5 kB]
< Get:15 http://azure.archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 Packages [41.6 kB]
< Get:16 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
---
> Get:10 http://azure.archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [710 kB]
> Get:11 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
> Get:12 http://azure.archive.ubuntu.com/ubuntu jammy-updates/restricted Translation-en [113 kB]
> Get:13 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [965 kB]
> Get:14 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe Translation-en [210 kB]
> Get:15 http://azure.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 c-n-f Metadata [21.5 kB]
> Get:16 http://azure.archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 Packages [41.6 kB]
18,20c18,20
< Hit:18 https://ppa.launchpadcontent.net/ubuntu-toolchain-r/test/ubuntu jammy InRelease
< Get:19 http://azure.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages [680 kB]
< Get:20 http://azure.archive.ubuntu.com/ubuntu jammy-security/main Translation-en [155 kB]
---
> Get:18 http://azure.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages [657 kB]
> Hit:19 https://ppa.launchpadcontent.net/ubuntu-toolchain-r/test/ubuntu jammy InRelease
> Get:20 http://azure.archive.ubuntu.com/ubuntu jammy-security/main Translation-en [153 kB]
22,23c22,23
< Get:22 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [694 kB]
< Get:23 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted Translation-en [110 kB]
---
> Get:22 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [662 kB]
> Get:23 http://azure.archive.ubuntu.com/ubuntu jammy-security/restricted Translation-en [105 kB]
28,30c28,30
< Get:28 https://packages.microsoft.com/ubuntu/22.04/prod jammy/main armhf Packages [9004 B]
< Get:29 https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages [87.2 kB]
< Get:30 https://packages.microsoft.com/ubuntu/22.04/prod jammy/main arm64 Packages [18.1 kB]
---
> Get:28 https://packages.microsoft.com/ubuntu/22.04/prod jammy/main amd64 Packages [85.7 kB]
> Get:29 https://packages.microsoft.com/ubuntu/22.04/prod jammy/main arm64 Packages [17.9 kB]
> Get:30 https://packages.microsoft.com/ubuntu/22.04/prod jammy/main armhf Packages [8877 B]
36,38c36,38
< Get:36 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [680 kB]
< Get:37 http://archive.ubuntu.com/ubuntu jammy/restricted amd64 c-n-f Metadata [488 B]
< Get:38 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [894 kB]
---
> Get:36 http://archive.ubuntu.com/ubuntu jammy/restricted amd64 c-n-f Metadata [488 B]
> Get:37 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [657 kB]
> Get:38 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [889 kB]
41,42c41,42
< Get:41 http://archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [714 kB]
< Get:42 http://archive.ubuntu.com/ubuntu jammy-updates/restricted Translation-en [114 kB]
---
> Get:41 http://archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [710 kB]
> Get:42 http://archive.ubuntu.com/ubuntu jammy-updates/restricted Translation-en [113 kB]
44c44
< Get:44 http://security.ubuntu.com/ubuntu jammy-security/main Translation-en [155 kB]
---
> Get:44 http://security.ubuntu.com/ubuntu jammy-security/main Translation-en [153 kB]
46,47c46,47
< Get:46 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [694 kB]
< Get:47 http://security.ubuntu.com/ubuntu jammy-security/restricted Translation-en [110 kB]
---
> Get:46 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [662 kB]
> Get:47 http://security.ubuntu.com/ubuntu jammy-security/restricted Translation-en [105 kB]
the diff file of the apt packages. doesn't seem like it tho. currently trying to find more possible causes dart last update -> May 10 python -> 2022/10/24 rust -> a set toolchain valgrind -> april 2023
(btw I also suspect it is GitHub CI machine update that causes this problem)
https://github.com/actions/runner-images/commits/main/images/linux/Ubuntu2204-Readme.md The failing of the test happened three days ago, so not that either Maybe it has to do with the dart and rust deps, will look into it more
just throwing ideas(left is old, right is new)
Another way is to make a minimal reproducible sample and create a bug on the related package. For example, maybe we can write a minimal rust program that panics, and check whether it still fails like this ("failed to initiate panic") under valgrind. If so, we can create an issue at Valgrind, and (maybe) another issue at Rust.
After a series of tests, I found that the issues seems to have nothing to do with Rust, and a simple Dart hello world will also fail.
https://github.com/dart-lang/sdk/issues/47346
Yes,
Thus I have allowed those "mismatched free" to happen (i.e. ci will still be green).
The main problem here is that, after we ignore those "mismatched free" things, we still have "fatal runtime error: failed to initiate panic, error 3".
Only testing returnPanic doesn't print this error message fatal runtime error: failed to initiate panic, error 3
.
00:00 +0: dart call returnPanic
thread 'frb_workerpool' panicked at 'return_panic() is called, thus deliberately panic', frb_example/pure_dart/rust/src/api.rs:396:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
dart catch e: Instance of 'PanicException'
==1065== Mismatched free() / delete / delete []
==1065== at 0x484412F: free (vg_replace_malloc.c:974)
==1065== by 0x48475A: ??? (in /mnt/d/Coding/Github/flutter_rust_bridge/frb_example/pure_dart/dart/main.exe)
==1065== by 0x484E7D: ??? (in /mnt/d/Coding/Github/flutter_rust_bridge/frb_example/pure_dart/dart/main.exe)
==1065== by 0x485391: ??? (in /mnt/d/Coding/Github/flutter_rust_bridge/frb_example/pure_dart/dart/main.exe)
==1065== by 0x519B88: ??? (in /mnt/d/Coding/Github/flutter_rust_bridge/frb_example/pure_dart/dart/main.exe)
==1065== by 0x519E52: ??? (in /mnt/d/Coding/Github/flutter_rust_bridge/frb_example/pure_dart/dart/main.exe)
==1065== by 0x4E228F: ??? (in /mnt/d/Coding/Github/flutter_rust_bridge/frb_example/pure_dart/dart/main.exe)
==1065== by 0x49D29EA: start_thread (pthread_create.c:444)
==1065== by 0x4A56C83: clone (clone.S:100)
==1065== Address 0x4c20dc0 is 0 bytes inside a block of size 56 alloc'd
==1065== at 0x4843223: operator new[](unsigned long) (vg_replace_malloc.c:714)
==1065== by 0x485A69: ??? (in /mnt/d/Coding/Github/flutter_rust_bridge/frb_example/pure_dart/dart/main.exe)
==1065== by 0x4882AA: ??? (in /mnt/d/Coding/Github/flutter_rust_bridge/frb_example/pure_dart/dart/main.exe)
==1065== by 0x5B7EB9: ??? (in /mnt/d/Coding/Github/flutter_rust_bridge/frb_example/pure_dart/dart/main.exe)
==1065== by 0x5989FB7: allo_isolate::Isolate::post (lib.rs:139)
==1065== by 0x5990783: flutter_rust_bridge::rust2dart::Rust2Dart::panic (rust2dart.rs:41)
==1065== by 0x598CBA3: <flutter_rust_bridge::handler::ReportDartErrorHandler as flutter_rust_bridge::handler::ErrorHandler>::handle_error (handler.rs:319)
==1065== by 0x55AD418: <flutter_rust_bridge::handler::ThreadPoolExecutor<EH> as flutter_rust_bridge::handler::Executor>::execute::{{closure}} (handler.rs:240)
==1065== by 0x55E929E: <F as threadpool::FnBox>::call_box (lib.rs:95)
==1065== by 0x59A2450: threadpool::spawn_in_pool::{{closure}} (lib.rs:769)
==1065== by 0x599D06D: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:135)
==1065== by 0x5997A7A: std::thread::Builder::spawn_unchecked_::{{closure}}::{{closure}} (mod.rs:529)
==1065==
00:00 +1: (tearDownAll)
00:00 +1: All tests passed!
Interesting! Then we may be able to bisect (or whatever) to reduce the testing
(btw, does the full test fail on your local machine?)
The unit tests are successful on my local machine.
Hmm then this looks like a github ci - only issue, at least maybe dependent on the OS version etc?
The errors occurs on my arch linux machine as well
Update: (at least on my machine)
it seems like it's not an valgrind error
running cargo test
in frb_codegen is enough to cause the error
so maybe the error originates is about panicing in FFI boundaries are UB?(should be handled in frb_rust/src/handle.rs
)
Looks great!
panicing in FFI boundaries are UB
IIRC we never panic across ffi boundaries (except for bugs). Instead, we have error handlers catching panic.
see:
(I even wrote double catch_unwind to be extra safe, see comments there)
@JustSimplyKyle Btw, what is your full logs? We should be sure it is the "failed to initiate panic" error instead of any other errors, otherwise we may be risk working on a non-goal. From the screenshot I am not very sure yet.
Sure! fulllog.log
(copy-pasted the last parts for the convenience of future readers)
Interesting! Looks like we are near (eg further reduce to minimal sample)
I condensed the frb_examples in into just these and it still can't initiate main.dart
import 'package:flutter_rust_bridge/flutter_rust_bridge.dart';
import 'package:test/test.dart';
import 'ffi.io.dart' if (dart.library.html) 'ffi.web.dart';
void main(List<String> args) async {
String dylibPath = args[0];
print('flutter_rust_bridge example program start (dylibPath=$dylibPath)');
print('construct api');
final api = initializeExternalLibrary(dylibPath);
tearDownAll(() => api.dispose());
// Test if sync return is working as expected.
test('dart call panic', () async {
try {
api.panic();
fail("exception not thrown");
} on FfiException catch (e) {
print('dart catch e: $e');
}
});
}
api.rs
// Test if sync return is working as expected by using Vec<u8> as return value.
pub fn panic() {
panic!("will panic");
}
generated
Future<void> panic({dynamic hint}) {
return _platform.executeNormal(FlutterRustBridgeTask(
callFfi: (port_) => _platform.inner.wire_panic(port_),
parseSuccessData: _wire2api_unit,
constMeta: kPanicConstMeta,
argValues: [],
hint: hint,
));
}
Future<S> executeNormal<S>(FlutterRustBridgeTask<S> task) {
final completer = Completer<dynamic>();
final sendPort = singleCompletePort(completer);
task.callFfi(sendPort.nativePort);
return completer.future.then((dynamic raw) =>
_transformRust2DartMessage(raw, task.parseSuccessData));
}
I'm not entirely sure whether if executeNormal calls execute, but https://github.com/fzyzcjy/flutter_rust_bridge/blob/e248cbc2df2328043843a12d61fc551b004fb9a4/frb_rust/src/handler.rs#L203 it seems like here, catch_unwind is only "capturing once" (and naively wrapping the full function in catch_unwind doesn't fix it)
EDIT: after further testing
the dbg! call(I add the dbg! call after the spawn call in execute linked above)seems like it's racing with the panic, so it seems like the error is indeed in the spawn call
EDIT2:
dbg!("test from execute(after spawn call)");
let ret = task(TaskCallback::new(rust2dart.clone()))
.map(|e| e.into_into_dart().into_dart());
if we put the dbg! call after the ret, it won't get called! hmm... so when task try to execute our function(which is just panic) it failes to do so... but we also failed to catch the panic??
this is my modified handler execute
, I removed all the error handling code for now
let _ = panic::catch_unwind(move || {
let WrapInfo { port, .. } = wrap_info;
let _ = panic::catch_unwind(move || {
let port2 = port.as_ref().cloned();
let port2 = port2.expect("(worker) thread");
#[allow(clippy::clone_on_copy)]
let rust2dart = Rust2Dart::new(port2.clone());
let _ = panic::catch_unwind(move || {
task(TaskCallback::new(rust2dart.clone()))
.map(|e| e.into_into_dart().into_dart())
});
unreachable!();
});
});
and naively wrapping the full function in catch_unwind doesn't fix it
so
// Test if sync return is working as expected by using Vec<u8> as return value.
pub fn panic() {
catch_unwind(||{
panic!("will panic");
});
}
does not work?
yep, doesn't still errors with
fatal runtime error: failed to initiate panic, error 3
that looks expected error, since our major problem is "failed to initiate panic" - so the panic itself should cause abort IMHO
(note: I am working on mathematics today, so my brain may be quite silly about programming!)
so next step may be further reduce it. for example, some naive bisect ideas:
Let me come back to this problem...
As shown in the issues above, it is reproduced using naive Dart + naive Rust, without flutter_rust_bridge.
With https://github.com/dart-lang/sdk/issues/53545#issuecomment-1722421459, I checked the dart version between the two CI that fails and passes:
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new issue.
Context
As is reported in https://github.com/fzyzcjy/flutter_rust_bridge/pull/1325#issuecomment-1684886886, https://github.com/fzyzcjy/flutter_rust_bridge/actions/runs/5868452973/job/15911323953 works while https://github.com/fzyzcjy/flutter_rust_bridge/actions/runs/5909307658/job/16029737370 breaks. The code change is completely unrelated to it.
This blocks
1325
1145
from merging, because both PRs are large and may really introduce memory-related issues, thus we should not merge without a green Valgrind CI - otherwise if is really has memory problems, it will be quite subtle and very hard to debug or fix in production.