rust-windowing / rust-windowing/winit

Connecting/Disconnecting monitors can crash winit

Open
#3,102 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

B - crash DS - win32
Dominant language
Rust
Stars
6.2k
Forks
1.3k
Avg merge
2d 19h
Merged PRs (30d)
9

Description

I was writing a monitor control application (which can connect and disconnect monitors at runtime), and if you connect and disconnect monitors enough times, eventually winit will just up and crash (I'm using egui, and the window is ONLY on the main monitor which never gets disconnected).

This is reproducible, but can be very hard to cause since it's sporadic. Just keep connecting and disconnecting a secondary monitor a lot of times, eventually it'll crash. Sometimes I can't get it to, sometimes I can.

Note: This is on Windows 11. If any other info is needed, don't hesitate to ask.

I suspect that, here, the monitor is_some() when it asks, so it goes through and calls size()
eframe-0.22.0\src\native\epi_integration.rs:431

    let monitor = window.current_monitor().is_some();
    let monitor_size = if monitor {
        let size = window
            .current_monitor()
            .unwrap()
            .size()
            .to_logical::<f32>(pixels_per_point.into());
        Some(egui::vec2(size.width, size.height))
    } else {
        None
    };

Which goes into wininit, winit-0.28.6\src\platform_impl\windows\monitor.rs:186, and the monitor disappears within that short timeframe, so when get_monitor_info() is called, now it's gone

    #[inline]
    pub fn size(&self) -> PhysicalSize<u32> {
        let rc_monitor = get_monitor_info(self.0).unwrap().monitorInfo.rcMonitor;
        PhysicalSize {
            width: (rc_monitor.right - rc_monitor.left) as u32,
            height: (rc_monitor.bottom - rc_monitor.top) as u32,
        }
    }
Stacktrace
panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 1461, kind: Uncategorized, message: "Invalid monitor handle." }', C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\monitor.rs:186:51

stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\panicking.rs:593
   1: core::panicking::panic_fmt
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\core\src\panicking.rs:67
   2: core::result::unwrap_failed
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\core\src\result.rs:1651
   3: enum2$<core::result::Result<windows_sys::Windows::Win32::Graphics::Gdi::MONITORINFOEXW,std::io::error::Error> >::unwrap<windows_sys::Windows::Win32::Graphics::Gdi::MONITORINFOEXW,std::io::error::Error>
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\core\src\result.rs:1076
   4: winit::platform_impl::platform::monitor::MonitorHandle::size
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\monitor.rs:186
   5: winit::monitor::MonitorHandle::size
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\monitor.rs:130
   6: eframe::native::epi_integration::read_window_info
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\native\epi_integration.rs:43
   7: eframe::native::epi_integration::EpiIntegration::update
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\native\epi_integration.rs:494
   8: eframe::native::run::glow_integration::impl$2::run_ui_and_paint
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\native\run.rs:829
   9: eframe::native::run::run_and_return::closure$0<eframe::native::run::glow_integration::GlowWinitApp>
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\native\run.rs:148
  10: winit::platform_impl::platform::event_loop::impl$3::run_return::closure$0<enum2$<eframe::native::run::UserEvent>,eframe::native::run::run_and_return::closure_env$0<eframe::native::run::glow_integration::GlowWinitApp> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop.rs:260
  11: alloc::boxed::impl$48::call_mut<tuple$<enum2$<winit::event::Event<enum2$<eframe::native::run::UserEvent> > >,ref_mut$<enum2$<winit::event_loop::ControlFlow> > >,dyn$<core::ops::function::FnMut<tuple$<enum2$<winit::event::Event<enum2$<eframe::native::run::
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\alloc\src\boxed.rs:2000
  12: winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure$0<enum2$<eframe::native::run::UserEvent> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop\runner.rs:250
  13: core::panic::unwind_safe::impl$23::call_once<tuple$<>,winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure_env$0<enum2$<eframe::native::run::UserEvent> > >
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\core\src\panic\unwind_safe.rs:271
  14: std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure_env$0<enum2$<eframe::native::run::UserEvent> > >,tuple$<> >
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\std\src\panicking.rs:500
  15: eframe::epi::backend::impl$2::default
  16: std::panicking::try<tuple$<>,core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure_env$0<enum2$<eframe::native::run::UserEvent> > > >
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\std\src\panicking.rs:464
  17: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::closure_env$0<enum2$<eframe::native::run::UserEvent> > >,tuple$<> >
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\std\src\panic.rs:142
  18: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<enum2$<eframe::native::run::UserEvent> >::catch_unwind<enum2$<eframe::native::run::UserEvent>,tuple$<>,winit::platform_impl::platform::event_loop::runner::impl$3::call_event_handler::clos
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop\runner.rs:157
  19: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<enum2$<eframe::native::run::UserEvent> >::call_event_handler<enum2$<eframe::native::run::UserEvent> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop\runner.rs:242
  20: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<enum2$<eframe::native::run::UserEvent> >::call_redraw_events_cleared<enum2$<eframe::native::run::UserEvent> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop\runner.rs:409
  21: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<enum2$<eframe::native::run::UserEvent> >::move_state_to<enum2$<eframe::native::run::UserEvent> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop\runner.rs:358
  22: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<enum2$<eframe::native::run::UserEvent> >::redraw_events_cleared<enum2$<eframe::native::run::UserEvent> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop\runner.rs:234
  23: winit::platform_impl::platform::event_loop::thread_event_target_callback::closure$0<enum2$<eframe::native::run::UserEvent> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop.rs:2371
  24: core::ops::function::FnOnce::call_once<winit::platform_impl::platform::event_loop::thread_event_target_callback::closure_env$0<enum2$<eframe::native::run::UserEvent> >,tuple$<> >
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\core\src\ops\function.rs:250
  25: core::panic::unwind_safe::impl$23::call_once<isize,winit::platform_impl::platform::event_loop::thread_event_target_callback::closure_env$0<enum2$<eframe::native::run::UserEvent> > >
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\core\src\panic\unwind_safe.rs:271
  26: std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::thread_event_target_callback::closure_env$0<enum2$<eframe::native::run::UserEvent> > >,isize>
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\std\src\panicking.rs:500
  27: eframe::epi::backend::impl$2::default
  28: std::panicking::try<isize,core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::thread_event_target_callback::closure_env$0<enum2$<eframe::native::run::UserEvent> > > >
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\std\src\panicking.rs:464
  29: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::thread_event_target_callback::closure_env$0<enum2$<eframe::native::run::UserEvent> > >,isize>
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\std\src\panic.rs:142
  30: winit::platform_impl::platform::event_loop::runner::EventLoopRunner<enum2$<eframe::native::run::UserEvent> >::catch_unwind<enum2$<eframe::native::run::UserEvent>,isize,winit::platform_impl::platform::event_loop::thread_event_target_callback::closure_env$0
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop\runner.rs:157
  31: winit::platform_impl::platform::event_loop::thread_event_target_callback<enum2$<eframe::native::run::UserEvent> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop.rs:2547
  32: DispatchMessageW
  33: DispatchMessageW
  34: GetClassLongW
  35: KiUserCallbackDispatcher
  36: NtUserDispatchMessage
  37: DispatchMessageW
  38: winit::platform_impl::platform::event_loop::EventLoop<enum2$<eframe::native::run::UserEvent> >::run_return<enum2$<eframe::native::run::UserEvent>,eframe::native::run::run_and_return::closure_env$0<eframe::native::run::glow_integration::GlowWinitApp> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform_impl\windows\event_loop.rs:282
  39: winit::platform::run_return::impl$0::run_return<enum2$<eframe::native::run::UserEvent>,eframe::native::run::run_and_return::closure_env$0<eframe::native::run::glow_integration::GlowWinitApp> >
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.28.6\src\platform\run_return.rs:51
  40: eframe::native::run::run_and_return<eframe::native::run::glow_integration::GlowWinitApp>
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\native\run.rs:132
  41: eframe::native::run::glow_integration::run_glow::closure$0
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\native\run.rs:1043
  42: eframe::native::run::with_event_loop::closure$0<enum2$<core::result::Result<tuple$<>,enum2$<eframe::Error> > >,eframe::native::run::glow_integration::run_glow::closure_env$0>
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\native\run.rs:116
  43: std::thread::local::LocalKey<core::cell::RefCell<enum2$<core::option::Option<winit::event_loop::EventLoop<enum2$<eframe::native::run::UserEvent> > > > > >::try_with<core::cell::RefCell<enum2$<core::option::Option<winit::event_loop::EventLoop<enum2$<eframe
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\std\src\thread\local.rs:270
  44: std::thread::local::LocalKey<core::cell::RefCell<enum2$<core::option::Option<winit::event_loop::EventLoop<enum2$<eframe::native::run::UserEvent> > > > > >::with<core::cell::RefCell<enum2$<core::option::Option<winit::event_loop::EventLoop<enum2$<eframe::na
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\std\src\thread\local.rs:246
  45: eframe::native::run::with_event_loop<enum2$<core::result::Result<tuple$<>,enum2$<eframe::Error> > >,eframe::native::run::glow_integration::run_glow::closure_env$0>
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\native\run.rs:109
  46: eframe::native::run::glow_integration::run_glow
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\native\run.rs:1040
  47: eframe::run_native
             at C:\Users\<user>\.cargo\registry\src\index.crates.io-6f17d22bba15001f\eframe-0.22.0\src\lib.rs:220

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with platform_impl/windows/monitor.rs at MonitorHandle::size, especially the get_monitor_info call at line 186, and compare it with the reported eframe epi_integration.rs call site. Reproduce by repeatedly connecting and disconnecting a secondary monitor on Windows 11. Done means the invalid monitor handle no longer causes the reported panic during this sequence.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
desktop, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.