madExcept dialog not showing up on one computer

delphi package - automated exception handling
Post Reply
obones
Posts: 66
Joined: Fri May 15, 2009 11:47 am

madExcept dialog not showing up on one computer

Post by obones »

Hello,

I have madExcept setup to show its dialog when an unhandled exception is raised and it works fine on most computers.
However, I have one user for which the dialog never shows up and the application continues automatically despite using the same exe file as others.
I looked in the source code but I could not find any RegReadStr call that would read an option to do that from the registry.
So I'm wondering what may cause this strange behavior on that particular computer.

Thanks a lot for any suggestion.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: madExcept dialog not showing up on one computer

Post by madshi »

Sorry for the late reply.

Hmmmm... I'm not sure why this happens. Haven't ever heard of this specific problem yet. Does the exception box not even show up if you raise a simple test exception in a main form button click event? What happens if you try with a brand new almost empty test project? Same problem there?

For me the key problem is that this will be hard to fix without being able to reproduce it somehow... :(
obones
Posts: 66
Joined: Fri May 15, 2009 11:47 am

Re: madExcept dialog not showing up on one computer

Post by obones »

No worries, I'm lost on this one as well.
I was asking if there was a "secret" configuration somewhere that would trigger this, but if there is none, then it must be something we are doing.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: madExcept dialog not showing up on one computer

Post by madshi »

There are settings to hide the dialog, but you have to intentionally enable them, and if you do, they should have the same effect on all PCs. So I've no explanation for this phenomenon right now.
obones
Posts: 66
Joined: Fri May 15, 2009 11:47 am

Re: madExcept dialog not showing up on one computer

Post by obones »

Ok, I now have more details on what triggers this behavior and it gets weirder.
So, we have application A that can be started directly via a double click on its exe. This application has madExcept embedded and if an exception is raised, then the dialog shows up.
Now, we also have the Launcher application that also has madExcept activated can start other applications, one of which being application A.

If we start A via the launcher, then, we do not get any bugreport window when an exception is raised. In one machine, the application continues but cannot be closed properly, it needs to be killed. On another computer, the application appears to be frozen.

Both the Launcher and application A keep a named pipe opened to communicate while they live.

Does this help find an explanation for this behavior ?
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: madExcept dialog not showing up on one computer

Post by madshi »

How does the launcher start "application A" exactly? And does it change anything if you disable the named pipe communication? Finally, does the launcher run under a different user account?
obones
Posts: 66
Joined: Fri May 15, 2009 11:47 am

Re: madExcept dialog not showing up on one computer

Post by obones »

madshi wrote:How does the launcher start "application A" exactly?
Via JclSysUtils.Execute which ultimately calls CreateProcess
madshi wrote:And does it change anything if you disable the named pipe communication?
This requires a bit of work, so I have not tested it just yet as I have explored other things
madshi wrote:Finally, does the launcher run under a different user account?
No, all in the same session, no elevation whatsoever

As I investigated this, I discovered that the application does not close properly because message are no longer handled by the main message loop but by the one inside HandleException. And this loop will only exit if an event is set by the HandleExceptionThread method. However, in the "Launcher" case this method never reaches SetEvent and this comes from the fact that the exception window is not closed yet.
I tracked things a bit further and ended up checking the LastError value after various calls inside TExceptionBox.Create and found that the first ShowWindow call fails by setting LastError to 50, ERROR_NOT_SUPPORTED

I'll try to remove the named pipe, or change the way CreateProcess is called to see if this has an impact on the ShowWindow call
obones
Posts: 66
Joined: Fri May 15, 2009 11:47 am

Re: madExcept dialog not showing up on one computer

Post by obones »

Ok, I have found the source of the issue, by changing options that were given to CreateProcess, but it revealed an issue that comes from a weird behavior of the ShowWindow API.
Indeed, that API ignores its parameter the first time it is called, if a default value was given to the CreateProcess call that started the process. This is clearly documented in the MSDN, but I had no idea that this existed.
So, when the application is started via the Launcher, it has a default visibility value set to SW_HIDE, which means that the call ShowWindow(FMainWnd, SW_SHOWNORMAL) inside TExceptionBox.Create is interpreted as ShowWindow(FMainWnd, SW_HIDE)
What's really weird is that the MSDN documentation says the parameter is ignored "the first time ShowWindow is called by an application", but the VCL calls ShowWindow before on various other windows and yet, I still see the documented behavior.

So, in the end, I have multiple solutions :
  1. Use my own code that calls CreateProcess without the SW_HIDE parameter in startup info
  2. Modify the JCL code so that one can control what value gets set in the startup info for CreateProcess
  3. Call ShowWindow with a dummy value in my own code on the madExcept assistant window via the OnExceptBoxCreate callback
  4. Wait for a madExcept version which calls SetWindowPos instead of ShowWindow
I'll implement point 2 as it might be of use for other people, but for a quick fix, I have implemented point 3 like this:

Code: Select all

procedure OnExceptBoxCreate(exceptBox: HWND; simpleMsgBox: boolean);
begin
  // Workaround a "feature" of ShowWindow that ignores its parameter the first time it is called
  ShowWindow(exceptBox, SW_SHOWDEFAULT);
end;
However, as madExcept cannot know if the process it is running into has been called with the appropriate flags for CreateProcess, nor can it force its user to use the above workaround, I believe it should change its code to call SetWindowPos instead of ShowWindow, like this:

Code: Select all

SetWindowPos(FMainWnd, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_SHOWWINDOW);
I have tested it here, it works just fine in all cases.
What's even weirder with the ShowWindow API is that it ignores its parameter on first call only if its related to visibility, but not when passing WS_RESTORE or WS_MINIMIZE which means the code right after it that tests if the window is minimized will appropriately restore the window.

Thanks for the suggestions along the way that helped me pinpoint the source of all this.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: madExcept dialog not showing up on one computer

Post by madshi »

Congrats on finding the issue! :D

Calling CreateProcess with a forced SW_HIDE is seriously evil, it should be considered a serious bug. I'd suggest that you either call CreateProcess yourself (it's easy enough) or modify the JCL code.

