Embarcadero's TTaskbar has a memory leak. Since I dropped this control on my form, FastMM reports a leak every time I close the app.
I tried to mute FastMM with this code:
procedure TMainForm.FormCreate(Sender: TObject);
begin
fastmm4.RegisterExpectedMemoryLeak(Taskbar);
end;
but it won't work. How to register this leak?
A memory block has been leaked. The size is: 100
This block was allocated by thread 0xC64, and the stack trace (return addresses) at the time was: 406A52 409A7B 409CAC 4283A0
[System.SysUtils][System][System.SysUtils.FmtStr] 409CC6 40D775 7628A65F
[Unknown function at StretchDIBits] 7731594E
[Unknown function at RtlpNtMakeTemporaryKey] 7731594E
[Unknown function at RtlpNtMakeTemporaryKey] 773168F8
[Unknown function at RtlpNtMakeTemporaryKey] 773168DC
[Unknown function at RtlpNtMakeTemporaryKey]The block is currently used for an object of class: UnicodeString
The allocation number is: 2209A memory block has been leaked. The size is: 36
This block was allocated by thread 0xC64, and the stack trace (return addresses) at the time was: 406A52 407D43 40846A 42CD40
[System.SysUtils][System][System.SysUtils.Exception.CreateFmt] 5DEDD7
[System.Win.TaskbarCore][System.Win][System.Win.TaskbarCore.TTaskbarBase.UpdateTab] 610F00
[Vcl.Taskbar][Vcl][Vcl.Taskbar.CheckMDI] 5DF39F
[System.Win.TaskbarCore][System.Win][System.Win.TaskbarCore.TTaskbarBase.ApplyTabsChanges] 610DB8
[Vcl.Taskbar][Vcl][Vcl.Taskbar.TCustomTaskbar.Initialize] 5EB044
[Vcl.Forms][Vcl][Vcl.Forms.TApplication.Run] 62573A
[MinimalTemplate.dpr][MinimalTemplate][MinimalTemplate.MinimalTemplate][26]The block is currently used for an object of class: ETaskbarException
The allocation number is: 2207This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):
21 - 36 bytes: ETaskbarException x 1
85 - 100 bytes: UnicodeString x 1
[Vcl.Forms][Vcl][Vcl.Forms.TCustomForm.SetVisible] 5F5010
The memory is leaked in this code from System.Win.TaskbarCore
:
procedure TTaskbarBase.UpdateTab;
var
LpfIsiconic: LONGBOOL;
LHandle: HWND;
LFlags: Integer;
begin
if FTaskbarIsAvailable then
begin
LHandle := GetFormHandle;
if not FRegistered and TaskBar.RegisterTab(LHandle) then
begin
TaskBar.SetTabOrder(LHandle);
TaskBar.SetTabActive(LHandle);
FRegistered := True;
end
else
ETaskbarException.CreateFmt(SCouldNotRegisterTabException, [TaskBar.LastError]);
....
The final line creates an exception, and then does nothing with it. The exception and the string that it owns are leaked. As reported by FastMM.
You can register these objects as being leaked if you can obtain their addresses. However, you cannot do that. There is no way to refer to this exception object.
If you simply must avoid this mis-reported leak, and it makes sense that you would, then you'll need to include a fixed version of System.Win.TaskbarCore
in your project. Make a copy of that file, and add it to your project. Then modify the code to fix the fault. My guess is that it would go like this:
if not FRegistered then
begin
if TaskBar.RegisterTab(LHandle) then
begin
TaskBar.SetTabOrder(LHandle);
TaskBar.SetTabActive(LHandle);
FRegistered := True;
end
else
raise ETaskbarException.CreateFmt(SCouldNotRegisterTabException, [TaskBar.LastError]);
end;
Clearly this needs to be reported to Embarcadero. I suggest that you submit a bug report.
Another way around this is to try to avoid the bogus line executing at all. I believe that if you remove this line from your .dfm file, you should avoid the bogus line, and therefore avoid the leak:
Visible = True
Simply remove that line, it seems to be the trigger.
Note that I worked this out by cutting the project down to its bare bones. In order to reproduce the problem this is the minimal dfm file needed:
object Form1: TMainForm
Visible = True
object Taskbar1: TTaskbar
end
end
And with this dfm file there is not leak:
object Form1: TMainForm
object Taskbar1: TTaskbar
end
end
By cutting the project down to the bare minimum, I was able to find the trigger. I cannot stress enough how valuable this technique of minimising a reproduction is.
Thanks to Remy for finding the QC report for this fault: QC#128865
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With