Crash on startup using madExcept

delphi package - automated exception handling
Post Reply
jarrod-ca
Posts: 6
Joined: Thu Feb 25, 2016 3:42 am

Crash on startup using madExcept

Post by jarrod-ca »

madExcept 4.0.15 (also tried 4.0.13), Delphi 10 Seattle.

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 problem is that some of our apps consistently crash at startup (without any message if run outside of the IDE - exe just stops). When run in the IDE and step through the code we see that the code above is successfully called but then we get one of two symptoms when running the remaining code in the dpr: exception "Unknown" deep in dfm streaming code when loading the main form, or: "floating point stack check" in EncodeDate in the VCL Now function when we call our standard startup Log() code in the dpr. In most cases, commenting out the RegisterExceptionHandler line restores things to normal working order, but where that doesn't work then disabling madExcept for the project works.

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);
or bury the call in an unused event handler in a random form then the problem returns (and no, RegisterExceptionHandler is not called). It is 100% consistent in this scenario - link it in, fail, comment out, works.

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?
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: Crash on startup using madExcept

Post by madshi »

I would say the 2 most likely reasons for this are:

1) The madExcept patching could cause issues if the map file (or TD32 debug info) does not match your EXE. In order to make sure this is not a problem, please double check that you have TD32 debug information disabled, and that there's also no *.tds file flying around anywhere which might be out of date and confuse madExcept. Also make sure that the map file has the same date and time as your EXE.

2) There could be some buffer overrun (or similar) issue in your code (or in madExcept) which randomly overwrites data or code. And when linking in madExcept, either with the RegisterExceptionHandler code or without, that changes the addresses of where your code and data ends up being mapped to, which changes which part of the code and data the buffer overrun damages.

To be honest, I think this is likely to be 2). Either a buffer overrun, or something like using an object which was already freed, or something really bad and ugly like that.

Have you tried activating the "instantly crash on buffer overrun" madExcept feature? Does that raise any red flags (create any new exceptions)? Unfortunately this feature currently only works with 32bit processes, and it consumes a lot of extra RAM, so if we have bad luck, your process might run out of RAM, when using this feature. But if you have good luck, you might find some buffer overrun (or similar problem), which causes all these problems. Please note that this feature requires madExcept32.dll to be present. So if you try to use this feature on an end user's PC, you'll have to distribute madExcept32.dll with your EXE. On your development PC madExcept should automatically find the dll, provided that madCollection was properly installed.
jarrod-ca
Posts: 6
Joined: Thu Feb 25, 2016 3:42 am

Re: Crash on startup using madExcept

Post by jarrod-ca »

Thanks for your help. I will investigate the things that you suggested to look at and let you know how I go.
jarrod-ca
Posts: 6
Joined: Thu Feb 25, 2016 3:42 am

Re: Crash on startup using madExcept

Post by jarrod-ca »

Update: I investigated both suggestions but was unable to find the cause or a fix.

a) checking for/removing old map/tds files. I couldn't find any in the search path but there were some in other folders (e.g. 64-bit output folder when testing 32-bit build) so I searched and removed all on my computer and the problem still occurred on a new full build. I also tried various compiler options related to debug information.

b) I was unable to find any buffer overrun in the startup code. The errors occur only a couple of statements into the .dpr main so I focused on the preceeding statements and on initialization code. I also enabled the buffer overrun detection in madExcept. There is a chance that there is a bug introduced in third party code that I haven't been able to identify, so a future update may fix it but I'm not convinced at the moment.

So in summary the problem still remains and at the moment we are unable to use madExcept. We will revisit this in the future. Thanks for your help and support.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: Crash on startup using madExcept

Post by madshi »

Well, I could investigate, but I'd need to be able to reproduce the issue on my PC. There's probably no hope for that, I guess?
Post Reply