Open Toyz opened 8 months ago
Thanks for posting a bug.
I tried to reproduce, but I cannot reproduce the problem.
Note that your code doesn't compile (missing comas and semicolon), but even when i add that and put the combobox next to each other, it works as expected.
Is there a backtrace available?
What exactly is crashing? Is it when running your program or when building, or the preview?
Here is a backtrace from the program that is triggering it (sadly i can't share this projects code and wildly enough I can't reproduce it in my own example code for some odd reason)
* thread #1, name = 'main', stop reason = Exception 0xc00000fd encountered at address 0x7ff73506a227: Stack overflow
* frame #0: 0x00007ff73506a227 test_project_code.exe`__chkstk() at chkstk.asm:109
frame #1: 0x00007ff7344c094b test_project_code.exe`test_project_code::slint_generatedMainWindow::InnerMainWindow::init(root=<unavailable>, tree_index=<unavailable>, tree_index_of_first_child=<unavailable>) at main.rs:3843
frame #2: 0x00007ff7345c7237 test_project_code.exe`test_project_code::slint_generatedMainWindow::InnerMainWindow::new() at main.rs:49192
frame #3: 0x00007ff7345c7c1c test_project_code.exe`test_project_code::slint_generatedMainWindow::MainWindow::new() at main.rs:50582
frame #4: 0x00007ff73435f9ab test_project_code.exe`test_project_code::main() at main.rs:44
frame #5: 0x00007ff7344185db test_project_code.exe`core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >(=0x00007ff73435f5e0) at function.rs:250
frame #6: 0x00007ff7344a8cee test_project_code.exe`std::sys_common::backtrace::__rust_begin_short_backtrace<void (*)(),tuple$<> >(*mut ) [inlined] core::hint::black_box(tuple$<>) at hint.rs:286
frame #7: 0x00007ff73433dea1 test_project_code.exe`std::rt::lang_start::closure$0<tuple$<> >(*mut std::rt::lang_start::closure_env$0<tuple$<> >) at rt.rs:166
frame #8: 0x00007ff73501e478 test_project_code.exe`std::rt::lang_start_internal() [inlined] std::rt::lang_start_internal::closure$2() at rt.rs:148
frame #9: 0x00007ff73501e46d test_project_code.exe`std::rt::lang_start_internal() [inlined] std::panicking::try::do_call() at panicking.rs:504
frame #10: 0x00007ff73501e46d test_project_code.exe`std::rt::lang_start_internal() [inlined] std::panicking::try() at panicking.rs:468
frame #11: 0x00007ff73501e46d test_project_code.exe`std::rt::lang_start_internal() [inlined] std::panic::catch_unwind() at panic.rs:142
frame #12: 0x00007ff73501e46d test_project_code.exe`std::rt::lang_start_internal() at rt.rs:148
frame #13: 0x00007ff73433de7a test_project_code.exe`std::rt::lang_start<tuple$<> >(main=0x00007ff73435f5e0, argc=1, argv=0x00000236d5a89800, sigpipe=0) at rt.rs:165
frame #14: 0x00007ff734360aa9 test_project_code.exe`main + 25
frame #15: 0x00007ff73506a430 test_project_code.exe`__scrt_common_main_seh() [inlined] invoke_main() at exe_common.inl:78
frame #16: 0x00007ff73506a40e test_project_code.exe`__scrt_common_main_seh() at exe_common.inl:288
frame #17: 0x00007ff84d6e257d kernel32.dll
frame #18: 0x00007ff84f0eaa58 ntdll.dll
thread #2, name = 'ntdll.dll thread'
frame #0: 0x00007ff84f132fc4 ntdll.dll
frame #1: 0x00007ff84f0c537e ntdll.dll
frame #2: 0x00007ff84d6e257d kernel32.dll
frame #3: 0x00007ff84f0eaa58 ntdll.dll
thread #3, name = 'ntdll.dll thread'
frame #0: 0x00007ff84f132fc4 ntdll.dll
frame #1: 0x00007ff84f0c537e ntdll.dll
frame #2: 0x00007ff84d6e257d kernel32.dll
frame #3: 0x00007ff84f0eaa58 ntdll.dll
thread #4, name = 'ntdll.dll thread'
frame #0: 0x00007ff84f132fc4 ntdll.dll
frame #1: 0x00007ff84f0c537e ntdll.dll
frame #2: 0x00007ff84d6e257d kernel32.dll
frame #3: 0x00007ff84f0eaa58 ntdll.dll
thread #5, name = 'test_project_code.exe!std::sys::windows::thread::impl$0::new::thread_start()'
frame #0: 0x00007ff84f132f64 ntdll.dll
frame #1: 0x00007ff84f0c39d5 ntdll.dll
frame #2: 0x00007ff84f0df9cc ntdll.dll
frame #3: 0x00007ff84f0dba93 ntdll.dll
frame #4: 0x00007ff84ca92df3 KernelBase.dll
frame #5: 0x00007ff73501ee5e test_project_code.exe`std::thread::park_timeout() [inlined] std::sys::windows::thread_parking::Parker::park_timeout() at thread_parking.rs:149
frame #6: 0x00007ff73501edf7 test_project_code.exe`std::thread::park_timeout() at mod.rs:1135
frame #7: 0x00007ff734fd9edb test_project_code.exe`std::sync::mpmc::context::Context::wait_until(self=0x000000f0566fe820) at context.rs:130
frame #8: 0x00007ff734fe15f0 test_project_code.exe`std::sync::mpmc::list::impl$3::recv::closure$1<enum2$<log2::Action> >(cx=0x000000f0566fe820) at list.rs:444
frame #9: 0x00007ff734fdad0c test_project_code.exe`std::sync::mpmc::context::impl$0::with::closure$0<std::sync::mpmc::list::impl$3::recv::closure_env$1<enum2$<log2::Action> >,tuple$<> >(cx=0x000000f0566fe820) at context.rs:50
frame #10: 0x00007ff734fdb0b6 test_project_code.exe`std::sync::mpmc::context::impl$0::with::closure$1<std::sync::mpmc::list::impl$3::recv::closure_env$1<enum2$<log2::Action> >,tuple$<> >(cell=0x00000236d5aae5c8) at context.rs:58
frame #11: 0x00007ff734fdb8c3 test_project_code.exe`std::thread::local::LocalKey<core::cell::Cell<enum2$<core::option::Option<std::sync::mpmc::context::Context> > > >::try_with<core::cell::Cell<enum2$<core::option::Option<std::sync::mpmc::context::Context> > >,std::sync::mpmc::context::impl$0::with::closure_env$1<std::sync::mpmc::list::impl$3::recv::closure_env$1<enum2$<log2::Action> >,tuple$<> >,tuple$<> >(self=0x00007ff735190998, f=std::sync::mpmc::context::impl$0::with::closure_env$1<std::sync::mpmc::list::impl$3::recv::closure_env$1<enum2$<log2::Action> >,tuple$<> > @ 0x000000f0566fe8f8) at local.rs:270
frame #12: 0x00007ff734fd9f71 test_project_code.exe`std::sync::mpmc::context::Context::with<std::sync::mpmc::list::impl$3::recv::closure_env$1<enum2$<log2::Action> >,tuple$<> >(f=std::sync::mpmc::list::impl$3::recv::closure_env$1<enum2$<log2::Action> > @ 0x000000f0566fe960) at context.rs:53
frame #13: 0x00007ff734fe1478 test_project_code.exe`std::sync::mpmc::list::Channel<enum2$<log2::Action> >::recv<enum2$<log2::Action> >(self=0x00000236d5a90100) at list.rs:434
frame #14: 0x00007ff734fd6b28 test_project_code.exe`std::sync::mpmc::Receiver<enum2$<log2::Action> >::recv_deadline<enum2$<log2::Action> >(self=0x000000f0566ff300) at mod.rs:340
frame #15: 0x00007ff734fd6a57 test_project_code.exe`std::sync::mpmc::Receiver<enum2$<log2::Action> >::recv_timeout<enum2$<log2::Action> >(self=0x000000f0566ff300) at mod.rs:323
frame #16: 0x00007ff734fd6dd0 test_project_code.exe`std::sync::mpsc::Receiver<enum2$<log2::Action> >::recv_timeout<enum2$<log2::Action> >(self=0x000000f0566ff300) at mod.rs:909
frame #17: 0x00007ff734fd4d48 test_project_code.exe`log2::worker(ctx=0x00000000566ff300) at lib.rs:360
frame #18: 0x00007ff734fd5da7 test_project_code.exe`log2::start_log2::closure$0(log2::start_log2::closure_env$0) at lib.rs:456
frame #19: 0x00007ff734fd94f9 test_project_code.exe`std::sys_common::backtrace::__rust_begin_short_backtrace<log2::start_log2::closure_env$0,tuple$<> >(log2::start_log2::closure_env$0) [inlined] core::hint::black_box(tuple$<>) at hint.rs:286
frame #20: 0x00007ff734fd7e71 test_project_code.exe`std::thread::impl$0::spawn_unchecked_::closure$1::closure$0<log2::start_log2::closure_env$0,tuple$<> >(std::thread::impl$0::spawn_unchecked_::closure$1::closure_env$0<log2::start_log2::closure_env$0,tuple$<> >) at mod.rs:529
frame #21: 0x00007ff734fd0d01 test_project_code.exe`core::panic::unwind_safe::impl$23::call_once<tuple$<>,std::thread::impl$0::spawn_unchecked_::closure$1::closure_env$0<log2::start_log2::closure_env$0,tuple$<> > >(self=<unavailable>, =tuple$<> @ 0x000000f0566ff47f) at unwind_safe.rs:271
frame #22: 0x00007ff734fdcd6b test_project_code.exe`std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked_::closure$1::closure_env$0<log2::start_log2::closure_env$0,tuple$<> > >,tuple$<> >(data=0x000000f0566ff5c0) at panicking.rs:504
frame #23: 0x00007ff734fdf893 test_project_code.exe
frame #24: 0x00007ff734fdcc04 test_project_code.exe`std::panicking::try<tuple$<>,core::panic::unwind_safe::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked_::closure$1::closure_env$0<log2::start_log2::closure_env$0,tuple$<> > > >(f=<unavailable>) at panicking.rs:468
frame #25: 0x00007ff734fd7cb3 test_project_code.exe`std::thread::impl$0::spawn_unchecked_::closure$1<log2::start_log2::closure_env$0,tuple$<> >(std::thread::impl$0::spawn_unchecked_::closure_env$1<log2::start_log2::closure_env$0,tuple$<> >) [inlined] std::panic::catch_unwind(f=core::panic::unwind_safe::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked_::closure$1::closure_env$0<log2::start_log2::closure_env$0,tuple$<> > > @ 0x000000f0566ff750) at panic.rs:142
frame #26: 0x00007ff734fd7caa test_project_code.exe`std::thread::impl$0::spawn_unchecked_::closure$1<log2::start_log2::closure_env$0,tuple$<> >(std::thread::impl$0::spawn_unchecked_::closure_env$1<log2::start_log2::closure_env$0,tuple$<> >) at mod.rs:528
frame #27: 0x00007ff734fcb08e test_project_code.exe`core::ops::function::FnOnce::call_once<std::thread::impl$0::spawn_unchecked_::closure_env$1<log2::start_log2::closure_env$0,tuple$<> >,tuple$<> >(=0x00000236d5aad710) at function.rs:250
frame #28: 0x00007ff73502ec5c test_project_code.exe`std::sys::windows::thread::impl$0::new::thread_start() at thread.rs:57
frame #29: 0x00007ff84d6e257d kernel32.dll
frame #30: 0x00007ff84f0eaa58 ntdll.dll
But the exact line it's being triggered at is the following.
let win = MainWindow::new().expect("MainWindow::new() failed");
Above this line is just HIDAPI calls which are all returning fine as they are debug logging the actual result(s) I have been working with.
My guess is this looks to be when it is walking the tree on run it might be triggering it, this project has 4 files total 3 of which extend a gridlayout and 1 which is the main.slint. From there the main tab in the tab layout when it wasn't in native contained 1 Combobox and then another tab contained another combobox the stack overflow occures.
Each page also exports a "Global" they control that page's state for communication back to the rust code as a struct bound as an in-out
Other information as well:
Cargo Version: cargo 1.76.0 (c84b36747 2024-01-18)
Windows Version: Microsoft Windows [Version 10.0.22635.2921] (Windows 11)
Is there a difference between debug mode and release mode? We had this bug before in which trying to allocate big structure on the heap would first do a few copies on the stack that would cause a stack overflow: https://github.com/slint-ui/slint/issues/133 Is that a regresion from previous version of Slint or of Rust?
Sorry for the late reply on this.
Just verified that this is only happening in DEBUG
build. RELEASE
builds work just fine
https://github.com/slint-ui/slint/pull/5415 fixes a stack overflow, but that's not really fitting with the backtrace
The default stack size on Windows is IIRC 1MB (see https://learn.microsoft.com/en-us/cpp/build/reference/stack-stack-allocations?view=msvc-170 ). I'm not sure there's much that we can do here. Ideas:
Any other ideas what we could do?
I now use the following code in my build.rs
:
// Increase stack size to prevent Slint issue <https://github.com/slint-ui/slint/issues/6299>.
const STACK_SIZE_MIB_DEBUG: f64 = 2.;
const STACK_SIZE_MIB_RELEASE: f64 = 1.;
//i 1 MB is MSVC's default (as of Visual Studio 2022): <https://learn.microsoft.com/en-us/cpp/build/reference/stack-stack-allocations>.
print!("cargo::rustc-link-arg=");
match env::var("TARGET").unwrap().as_str() {
"x86_64-pc-windows-msvc" => print!("/STACK:"),
"x86_64-pc-windows-gnu" => print!("-Wl,--stack,"),
//i Source: <https://users.rust-lang.org/t/stack-overflow-when-compiling-on-windows-10/50818/8>.
_ => panic!("unexpected target"),
}
let stack_size_bytes = (match env::var("PROFILE").unwrap().as_str() {
"debug" => STACK_SIZE_MIB_DEBUG,
"release" => STACK_SIZE_MIB_RELEASE,
_ => panic!("unexpected profile"),
} * 1024f64.powi(2))
.round() as u64;
println!("{stack_size_bytes}");
Can that it bad, though, to just increase the stack when building for mobile (currently only Android), because resources are more limited?
In times where mobile phones measure ram in gigabytes I'm less concerned about 1-5 MB.
Any other ideas what we could do?
unsafe
code that doesn't put the component on the stack first.Among those (docs, templates, above bullet points), what's your preference?
When using Slint bindings for rust with the Slint builder, you will cause a
STATUS_STACK_OVERFLOW
when you have more than 1 combo box within the project.main.slint
build.rs
main.rs
When running this on the latest (1.4.1 and including main) it will trigger a stack overflow on windows.
--- Notes ---
When using
native
styles the combo boxes work fine and don't trigger a panic