gtk-rs / gtk4-rs

Rust bindings of GTK 4
https://gtk-rs.org/gtk4-rs/
MIT License
1.75k stars 168 forks source link

`#[gtk4::test]` fails with an error "Attempted to initialize GTK on OSX from non-main thread" #1235

Open andy128k opened 1 year ago

andy128k commented 1 year ago

Bug description

Minimal example https://github.com/andy128k/test-gtk-rs-osx Successful build on Linux https://github.com/andy128k/test-gtk-rs-osx/actions/runs/3828477828/jobs/6514110530 Failure on macos https://github.com/andy128k/test-gtk-rs-osx/actions/runs/3828477834/jobs/6514110710

Backtrace

thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
  left: `0`,
 right: `1`: Attempted to initialize GTK on OSX from non-main thread', /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk4-0.5.5/src/rt.rs:100:9
stack backtrace:
   0:        0x10f877762 - std::backtrace_rs::backtrace::libunwind::trace::h74d17ea919046bae
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:        0x10f877762 - std::backtrace_rs::backtrace::trace_unsynchronized::h2fc77fd5a14165ac
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x10f877762 - std::sys_common::backtrace::_print_fmt::h2687aa7717781133
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/sys_common/backtrace.rs:65:5
   3:        0x10f877762 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hdc69a6f447628e71
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/sys_common/backtrace.rs:44:22
   4:        0x10f89380a - core::fmt::write::hb9e764fa47ae8444
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/fmt/mod.rs:1209:17
   5:        0x10f8740ac - std::io::Write::write_fmt::h8fc98987ed860a54
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/io/mod.rs:1682:15
   6:        0x10f87752a - std::sys_common::backtrace::_print::h882e8250b822b8b0
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/sys_common/backtrace.rs:47:5
   7:        0x10f87752a - std::sys_common::backtrace::print::h488fe4c0b1fb9d50
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/sys_common/backtrace.rs:34:9
   8:        0x10f879366 - std::panicking::default_hook::{{closure}}::h5618ea3156b8b833
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:267:22
   9:        0x10f8790b7 - std::panicking::default_hook::h0421c26a8a92801c
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:286:9
  10:        0x10f879aad - std::panicking::rust_panic_with_hook::h57383cd32463c250
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:688:13
  11:        0x10f879863 - std::panicking::begin_panic_handler::{{closure}}::h1d1f7305cfe67fdd
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:579:13
  12:        0x10f877bf8 - std::sys_common::backtrace::__rust_end_short_backtrace::hd8e12e82ff026bae
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/sys_common/backtrace.rs:137:18
  13:        0x10f87952d - rust_begin_unwind
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:575:5
  14:        0x10f89f003 - core::panicking::panic_fmt::h7894cd1015cfee41
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/panicking.rs:65:14
  15:        0x10f892435 - core::panicking::assert_failed_inner::h811f6cef9620601c
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/panicking.rs:240:23
  16:        0x10f89be24 - core::panicking::assert_failed::h69752dbf4d844fbc
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/panicking.rs:203:5
  17:        0x10f8362df - gtk4::rt::set_initialized::he211caa8b0bb3175
                               at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk4-0.5.5/src/rt.rs:100:9
  18:        0x10f8364df - gtk4::rt::init::h936d09e915eb8cd6
                               at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk4-0.5.5/src/rt.rs:150:13
  19:        0x10f839ad1 - gtk4::TEST_THREAD_WORKER::{{closure}}::{{closure}}::hc918ed6ec2882a74
                               at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk4-0.5.5/src/lib.rs:89:13
  20:        0x10f835491 - core::ops::function::FnOnce::call_once{{vtable.shim}}::h2d73bd5afdbbed77
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/ops/function.rs:251:5
  21:        0x10f84589e - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hb536d0fee37bdbd0
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/alloc/src/boxed.rs:1987:9
  22:        0x10f84583f - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h95ddbd0c7fa625d8
                               at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/alloc/src/boxed.rs:1987:9
  23:        0x10f845a56 - glib::thread_pool::spawn_func::h21cce7ae6b531d2c
                               at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.16.7/src/thread_pool.rs:187:5
  24:        0x11059e448 - _g_thread_pool_thread_proxy
  25:        0x11059d54b - _g_thread_proxy
  26:     0x7fff206918fc - __pthread_start
fatal runtime error: failed to initiate panic, error 5
error: test failed, to rerun pass `--bin test-gtk-rs-osx`
bilelmoussaoui commented 1 year ago

Seems the problem comes from https://github.com/gtk-rs/gtk4-rs/blob/master/gtk4/src/rt.rs#L99-L107 so someone with access to a macos machine would have to debug this.

andy128k commented 1 year ago

Recently released Rust 1.67 made things somehow worse. Now new threads are spawned for every test.

This happened to be an old issue. This stackoverflow question is almost 6 years old. It advises to not to use libtest harness and write tests out of source tree. E.g. fltk-rs follows this and their tests look like this.

N.B. I've also found a useful article with details how to organize such tests.

andy128k commented 1 year ago

So, #[gtk::test] macro makes tests run in the same thread, but this thread is never a main one. That works on Linux and Windows but does not work on macos. I don't see how any macro may solve this given that a main thread is used by libtest itself.

jf2048 commented 1 year ago

This seems pretty bad, won't this interfere with testing in every single other GUI crate that binds anything related to appkit? Do we know exactly what functions have to be called on the main thread?

I wonder if we can workaround it for now by making CI use a gtk build with the x11 or broadway backend, if that will avoid calling any appkit functions?

bilelmoussaoui commented 1 year ago

@jf2048 something i tried to do here is to make use of https://developer.apple.com/documentation/dispatch/1453123-dispatch_sync_f, but as i don't have access to a macos and the CI being slow, it was impossible to implement....

bilelmoussaoui commented 9 months ago

I just learned that there is actually a wrapper for this macOS dispatch thing. We can use http://sasheldon.com/rust-objc/dispatch/struct.Queue.html#method.sync to achieve what we want I believe. I added it to my to-do list