I could change the ShowWindow call, but honestly, the original purpose of SetWindowPos is to change the window position (as the name of the API shows). Although a specific combination of flags allows SetWindowPos to be "misused" as a ShowWindow alternative, I think it's better coding style to use the appropriate API for the intended purpose, which is clearly ShowWindow. In all my years of madExcept, you're the only user to run into this problem. I can only guess that nobody else uses JCL for creating processes, or maybe there are other reasons that other users don't seem to be affected.
obones
Posts: 66
Joined: Fri May 15, 2009 11:47 am

Re: madExcept dialog not showing up on one computer

Post by obones »

madshi wrote:Calling CreateProcess with a forced SW_HIDE is seriously evil, it should be considered a serious bug. I'd suggest that you either call CreateProcess yourself (it's easy enough) or modify the JCL code.
Yes, I know that, but it's been like that for a least 15 years, so I won't change the default. That being said, the commit I just did allows to change that behavior if need be.
madshi wrote:I could change the ShowWindow call, but honestly, the original purpose of SetWindowPos is to change the window position (as the name of the API shows). Although a specific combination of flags allows SetWindowPos to be "misused" as a ShowWindow alternative, I think it's better coding style to use the appropriate API for the intended purpose, which is clearly ShowWindow.
Well, I looked at the VCL code to see where ShowWindow is called, and clearly, it is not called when the visibility of a form is to be changed, but SetWindowPos is instead:

Code: Select all

procedure TWinControl.CMShowingChanged(var Message: TMessage);
const
  ShowFlags: array[Boolean] of Word = (
    SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_HIDEWINDOW,
    SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_SHOWWINDOW);
begin
  SetWindowPos(WindowHandle, 0, 0, 0, 0, 0, ShowFlags[FShowing]);
end;
So clearly, someone at Borland knew about this and decided to "misuse" the SetWindowPos API, hence my suggestion that you do the same inside madExcept.
In the end, I agree that not many people would actually run into that, but I'm not even sure anyone would come back to you about this instead of just saying "Meh, it does not work, let's use something else"
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: madExcept dialog not showing up on one computer

Post by madshi »

obones wrote:So clearly, someone at Borland knew about this and decided to "misuse" the SetWindowPos API, hence my suggestion that you do the same inside madExcept.
In the end, I agree that not many people would actually run into that, but I'm not even sure anyone would come back to you about this instead of just saying "Meh, it does not work, let's use something else"
Fair enough. I've replaced ShowWindow with SetWindowPos.
obones
Posts: 66
Joined: Fri May 15, 2009 11:47 am

Re: madExcept dialog not showing up on one computer

Post by obones »

That's perfect, thanks your rapid answers.
Post Reply