Why Themes.pas loses Singleton TThemeServices when connecting to a DLL

Update: Changes to the introduction of VCL styles in XE2 fix memory leak. Therefore, I think it was unintentional.


I ran into a VCL memory leak today, at Themes.pas. This only happens for the DLL. The module completion code looks like this:

finalization if not IsLibrary then InternalServices.Free; 

InternalServices is a singleton that is created on demand when you call ThemeServices . Many DLLs do not have a user interface and therefore never create this singleton. However, I happen to have a COM add-in in Excel that causes this leak to occur.

The leak doesn’t bother me much, because this DLL is never loaded or unloaded from the same process. And I know how I could fix the leak using the ThemeServicesClass global variable.

My question, however, is to ask if anyone can explain why this code is what it is. It seems to be deliberately encoded in this way. For life, I cannot come up with an explanation for this intentional leak.

+7
source share
3 answers

One explanation is that the module completion section is executed when the OS lock is active. During this time, there are significant restrictions on what DLLs are allowed to do without risking a dead end.

+5
source

We are facing the same problem. Here is what we are doing now to prevent a leak in our projects:

  • In the dll.dpr file, add Themes to the uses section.

  • Add the following to clear the leak at shutdown:

     procedure DLLEntryProc(EntryCode: integer); begin case EntryCode of DLL_PROCESS_DETACH: begin ThemeServices.Free; end; DLL_PROCESS_ATTACH: begin end; DLL_THREAD_ATTACH: begin end; DLL_THREAD_DETACH: begin end; end; end; begin {$IFDEF DEBUG} ReportMemoryLeaksOnShutdown := True; {$ENDIF} DllProc := @DLLEntryProc; end. 
+5
source

On the same idea that there should be a good reason to leave it leaking (indy leaks a few things for their intended purpose, or at least it was used), I prefer to ignore it, for example:

 {$I FastMM4Options.inc} ... {$IFDEF EnableMemoryLeakReporting} if IsLibrary then// ThemeServices is leaked when created in a DLL. RegisterExpectedMemoryLeak(ThemeServices); {$ENDIF} 
0
source

All Articles