Open XDream8 opened 11 months ago
usually WaylandOnly
panics when invoked during an X session, but I guess this is not the case?
xwayland support is enabled in my sway session can it be related to it?
$ echo $WAYLAND_DISPLAY
wayland-1
$ echo $DISPLAY
:0
well, if you have xwayland anyway - you can just use LinuxBackend::X11 :)
still a bug tho!
tried using all of the backends available to linux and none of them works.
it seems pretty hard to find out how and why this happens but it seems to not detect X11 or wayland libraries so i would say it may be related to how wayland/X11 is packaged.
this is how wayland library is configured and i dont see any problem so i presume it may be related to the wayland bindings used in miniquad
meson \
--prefix=/usr \
-Ddefault_library=both \
-Dtests=false \
-Ddocumentation=false \
-Ddtd_validation=false \
. build
it may also be because of musl libc so i recommend testing macroquad in a Void musl environment
$ ldd /usr/lib/libwayland-egl.so
ldd (0x7fdb9b213000)
libc.so => ldd (0x7fdb9b213000)
$ ldd /usr/lib/libwayland-client.so
ldd (0x7f31288c2000)
libffi.so.8 => /lib/libffi.so.8 (0x7f31288a2000)
libc.so => ldd (0x7f31288c2000)
logs: X11WithWaylandFallback backend:
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.02s
Running `target/debug/game-test`
Failed to initialize through X11! Trying wayland instead
X11Only backend backtrace:
$ RUST_BACKTRACE=full cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.02s
Running `target/debug/game-test`
thread 'main' panicked at 'X11 backend failed', /home/xdream8/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/miniquad-0.4.0-alpha.10/src/lib.rs:253:50
stack backtrace:
0: 0x7fc6d2841d91 - std::backtrace_rs::backtrace::libunwind::trace::hd4ea3ee8a54906d1
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
1: 0x7fc6d2841d91 - std::backtrace_rs::backtrace::trace_unsynchronized::hb1a2d1da57c55e75
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x7fc6d2841d91 - std::sys_common::backtrace::_print_fmt::ha020ae1a8a6e7652
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:65:5
3: 0x7fc6d2841d91 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h9f8b5092c5aa701c
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:44:22
4: 0x7fc6d2878cbf - core::fmt::rt::Argument::fmt::h08453fb0e29bdaee
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/fmt/rt.rs:138:9
5: 0x7fc6d2878cbf - core::fmt::write::hf3858e39e16479b1
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/fmt/mod.rs:1094:21
6: 0x7fc6d283f647 - std::io::Write::write_fmt::h15da7eaa151b6970
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/io/mod.rs:1714:15
7: 0x7fc6d2841ba5 - std::sys_common::backtrace::_print::ha534c3c7329a338a
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:47:5
8: 0x7fc6d2841ba5 - std::sys_common::backtrace::print::h61e8291cc38f15df
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:34:9
9: 0x7fc6d2842fb3 - std::panicking::default_hook::{{closure}}::h00e02ec987560e96
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:269:22
10: 0x7fc6d2842d44 - std::panicking::default_hook::ha1e4b3a7bcabe548
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:288:9
11: 0x7fc6d2843539 - std::panicking::rust_panic_with_hook::hd0af6192a7f5c8c0
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:705:13
12: 0x7fc6d2843437 - std::panicking::begin_panic_handler::{{closure}}::h142dcdc9390ef36c
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:597:13
13: 0x7fc6d28421f6 - std::sys_common::backtrace::__rust_end_short_backtrace::hf4e07a5e30bef7f3
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:151:18
14: 0x7fc6d2843182 - rust_begin_unwind
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:593:5
15: 0x7fc6d26eafb3 - core::panicking::panic_fmt::ha8f81b88fc5ce542
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/panicking.rs:67:14
16: 0x7fc6d26eaf73 - core::panicking::panic_display::h03e84ec271c1e6e1
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/panicking.rs:150:5
17: 0x7fc6d26eaf73 - core::panicking::panic_str::hdc0850b540d64ea7
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/panicking.rs:134:5
18: 0x7fc6d26eaf73 - core::option::expect_failed::h3c5396f230db78ad
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/option.rs:1952:5
19: 0x7fc6d26ec5eb - core::option::Option<T>::expect::hf7d3a587c04a88a9
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/option.rs:898:21
20: 0x7fc6d26ed31c - miniquad::start::h10a9b14f4f768930
at /home/xdream8/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/miniquad-0.4.0-alpha.10/src/lib.rs:253:17
21: 0x7fc6d26ebf22 - macroquad::Window::from_config::hf3dfaf5ba196c3d0
at /home/xdream8/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/macroquad-0.4.4/src/lib.rs:764:9
22: 0x7fc6d270bf01 - game_test::main::h4622dff978458ac6
at /home/xdream8/files/proj/game-test/src/main.rs:16:1
23: 0x7fc6d26fda6b - core::ops::function::FnOnce::call_once::hc7453ee3b2940630
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ops/function.rs:250:5
24: 0x7fc6d2708afe - std::sys_common::backtrace::__rust_begin_short_backtrace::had79d23161cfa5c1
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:135:18
25: 0x7fc6d26ff791 - std::rt::lang_start::{{closure}}::h1933c5677f1f2d8a
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:166:18
26: 0x7fc6d283cb22 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h2565476b49fcd7dc
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ops/function.rs:284:13
27: 0x7fc6d283cb22 - std::panicking::try::do_call::ha1014e3bb8270d94
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:500:40
28: 0x7fc6d283cb22 - std::panicking::try::h47374bd91e24ad1c
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:464:19
29: 0x7fc6d283cb22 - std::panic::catch_unwind::h8a54a4989bd6bf92
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panic.rs:142:14
30: 0x7fc6d283cb22 - std::rt::lang_start_internal::{{closure}}::hb8b1292915cb49e2
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:148:48
31: 0x7fc6d283cb22 - std::panicking::try::do_call::h46799a8db12eba03
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:500:40
32: 0x7fc6d283cb22 - std::panicking::try::h902bd23c128df220
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:464:19
33: 0x7fc6d283cb22 - std::panic::catch_unwind::h5775836cd784f100
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panic.rs:142:14
34: 0x7fc6d283cb22 - std::rt::lang_start_internal::hbfa2424132dddc00
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:148:20
35: 0x7fc6d26ff76a - std::rt::lang_start::hb22af59277123dbf
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:165:17
36: 0x7fc6d270bf6e - main
i will test this code and see if it is related to it: https://github.com/not-fl3/miniquad/blob/aa38a5bfc01350dd6e6132d44372189f14ba5dd9/src/native/module.rs#L22C35-L22C35
yep it seems to be caused by dlopen() by libc crate. i will try doing this with dlopen crate and see the results
code:
#[derive(Debug)]
enum Error {
DlOpenError,
}
use libc::{dlopen, RTLD_LAZY, RTLD_LOCAL};
use std::{
ffi::{c_void, CString},
ptr::NonNull,
};
fn load(path: &str) -> Result<NonNull<c_void>, Error> {
let path = CString::new(path).unwrap();
let module = unsafe { dlopen(path.as_ptr(), RTLD_LAZY | RTLD_LOCAL) };
if module.is_null() {
Err(Error::DlOpenError)
} else {
Ok(unsafe { NonNull::new_unchecked(module) })
}
}
fn main() {
if let Err(err) = load("/usr/lib/libwayland-egl.so") {
eprintln!("{err:?}");
};
}
result:
$ cargo run
Compiling tests v0.1.0 (/home/xdream8/files/proj/tests)
Finished dev [unoptimized + debuginfo] target(s) in 0.17s
Running `target/debug/tests`
DlOpenError
Library::open() from dlopen crate does not work too(as it seems to use dlopen() method from libc crate too). now i am 99.9% sure that this is a problem with libc crate(more likely lack of support for musl libc)
I do not know enough about musl to comment, but does it support dynamic loading? Quick google give me this, which is a bit suspicious: https://git.musl-libc.org/cgit/musl/tree/src/ldso/dlopen.c
ok, it was in dlink.c and according to documentation - musl can dlopen just fine. The only thing we should change to make it happen - use musl's dlopen.
I did not tried, but, I think, ditching libc crate alltogether and just using extern "C" fn dlopen(filename: *const i8, flag: std::ffi::c_int) -> *mut std::ffi::c_void
should work just fine on both libc and musl machines?
i will try testing this code in a Void musl vm and see if it gives the same error
code:
use std::{
ffi::{c_void, c_char, CString, CStr},
ptr::NonNull,
};
extern "C" {
fn dlopen(filename: *const c_char, flag: i32) -> *mut c_void;
fn dlerror() -> *mut c_char;
}
fn load(path: &str) -> Result<NonNull<c_void>, String> {
let path = CString::new(path).unwrap();
let module = unsafe { dlopen(path.as_ptr(), 1 | 0) };
if module.is_null() {
let error = unsafe {
let error_ptr = dlerror();
if error_ptr.is_null() {
"Unknown Error"
} else {
CStr::from_ptr(error_ptr).to_str().unwrap()
}
};
Err(error.to_owned())
} else {
Ok(unsafe { NonNull::new_unchecked(module) })
}
}
fn main() {
if let Err(err) = load("/usr/lib/libwayland-egl.so") {
eprintln!("{err}");
};
}
log:
$ cargo run
Compiling tests v0.1.0 (/home/xdream8/files/proj/tests)
Finished dev [unoptimized + debuginfo] target(s) in 0.20s
Running `target/debug/tests`
Dynamic loading not supported
Hmm, I found this: https://github.com/helix-editor/helix/pull/4818/files#diff-9a4f3e4537ebb7474452d131b0d969d89a51286f4269aac5ef268e712be17268R5
modifying .cargo/config.toml is not a perfect solution, but does it works?
quick test to check if their solution works: RUSTFLAGS='-C target-feature=-crt-static' cargo run
on this example, I am very curious if it will fix it?
`
i will try testing this code in a Void musl vm and see if it gives the same error
code:
use std::{ ffi::{c_void, c_char, CString, CStr}, ptr::NonNull, }; extern "C" { fn dlopen(filename: *const c_char, flag: i32) -> *mut c_void; fn dlerror() -> *mut c_char; } fn load(path: &str) -> Result<NonNull<c_void>, String> { let path = CString::new(path).unwrap(); let module = unsafe { dlopen(path.as_ptr(), 1 | 0) }; if module.is_null() { let error = unsafe { let error_ptr = dlerror(); if error_ptr.is_null() { "Unknown Error" } else { CStr::from_ptr(error_ptr).to_str().unwrap() } }; Err(error.to_owned()) } else { Ok(unsafe { NonNull::new_unchecked(module) }) } } fn main() { if let Err(err) = load("/usr/lib/libwayland-egl.so") { eprintln!("{err}"); }; }
log:
$ cargo run Compiling tests v0.1.0 (/home/xdream8/files/proj/tests) Finished dev [unoptimized + debuginfo] target(s) in 0.20s Running `target/debug/tests` Dynamic loading not supported
yep that indeed fixes this. i dont get any error
wow! should we just put this in .cargo and call it a day?
that would be good
feel free to open a PR! I don't have a musl-based setup to test it out :(
Also I believe for the library it should be done through build.rs, not .cargo. But without a musl environment I can't really test it, so can't really tell how exactly it should look like.
tried this for macroquad:
build.rs:
fn main() {
let target = std::env::var("TARGET").unwrap();
if target.contains("musl") {
println!("cargo:rustc-link-lib=dylib=m");
println!("cargo:rustc-link-lib=dylib=c");
println!("cargo:rustc-cfg=feature=\"crt-static\"");
println!("cargo:rustc-env=RUSTFLAGS=-crt-static");
}
}
in a test project:
macroquad = { path="./macroquad" }
but when i tried using it in a project i got the 'Wayland backend failed' error again.
then i tried doing the same for miniquad too
build.rs:
use std::env;
fn main() {
let target = env::var("TARGET").unwrap_or_else(|e| panic!("{}", e));
if target.contains("darwin") || target.contains("ios") {
println!("cargo:rustc-link-lib=framework=MetalKit");
} else if target.contains("musl") {
println!("cargo:rustc-link-lib=dylib=m");
println!("cargo:rustc-link-lib=dylib=c");
println!("cargo:rustc-cfg=feature=\"crt-static\"");
println!("cargo:rustc-env=RUSTFLAGS=-crt-static");
}
}
modified a line in Cargo.toml for macroquad:
miniquad = { path = "../miniquad", features = ["log-impl"] }
but then again got the same error:
$ cargo run
Compiling miniquad v0.4.0-alpha.10 (/home/xdream8/files/proj/game-test/miniquad)
Compiling macroquad v0.4.4 (/home/xdream8/files/proj/game-test/macroquad)
Compiling game-test v0.1.0 (/home/xdream8/files/proj/game-test)
Finished dev [unoptimized + debuginfo] target(s) in 1.93s
Running `target/debug/game-test`
thread 'main' panicked at 'Wayland backend failed', /home/xdream8/files/proj/game-test/miniquad/src/lib.rs:256:54
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
i also removed the dependency for libc for linux part
code:
#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod linux {
use super::Error;
use std::{
ffi::{c_void, c_char, CString},
ptr::NonNull,
};
extern "C" {
fn dlopen(filename: *const c_char, flag: i32) -> *mut c_void;
fn dlclose(handle: *mut c_void) -> *mut c_void;
fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void;
}
pub struct Module(NonNull<c_void>);
impl Module {
pub fn load(path: &str) -> Result<Self, Error> {
let path = CString::new(path).unwrap();
let module = unsafe { dlopen(path.as_ptr(), 1 | 0) };
if module.is_null() {
Err(Error::DlOpenError)
} else {
Ok(Module(unsafe { NonNull::new_unchecked(module) }))
}
}
pub fn get_symbol<F: Sized>(&self, name: &str) -> Result<F, Error> {
let name = CString::new(name).unwrap();
let symbol = unsafe { dlsym(self.0.as_ptr(), name.as_ptr()) };
if symbol.is_null() {
return Err(Error::DlSymError);
}
Ok(unsafe { std::mem::transmute_copy::<_, F>(&symbol) })
}
}
impl Drop for Module {
fn drop(&mut self) {
unsafe { dlclose(self.0.as_ptr()) };
}
}
}
then i tried adding -crt-static
directly to RUSTFLAGS again and it worked fine
it seems that all crates must be linked dynamically. so the best we can do is add a notice/warning to README and let developers handle this.
i am open to any better ideas
if you want i can create a pr for removing libc dependency for linux and android but it should probably be tested for android first as android uses the same code too
distro: kiss linux(community maintained, uses a source based package manager and musl libc) macroquad version: 0.4.4 rust version: 1.72.1(installed using rustup)
code:
backtrace: