Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions FastMM4.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,20 @@ procedure GetMemoryMap(var AMemoryMap: TMemoryMap);
function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean; overload;
function RegisterExpectedMemoryLeak(ALeakedObjectClass: TClass; ACount: Integer = 1): Boolean; overload;
function RegisterExpectedMemoryLeak(ALeakedBlockSize: NativeInt; ACount: Integer = 1): Boolean; overload;

{$ifdef MSWINDOWS}
{Start registering all allocations in the current thread as expected memory leaks.
Only one thread in the program can be in this state. While the program is registering
all memory allocations in a thread as expected leaks any other call to this function
will block and will only continue when the original thread calls
StopRegisteringAllThreadAllocationsAsExpectedLeaks;
}
procedure StartRegisteringAllThreadAllocationsAsExpectedLeaks;
{Stops registering all allocations in the current thread as expected memory leaks.
}
procedure StopRegisteringAllThreadAllocationsAsExpectedLeaks;
{$endif}

{$ifdef CheckCppObjectTypeEnabled}
{Registers expected memory leaks by virtual object's typeId pointer.
Usage: RegisterExpectedMemoryLeak(typeid(ACppObject).tpp, Count);}
Expand Down Expand Up @@ -9651,6 +9665,11 @@ function DebugGetMem(ASize: {$ifdef XE2AndUp}NativeInt{$else}Integer{$endif}): P
{Leaving the memory manager routine: Block scans may be performed again.}
DoneChangingFullDebugModeBlock;
end;
if Result <> nil then
begin
if (RegisterAllAsLeakForThread <> 0) and (RegisterAllAsLeakForThread = GetCurrentThreadID) then
RegisterExpectedMemoryLeak(Result);
end;
end;

function CheckBlockBeforeFreeOrRealloc(APBlock: PFullDebugBlockHeader;
Expand Down Expand Up @@ -10492,6 +10511,31 @@ function RegisterExpectedMemoryLeak(ALeakedBlockSize: NativeInt; ACount: Integer
ExpectedMemoryLeaksListLocked := False;
end;

{$ifdef MSWINDOWS}
procedure StartRegisteringAllThreadAllocationsAsExpectedLeaks;
var
LThreadID: Cardinal;
begin
LThreadID := GetCurrentThreadID;
while LockCmpxchg32(0, LThreadID, @RegisterAllAsLeakForThread) <> 0 do
begin
Sleep(InitialSleepTime);
if LockCmpxchg(0, LThreadID, @RegisterAllAsLeakForThread) = 0 then
Break;
Sleep(AdditionalSleepTime);
end;
end;

procedure StopRegisteringAllThreadAllocationsAsExpectedLeaks;
var
LThreadID: Cardinal;
begin
LThreadID := GetCurrentThreadID;
if LockCmpxchg32(LThreadID, 0, @RegisterAllAsLeakForThread) <> LThreadID then
{$ifdef BCB6OrDelphi7AndUp}System.Error(reInvalidPtr);{$else}System.RunError(reInvalidPtr);{$endif}
end;
{$endif}

function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean; overload;
var
LNewEntry: TExpectedMemoryLeak;
Expand Down