|
@@ -34,7 +34,8 @@ interface
|
|
uses
|
|
uses
|
|
Classes, SysUtils,
|
|
Classes, SysUtils,
|
|
SyncObjs,
|
|
SyncObjs,
|
|
- UAbstractAVLTree;
|
|
|
|
|
|
+ UAbstractAVLTree
|
|
|
|
+ {$IFNDEF FPC},System.Generics.Collections,System.Generics.Defaults{$ELSE},Generics.Collections,Generics.Defaults{$ENDIF};
|
|
|
|
|
|
{$I ./ConfigAbstractMem.inc }
|
|
{$I ./ConfigAbstractMem.inc }
|
|
|
|
|
|
@@ -71,7 +72,6 @@ Type
|
|
function ToString : String;
|
|
function ToString : String;
|
|
end;
|
|
end;
|
|
|
|
|
|
-
|
|
|
|
TAbstractMemMemoryLeaks = Class( TAVLAbstractTree<TAbstractMemMemoryLeaksNode> )
|
|
TAbstractMemMemoryLeaks = Class( TAVLAbstractTree<TAbstractMemMemoryLeaksNode> )
|
|
private
|
|
private
|
|
FAbstractMem : TAbstractMem;
|
|
FAbstractMem : TAbstractMem;
|
|
@@ -97,6 +97,11 @@ Type
|
|
|
|
|
|
TAbstractMemZoneType = (amzt_unknown, amzt_memory_leak, amzt_used);
|
|
TAbstractMemZoneType = (amzt_unknown, amzt_memory_leak, amzt_used);
|
|
|
|
|
|
|
|
+ TAbstractMemZoneInfo = record
|
|
|
|
+ AMZone : TAMZone;
|
|
|
|
+ ZoneType : TAbstractMemZoneType;
|
|
|
|
+ end;
|
|
|
|
+
|
|
{ TAbstractMem }
|
|
{ TAbstractMem }
|
|
|
|
|
|
TAbstractMem = Class
|
|
TAbstractMem = Class
|
|
@@ -135,7 +140,7 @@ Type
|
|
procedure Dispose(const APosition : TAbstractMemPosition); overload;
|
|
procedure Dispose(const APosition : TAbstractMemPosition); overload;
|
|
function GetUsedZoneInfo(const APosition : TAbstractMemPosition; ACheckForUsedZone : Boolean; out AAMZone : TAMZone) : Boolean;
|
|
function GetUsedZoneInfo(const APosition : TAbstractMemPosition; ACheckForUsedZone : Boolean; out AAMZone : TAMZone) : Boolean;
|
|
function ToString : String; override;
|
|
function ToString : String; override;
|
|
- function CheckConsistency(const AStructure : TStrings; out ATotalUsedSize, ATotalUsedBlocksCount, ATotalLeaksSize, ATotalLeaksBlocksCount : Integer) : Boolean;
|
|
|
|
|
|
+ function CheckConsistency(const AStructure : TStrings; const AAbstractMemZoneInfoList : TList<TAbstractMemZoneInfo>; out ATotalUsedSize, ATotalUsedBlocksCount, ATotalLeaksSize, ATotalLeaksBlocksCount : Integer) : Boolean;
|
|
function ReadFirstData(var AFirstDataZone : TAMZone; var AFirstData : TBytes) : Boolean;
|
|
function ReadFirstData(var AFirstDataZone : TAMZone; var AFirstData : TBytes) : Boolean;
|
|
class function GetAbstractMemVersion : String;
|
|
class function GetAbstractMemVersion : String;
|
|
property ReadOnly : Boolean read FReadOnly;
|
|
property ReadOnly : Boolean read FReadOnly;
|
|
@@ -189,9 +194,12 @@ const
|
|
|
|
|
|
{ TAbstractMem }
|
|
{ TAbstractMem }
|
|
|
|
|
|
-function TAbstractMem.CheckConsistency(const AStructure: TStrings; out ATotalUsedSize, ATotalUsedBlocksCount, ATotalLeaksSize, ATotalLeaksBlocksCount : Integer) : Boolean;
|
|
|
|
|
|
+function TAbstractMem.CheckConsistency(const AStructure : TStrings; const AAbstractMemZoneInfoList : TList<TAbstractMemZoneInfo>; out ATotalUsedSize, ATotalUsedBlocksCount, ATotalLeaksSize, ATotalLeaksBlocksCount : Integer) : Boolean;
|
|
var LPosition : TAbstractMemPosition;
|
|
var LPosition : TAbstractMemPosition;
|
|
LZone : TAMZone;
|
|
LZone : TAMZone;
|
|
|
|
+ LAMZoneInfo : TAbstractMemZoneInfo;
|
|
|
|
+ i, nCount : Integer;
|
|
|
|
+ LMemLeakFound,LMemLeakToFind : TAbstractMemMemoryLeaksNode;
|
|
begin
|
|
begin
|
|
// Will check since first position:
|
|
// Will check since first position:
|
|
FLock.Acquire;
|
|
FLock.Acquire;
|
|
@@ -206,12 +214,22 @@ begin
|
|
case GetZoneType(LPosition,LZone) of
|
|
case GetZoneType(LPosition,LZone) of
|
|
amzt_memory_leak : begin
|
|
amzt_memory_leak : begin
|
|
if Assigned(AStructure) then AStructure.Add( Format('%d to %d mem leak %d bytes',[LPosition,LZone.position + LZone.size,LZone.size]));
|
|
if Assigned(AStructure) then AStructure.Add( Format('%d to %d mem leak %d bytes',[LPosition,LZone.position + LZone.size,LZone.size]));
|
|
|
|
+ if Assigned(AAbstractMemZoneInfoList) then begin
|
|
|
|
+ LAMZoneInfo.AMZone := LZone;
|
|
|
|
+ LAMZoneInfo.ZoneType := amzt_memory_leak;
|
|
|
|
+ AAbstractMemZoneInfoList.Add(LAMZoneInfo);
|
|
|
|
+ end;
|
|
Inc(LPosition, LZone.size);
|
|
Inc(LPosition, LZone.size);
|
|
inc(ATotalLeaksSize,LZone.size);
|
|
inc(ATotalLeaksSize,LZone.size);
|
|
inc(ATotalLeaksBlocksCount);
|
|
inc(ATotalLeaksBlocksCount);
|
|
end;
|
|
end;
|
|
amzt_used : begin
|
|
amzt_used : begin
|
|
if Assigned(AStructure) then AStructure.Add( Format('%d to %d used %d bytes',[LPosition,LZone.position + LZone.size, LZone.size]));
|
|
if Assigned(AStructure) then AStructure.Add( Format('%d to %d used %d bytes',[LPosition,LZone.position + LZone.size, LZone.size]));
|
|
|
|
+ if Assigned(AAbstractMemZoneInfoList) then begin
|
|
|
|
+ LAMZoneInfo.AMZone := LZone;
|
|
|
|
+ LAMZoneInfo.ZoneType := amzt_used;
|
|
|
|
+ AAbstractMemZoneInfoList.Add(LAMZoneInfo);
|
|
|
|
+ end;
|
|
inc(LPosition, LZone.size + CT_ExtraSizeForUsedZoneType);
|
|
inc(LPosition, LZone.size + CT_ExtraSizeForUsedZoneType);
|
|
inc(ATotalUsedSize,LZone.size + CT_ExtraSizeForUsedZoneType);
|
|
inc(ATotalUsedSize,LZone.size + CT_ExtraSizeForUsedZoneType);
|
|
inc(ATotalUsedBlocksCount);
|
|
inc(ATotalUsedBlocksCount);
|
|
@@ -221,6 +239,34 @@ begin
|
|
Result := False;
|
|
Result := False;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
+ //
|
|
|
|
+ if Assigned(AAbstractMemZoneInfoList) then begin
|
|
|
|
+ // Try to find all blocks:
|
|
|
|
+ for i := 0 to AAbstractMemZoneInfoList.Count-1 do begin
|
|
|
|
+ if (AAbstractMemZoneInfoList.Items[i].ZoneType=amzt_memory_leak) then begin
|
|
|
|
+ // Search it:
|
|
|
|
+ LMemLeakToFind.Clear;
|
|
|
|
+ LMemLeakToFind.SetSize( AAbstractMemZoneInfoList.Items[i].AMZone.size );
|
|
|
|
+ LMemLeakToFind.myPosition := AAbstractMemZoneInfoList.Items[i].AMZone.position;
|
|
|
|
+
|
|
|
|
+ LMemLeakFound := FMemLeaks.Find( LMemLeakToFind );
|
|
|
|
+ if Not FMemLeaks.IsNil(LMemLeakFound) then begin
|
|
|
|
+ if (LMemLeakFound.myPosition<>AAbstractMemZoneInfoList.Items[i].AMZone.position) then begin
|
|
|
|
+ if Assigned(AStructure) then AStructure.Add( Format('MemLeak of %d bytes at %d pos not equal at %d/%d',
|
|
|
|
+ [LMemLeakToFind.GetSize,AAbstractMemZoneInfoList.Items[i].AMZone.position,i+1,AAbstractMemZoneInfoList.Count]));
|
|
|
|
+ Result := False;
|
|
|
|
+ end;
|
|
|
|
+ end else begin
|
|
|
|
+ if Assigned(AStructure) then AStructure.Add( Format('MemLeak of %d bytes at pos %d pos not found %d/%d',
|
|
|
|
+ [LMemLeakToFind.GetSize,AAbstractMemZoneInfoList.Items[i].AMZone.position,i+1,AAbstractMemZoneInfoList.Count]));
|
|
|
|
+ Result := False;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ end;
|
|
Finally
|
|
Finally
|
|
FLock.Release;
|
|
FLock.Release;
|
|
End;
|
|
End;
|
|
@@ -554,7 +600,7 @@ var LAnalize : TStrings;
|
|
begin
|
|
begin
|
|
LAnalize := TStringList.Create;
|
|
LAnalize := TStringList.Create;
|
|
try
|
|
try
|
|
- if Not CheckConsistency(LAnalize,LTotalUsedSize, LTotalUsedBlocksCount, LTotalLeaksSize, LTotalLeaksBlocksCount) then begin
|
|
|
|
|
|
+ if Not CheckConsistency(LAnalize, Nil, LTotalUsedSize, LTotalUsedBlocksCount, LTotalLeaksSize, LTotalLeaksBlocksCount) then begin
|
|
LAnalize.Add('CONSISTENCY ERROR FOUND');
|
|
LAnalize.Add('CONSISTENCY ERROR FOUND');
|
|
end else begin
|
|
end else begin
|
|
LAnalize.Clear;
|
|
LAnalize.Clear;
|