RegisterExpectedMemoryLeak

delphi package - automated exception handling
troberts
Posts: 3
Joined: Mon Feb 28, 2022 6:08 pm

Re: RegisterExpectedMemoryLeak

Post by troberts »

Picking this up again. I have a fresh install of Delphi 11 and madExcept on a new PC and I have exactly the same problem as the writer of this post (leaking of TIdCriticalSection):

https://stackoverflow.com/questions/711 ... 6#71292136

I read Remy's answer and it seems to me that it shouldn't be necessary to recompile Indy and so therefore the problem must be with the madExcept install. I have uninstalled and reinstalled madExcept to no avail.

Any further ideas?
gambit47
Posts: 6
Joined: Wed May 31, 2006 8:02 pm

Re: RegisterExpectedMemoryLeak

Post by gambit47 »

madshi wrote: Mon Oct 06, 2014 6:17 pm madExcept's leak checking should automatically handle leaks registered via RegisterExpectedMemoryLeak() correctly. At least that's the theory...
In practice, has that actually been verified?
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: RegisterExpectedMemoryLeak

Post by madshi »

IIRC I did test it at some point.
WoRei
Posts: 4
Joined: Wed Jul 27, 2022 10:34 am

Re: RegisterExpectedMemoryLeak

Post by WoRei »

Hi,

after migrating to Delphi 11.1 (latest patch installed), we encounter the same problem.
To reproduce the problem, do the following steps:
* Make new project (Windows VCL)
* add IdThread to the uses clause
* Enable madExcept and leak checking
* Compile, run and close the application
This will result in the output from the file "leakcheck_result1.png".

If madExcept is disabled and Delphis internal leak checking is enabled (ReportMemoryLeaksOnShutdown := True) the leak is hidden (as expected).
P.S.: It was checked that Delphis leak checking is working - we added an object leak in "FormCreate".

P.P.S.: Indy registers leaks in the initialization clause, for example in IdThread.pas:
...
IndyRegisterExpectedMemoryLeak(GThreadCount);
IndyRegisterExpectedMemoryLeak(TIdThreadSafeIntegerAccess(GThreadCount).FCriticalSection);
...
It was verififed by debugging that this code is executed.

Best regards,
Wolfgang
Attachments
leakcheck_result1.png
leakcheck_result1.png (21.18 KiB) Viewed 4976 times
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: RegisterExpectedMemoryLeak

Post by madshi »

Does the "TIdThreadSafeIntegerAccess(GThreadCount).FCriticalSection" address match one of the reported leaks ($5d4150c or $5cf290c)?
WoRei
Posts: 4
Joined: Wed Jul 27, 2022 10:34 am

Re: RegisterExpectedMemoryLeak

Post by WoRei »

madshi wrote: Fri Jul 29, 2022 3:24 pm Does the "TIdThreadSafeIntegerAccess(GThreadCount).FCriticalSection" address match one of the reported leaks ($5d4150c or $5cf290c)?
Hi,

thanks for the hint, I have not checked that yet.
The answer is no, the memory address is shifted by 4 bytes (see attachments).
I have tried this a few times and it is always 4 bytes. (for both leaks).

P.S.: I included the second leak because with this one it was easier to include the creation of the object (at line 1230).
TIdCriticalSection is just a TCriticalSection as declared in IdGlobal.pas, line 1305:
---------
TIdCriticalSection = class(TCriticalSection)
end;
---------

Best regards,
Wolfgang
Attachments
1.png
1.png (19.17 KiB) Viewed 4922 times
2.png
2.png (21.12 KiB) Viewed 4922 times
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: RegisterExpectedMemoryLeak

Post by madshi »

Well, looking at the Delphi RTL source code, TCriticalSection is basically a Delphi class, but what madExcept is complaining about is not the Delphi class, but the win32 critical section object inside. If you look at the definition ot TCriticalSection, it looks like this:

Code: Select all

