HiddenExceptionHandler calling DispatchMessage

delphi package - automated exception handling
Post Reply
feldbaumer
Posts: 4
Joined: Tue Mar 27, 2012 6:08 pm

HiddenExceptionHandler calling DispatchMessage

Post by feldbaumer »

Hello,

I've a small problem using a custom HiddenExceptionHandler - basically everything works absolutely fine, however HandleException (in madExcept.pas) pumps the MessageLoop while processing the exception-handler.
My exception-handler is absolutely silent (just writing the bugreport.txt) and these calls to TranslateMessage/DispatchMessage sometimes mess up the flow of our program... (because messages meant to be handled _after_ the exception suddendly get handled "in between")?

So my question: is there any option to change this behaviour? We have no problem with accepting the delays coming from the "extended" exception-handler, but we can't live with "random" AVs. I already tried to always set hep.event to 0 (in HandleException) and it seems to work, however it's not clear to me if this might have any negative side-effects?

best regards,
Peter
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: HiddenExceptionHandler calling DispatchMessage

Post by madshi »

Hmmmmm... The problem for madExcept is that it just doesn't know how long exception handling will take. It is possible that it ends up in a dialog which would mean that the main thread would be stuck "forever", until the end user manually closes the dialog. Because of that I'm handling messages while waiting for exception handling to complete.

I understand that it can make problems. Do you have any suggestions/ideas on how to solve this? One thought I just had is that I could wait without handling messages for e.g. 1 second. And if exception handling takes longer, I'd start handling messages. I could also offer a (runtime) option to modify this behaviour. What do you think?
feldbaumer
Posts: 4
Joined: Tue Mar 27, 2012 6:08 pm

Re: HiddenExceptionHandler calling DispatchMessage

Post by feldbaumer »

I do not completely understand the reasoning behind "continuing" the program at all?
If there is an exception, why should the program (which actually is just meant to be in exactly the except-end section) continue? This could have all kind of weird effects (also in a case where there actually is a madexcept-dialog open, and the user takes its time to act on it).
My opinion is, that basically everything should "stop" as long as its not clear what the user intends to do. In my case its even easier - all the handling is completely silent (we're talking about a service-app here) - and the only thing happening is writing a bugreport-entry.

I just had a second look at the source-code and I think that every exception should
.) either be handled like an exception in a "secondary" thread (if GetCurrentThreadId = MainThreadId then begin... in line 10101)
.) or like if the process is detected as stuck (line 10095)
I don't know which one is better/ where the difference is at all?

It isn't completely clear for me in the first place why exceptions in the main-thread are treated differently than exceptions in any other thread (other than keeping the main/original UI responsive, but this in itself is an error as far as I can see; because either the app is in the except-handling block or it is continuing "normally", having an additional dialog open, showing some (exception)-info).

As far as I'm concerned I'd simply like to have some global variable/setting (should be runtime configurable), that can set the behaviour - maybe 3 states:
1) like now (backward compatibilty)
2) completely blocking (calling ReceiveHandleException directly or WaitForSingleObject(hep.event, INFINITE);)
3) completely asynchronous (if its possible at all)

My immediate question however is: can I - for my intended behaviour in my service-app - remove the GetCurrentThreadId = MainThreadId check safely (therefore calling WaitForSingleObject(hep.event, INFINITE) also in the main-thread instead of pumping messages) without causing unwanted problems?
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: HiddenExceptionHandler calling DispatchMessage

Post by madshi »

feldbaumer wrote:I do not completely understand the reasoning behind "continuing" the program at all?
If there is an exception, why should the program (which actually is just meant to be in exactly the except-end section) continue? This could have all kind of weird effects (also in a case where there actually is a madexcept-dialog open, and the user takes its time to act on it).
Without message handling in the main thread, all GUI would be completely frozen. That would look very bad to the user. E.g. if you move the madExcept exception dialog with the mouse, the VCL windows in the background would not redraw, leaving traces of the exception dialog all over the screen.

