I've spent several hours trying to solve this strange issue. Please help!
We have a suite of reasonably complex VCL forms applications. Historically they have all worked fine. We're reasonably careful, well initialized code, no memory leaks, etc. Adding madExcept to them seemed to work well at first (in development, not released to customers) but some apps are having startup issues when madExcept is used. There are two ways I have found to fix it, both involve removing madExcept as follows.
There is historical code scattered throughout the apps and libraries that raises an exception simply to show a friendly error message to the user (bad practice), so we decided to change the behavior so that madExcept logs the exceptions to file and we suppress the madExcept dialog and instead call MessageBox like the VCL does to show the unhandled exception message to the user, by using the following code:
Code: Select all
program OurApp;
uses
madExcept,
Windows,
Forms,
System.SysUtils;
procedure _exceptionHandler(const exceptIntf: IMEException; var handled: boolean);
begin
exceptIntf.ShowSetting := ssNothing;
if (exceptIntf.ExceptObject is Exception) and (GetCurrentThreadID = MainThreadID) then
MessageBox(0, PChar(Exception(exceptIntf.ExceptObject).Message), PChar(Application.Title), MB_OK or MB_ICONSTOP or MB_TASKMODAL);
end;
begin
RegisterExceptionHandler(_exceptionHandler, stTrySyncCallAlways);
// Other code here
end.
The strange thing is that in the case where removing RegisterExceptionHandler works, the problem returns if RegisterExceptionHandler and dependent code is simply linked in to the app without even being called . For example, if we remove the _exceptionHandler procedure and instead write (in debug mode, optimizations disabled):
Code: Select all
if False then
RegisterExceptionHandler(nil, stTrySyncCallAlways);
So I tried creating a simple app that uses madExcept and RegisterExceptionHandler and it works perfectly without error, and some of our apps also work. There is nothing obvious yet as to why some work and others don't - they use the same third party components/libraries and coding paradigms. We're not using any other third party exception handling. We're not using JCL stack trace or similar. I thought it could be a clash with initialization code but we only have a bunch of Spring4D RegisterClass or RegisterType calls and I don't suspect that they are an issue. The apps have worked fine for years and we have many customers. We run automated tests on other machines at least daily. I should point out that the same crash/exceptions happen to a colleague using a different machine if he enables madExcept and adds RegisterExceptionHandler.
In the cases where it still fails at startup and commenting out RegisterExceptionHandler doesn't fix it then disabling madExcept for the project fixes it. Failing a solution we will likely have to stop using madExcept which would be very unfortunate as I really love it and have used it in previous companies and in my own apps.
Any ideas what is going on? Could it be the madExcept patching? Can I diagnose or disable that part? Is there anything further that I can try to diagnose the problem?