#![windows_subsystem = "windows"] and panics

I'm normally developing for Unix-like platforms only, but working on a Windows program now. In order to suppress a console window opening, I use #![windows_subsystem = "windows"] in my main.rs.

However, this has the side-effect that panics aren't reported in any way. What's the idiomatic way to deal with this? Or are they already reported somewhere and logged? If yes, where to find the panic reports?

If you have a log backend configured already, you can easily integrate log-panics to have panics routed to your log backend.

Some GUI apps may want to be able to report an error to the user as well, in which case you'll probably need to use set_hook directly to set a panic hook that handles notifying the UI of a panic somehow.

3 Likes

I guess I can make this hook just open a window then? Maybe using windows::Win32::UI::WindowsAndMessaging::MessageBoxW (see also MessageBoxW in Win32 docs). So I take there is no "default" way to do this in std or a commonly used crate?


For some reason I'm a bit anxious to do anything during a panic, as this (potentially) indicates a serious bug. But I guess it's okay to do things in the panic handler. Maybe I just need to take care what I do, depending on what other parts of the program have already done.

Yes, that is what it's there for :slight_smile:. The usual thing is to display a brief error to the user but write as much error information as possible to a file.

The only thing to think about in a panic hook is panicking again, but that'll just abort the process so it can't make things any worse. You can also use catch_unwind in main to wrap your whole program in a catch block.

A problem I see here is that if I open a message box (using MessageBoxW), then the thread will block while the program is yet running. This could lead to the program being reported as "does not respond", right? (edit: I don't think this is the case because unsafe extern "system" fn window_proc could still be called even if my main loop panics.) Maybe redraw-routines will hang as well? I wonder if there's any better options?

I was thinking on that too, but that means the stack is already unwound by the time I catch it, so I have no information about where the panic happened, right? The advantage would be that the unwinding (hopefully) closed all windows of the application. But in order to get the location of the panic, I would need to install a custom panic handler anyway.

Overall this seems to be a lot of work. I wished there was some easier solution. (Or maybe it's not a problem to let a Windows program hang for a while during a panic? Or is there a way to open a message window in a non-blocking way while I can let the program terminate by returning from the panic hook instantly?)

I would probably use the panic handler to grab a backtrace and any other info I needed, put it in a static or something, and then use catch_unwind somewhere in main to detect that a panic occurred and display something to the user, personally.

I recall MessageBox having its own message pump which means your program will appear to be responsive.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.