madExcept dialog not showing up on one computer
madExcept dialog not showing up on one computer
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.
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.
Re: madExcept dialog not showing up on one computer
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...![sad :(](./images/smilies/icon_sad.gif)
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...
![sad :(](./images/smilies/icon_sad.gif)
Re: madExcept dialog not showing up on one computer
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.
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.
Re: madExcept dialog not showing up on one computer
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.
Re: madExcept dialog not showing up on one computer
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 ?
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 ?
Re: madExcept dialog not showing up on one computer
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?
Re: madExcept dialog not showing up on one computer
Via JclSysUtils.Execute which ultimately calls CreateProcessmadshi wrote:How does the launcher start "application A" exactly?
This requires a bit of work, so I have not tested it just yet as I have explored other thingsmadshi wrote:And does it change anything if you disable the named pipe communication?
No, all in the same session, no elevation whatsoevermadshi wrote:Finally, does the launcher run under a different user account?
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
Re: madExcept dialog not showing up on one computer
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 :
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:
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.
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 :
- Use my own code that calls CreateProcess without the SW_HIDE parameter in startup info
- Modify the JCL code so that one can control what value gets set in the startup info for CreateProcess
- Call ShowWindow with a dummy value in my own code on the madExcept assistant window via the OnExceptBoxCreate callback
- Wait for a madExcept version which calls SetWindowPos instead of ShowWindow
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;
Code: Select all
SetWindowPos(FMainWnd, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_SHOWWINDOW);
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.
Re: madExcept dialog not showing up on one computer
Congrats on finding the issue!
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.
![very happy :D](./images/smilies/icon_razz.gif)
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.
Re: madExcept dialog not showing up on one computer
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: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.
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: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.
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;
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"
Re: madExcept dialog not showing up on one computer
Fair enough. I've replaced ShowWindow with SetWindowPos.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"
Re: madExcept dialog not showing up on one computer
That's perfect, thanks your rapid answers.