type
  TCriticalSection = class(TSynchroObject)
  protected
    FSection: TRTLCriticalSection;
    [...]
  end;
So what madExcept complains about is the "FSection" object within the TCriticalSection class. In order to hide it, Indy would have to add the following line, I think:

Code: Select all

IndyRegisterExpectedMemoryLeak(GThreadCount);
IndyRegisterExpectedMemoryLeak(TIdThreadSafeIntegerAccess(GThreadCount).FCriticalSection);
IndyRegisterExpectedMemoryLeak(@TIdThreadSafeIntegerAccess(GThreadCount).FCriticalSection.FSection);
WoRei
Posts: 4
Joined: Wed Jul 27, 2022 10:34 am

Re: RegisterExpectedMemoryLeak

Post by WoRei »

Hi,

I checked the source code of TCritialSection in both Delphi versions and from what I have seen, the implementation of TCriticalSection has not changed, it is the same in both versions.

So I made a small test application which just creates a TCriticalSection which is not freed, but registered as memory leak (see attachment).
I tested the following:
- Delphi 10.2 madExcept 5.0.0 (this was my previous system) --> leak is not reported
- Delphi 11.1 madExcept 5.1.2 --> leak is reported and another registered memory leak (for the FSection record) is needed.
- Delphi 10.2 madExcept 5.1.2 (I installed the new version on my old system) --> leak is reported and another registered memory leak (for the FSection record) is needed.

So something must have changed in madExcept from version 5.0.0 to 5.1.2.

P.S.: Delphis internal leak check (ReportMemoryLeaksOnShutdown) works like version 5.0.0 and does not report the leak.

Could you please check if this is a bug in version 5.1.2 or an intended change of the behavior?

From my point of view, the new behavior is not practicable, since one very often has no access to internal objects and therefore cannot register them as a leak. This is also the case with TCriticalSection, for example: FSection is protected and one can only access the object via a trick (by deriving from TCriticalSection). But if FSection were private, then it wouldn't work at all.
Attachments
1.png
1.png (11.93 KiB) Viewed 4900 times
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: RegisterExpectedMemoryLeak

Post by madshi »

Delphi's internal leak checker only tests for leaks in the Delphi internal memory manager. madExcept hooks over 400 different win32 APIs to report all kinds of additional leaks to you. So of course Delphi does not report this specific leak, because it's not a Delphi memory manager allocation, instead it's a call to the win32 API "InitializeCriticalSection()". In the same way Delphi does not report leaked file handles, window handles, process handles, GDI handles, printer handles, OS level allocations (VirtualAlloc) etc etc etc, which madExcept all nicely reports to you.

madExcept has a special feature in it which tries to automatically assign "child" leaks to a parent leak. Meaning, if some Delphi object (or dynamic array or similar) is leaked, then madExcept looks through the leaked object to see if there might be more leaks that belong to the same "parent". This is a special filtering method which AFAIK no other leak reporter does (?). It can be quite costly in terms of processing time, so I tweaked it over time. It seems that while doing so I introduced a small bug. Which should hopefully be fixed in this new build now?

http://madshi.net/madCollectionUpdate.exe
WoRei
Posts: 4
Joined: Wed Jul 27, 2022 10:34 am

Re: RegisterExpectedMemoryLeak

Post by WoRei »

Hi,

thanks for the detailed information :D
We already knew that madExcept is a piece of exceptionally good software, but this additional information makes it even more impressive.
madExcept is among the absolutely most useful components of Delphi (especially compared to the internal leak checker or exception handler, which isn't very helpful most of the time) that we know of - we've found countless bugs and memory leaks with it.

I have tested the updated version of madExcept and it works now like before - thanks for your help and support :D

Best regards,
Wolfgang
troberts
Posts: 3
Joined: Mon Feb 28, 2022 6:08 pm

Re: RegisterExpectedMemoryLeak

Post by troberts »

I can confirm that the leak is gone too. Thanks for your help.
Post Reply