Not all exceptions are critical. Sometimes an exception can be as simple as "The file could not be opened". Having the whole GUI completely frozen (without even repainting itself) just because there's an innocent exception somewhere isn't a good user experience. Of course if there's really something critical going on, having the GUI frozen might make sense, but it's not really possible for madExcept to know which exceptions are critical and which are not.

There's an option in the madExcept settings dialog which allows you to pause/suspend all threads while exception handling is active. That should pretty much do what you want, at the cost of a non-responding and non-redrawing VCL GUI. However, the threads are paused by the secondary exception handling thread. So there might still be a few microseconds in which the main thread handles messages in the madExcept Translate/DispatchMessage loop. Probably I should fix that, so that when the "pause all running threads" option is activated, the main thread doesn't enter that message loop at all.
feldbaumer wrote:It isn't completely clear for me in the first place why exceptions in the main-thread are treated differently than exceptions in any other thread
Secondary threads usually don't need message handling. The main thread does, in most cases, cause the VCL is running in the main thread.
feldbaumer wrote:As far as I'm concerned I'd simply like to have some global variable/setting (should be runtime configurable), that can set the behaviour - maybe 3 states:
1) like now (backward compatibilty)
2) completely blocking (calling ReceiveHandleException directly or WaitForSingleObject(hep.event, INFINITE);)
3) completely asynchronous (if its possible at all)
Option 1) is no problem, haha. Option 2) I should be able to offer by slightly modifying the way the "pause all running threads" option works (skipping the message handling in the main thread with that option activated). Not sure what you mean exactly with option 3).
feldbaumer wrote:My immediate question however is: can I - for my intended behaviour in my service-app - remove the GetCurrentThreadId = MainThreadId check safely (therefore calling WaitForSingleObject(hep.event, INFINITE) also in the main-thread instead of pumping messages) without causing unwanted problems?
Yes.
feldbaumer
Posts: 4
Joined: Tue Mar 27, 2012 6:08 pm

Re: HiddenExceptionHandler calling DispatchMessage

Post by feldbaumer »

madshi wrote:Without message handling in the main thread, all GUI would be completely frozen. That would look very bad to the user. E.g. if you move the madExcept exception dialog with the mouse, the VCL windows in the background would not redraw, leaving traces of the exception dialog all over the screen.
I understand the behaviour concerning the "frozen" look, however from Vista onwards I think the OS handles this situation (ghosting)?
madshi wrote: There's an option in the madExcept settings dialog which allows you to pause/suspend all threads while exception handling is active. That should pretty much do what you want, at the cost of a non-responding and non-redrawing VCL GUI. However, the threads are paused by the secondary exception handling thread. So there might still be a few microseconds in which the main thread handles messages in the madExcept Translate/DispatchMessage loop. Probably I should fix that, so that when the "pause all running threads" option is activated, the main thread doesn't enter that message loop at all.
I saw that option, but as you wrote it doesn't completely 100% disable message-handling (even if it's only for a very short period).
In my case Winsock-messages keep coming in and there's no chance for me to stop that - so messages get handled that shouldn't be, because e.g. the exception closes the socket.

madshi wrote:
feldbaumer wrote:...3) completely asynchronous (if its possible at all)
Not sure what you mean exactly with option 3).
I was thinking of something like posted message - the exception handler finishes completely (without any actions/ui happening) but posts a message to the main-ui thread, and only when the message-loop gets pumped again (by the "original" app) the madexcept-UI gets shown (or all that happens in a seperate thread parallel to the original program continuing its operation - but that might have issues regarding vcl-controls/ the madexcept ui in a secondary thread).
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: HiddenExceptionHandler calling DispatchMessage

Post by madshi »

This should now be fixed in the latest madExcept 3 build. And in madExcept 4, of course.

http://madshi.net/madCollection.exe (installer version 2.7.0.0)
Post Reply