You are not logged in.
Pages: 1
Hi,
I have a problem with SetWeak. I have a parent who has a children list. I did something similar to this example, but then there were problems with the memory. It seems to me that problem occurs after calling TDynArrayHashed.ReHash.
In this example, when you call CreateStructure with ANumber = 243, then everything is ok. With ANumber = 244 TParent.FRefCount becomes smaller than zero.
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Generics.Collections,
mORMot, SynCommons;
type
IParent = interface;
IChild = interface
['{B71BD1C3-CE4C-438A-8090-DA6AACF0B3C4}']
end;
TChild = class(TInterfacedObject, IChild)
private
_parent: IParent;
public
Constructor Create(const AParent: IParent);
end;
IParent = interface
['{3C02359E-D6DA-40E0-A12E-30B239DA7D9F}']
function getChildList: TList<IChild>;
end;
TParent = class(TInterfacedObject, IParent)
private
_childList: TList<IChild>;
public
Constructor Create;
destructor Destroy; override;
function getChildList: TList<IChild>;
function _Release: Integer; stdcall;
end;
{ TParent }
constructor TParent.Create;
begin
inherited Create;
_childList := TList<IChild>.Create;
end;
destructor TParent.Destroy;
begin
_childList.Free;
inherited;
end;
function TParent.getChildList: TList<IChild>;
begin
Result := _childList;
end;
function TParent._Release: Integer;
begin
Result := AtomicDecrement(FRefCount);
if Result = 0 then
Destroy
else if Result < 0 then
raise Exception.Create('Something goes wrong');
end;
{ TChild }
constructor TChild.Create(const AParent: IParent);
begin
inherited Create;
SetWeak0(@_parent, AParent);
end;
procedure CreateStructure(const ANumber: integer);
var
i: integer;
parent: IParent;
child: IChild;
list: TList<IParent>;
begin
list := TList<IParent>.Create;
for i := 0 to ANumber - 1 do
begin
parent := TParent.Create;
child := TChild.Create(parent);
parent.getChildList.Add(child);
list.Add(parent);
end;
parent := nil;
child := nil;
list.Free;
end;
begin
try
CreateStructure(244); // 243 is ok
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
What am I doing wrong?
Offline
And in this example I have a out of memory
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
FastMM4,
System.SysUtils,
Generics.Collections,
mORMot, SynCommons;
type
IParent = interface;
IChild = interface
['{B71BD1C3-CE4C-438A-8090-DA6AACF0B3C4}']
end;
TChild = class(TInterfacedObject, IChild)
private
_parent: IParent;
public
Constructor Create(const AParent: IParent);
end;
IParent = interface
['{3C02359E-D6DA-40E0-A12E-30B239DA7D9F}']
function getChildList: TList<IChild>;
end;
TParent = class(TInterfacedObject, IParent)
private
_childList: TList<IChild>;
public
Constructor Create;
destructor Destroy; override;
function getChildList: TList<IChild>;
end;
{ TParent }
constructor TParent.Create;
begin
inherited Create;
_childList := TList<IChild>.Create;
end;
destructor TParent.Destroy;
begin
_childList.Free;
inherited;
end;
function TParent.getChildList: TList<IChild>;
begin
Result := _childList;
end;
{ TChild }
constructor TChild.Create(const AParent: IParent);
begin
inherited Create;
SetWeak0(@_parent, AParent);
end;
var
list: TList<IParent>;
parent: IParent;
child: IChild;
begin
FastMM4.FullDebugModeScanMemoryPoolBeforeEveryOperation := true;
list := TList<IParent>.Create;
parent := TParent.Create;
list.Add(parent);
child := TChild.Create(parent);
parent.getChildList.Add(child);
parent := nil;
child := nil;
list.Free; // BOOM
end.
---------------------------
Project1.exe: Memory Error Detected
---------------------------
FastMM has detected an error during a free block scan operation. FastMM detected that a block has been modified after being freed.
Modified byte offsets (and lengths): 12(3)
The previous block size was: 24
This block was previously allocated by thread 0x9720, and the stack trace (return addresses) at the time was:
406A0E [System.pas][System][@GetMem$qqri][4351]
40848B [System.pas][System][TObject.NewInstance$qqrv][15578]
40DFC9 [System.pas][System][TInterfacedObject.NewInstance$qqrv][36448]
408BBA [System.pas][System][@ClassCreate$qqrpvzc][16888]
5F2EF6 [Project1.dpr][Project1][TChild.$bctr$qqrx44System.%DelphiInterface$t16Project1.IParent%][64]
5FC624 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.Add$qqrx44System.%DelphiInterface$t16Project1.IParent%][845]
600598
75CD337A [BaseThreadInitThunk]
778692B2 [Unknown function at RtlInitializeExceptionChain]
77869285 [Unknown function at RtlInitializeExceptionChain]
The block was previously used for an object of class: TChild
The allocation number was: 301
The block was previously freed by thread 0x9720, and the stack trace (return addresses) at the time was:
406A2A [System.pas][System][@FreeMem$qqrpv][4399]
4084A9 [System.pas][System][TObject.FreeInstance$qqrv][15587]
5F114A [mORMot.pas][mORMot][TSetWeakZeroClass.HookedFreeInstance$qqrv][39469]
408C05 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]
4085A2 [System.pas][System][TObject.$bdtr$qqrv][15647]
40E035 [System.pas][System][TInterfacedObject._Release$qqsv][36476]
40DF3B [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]
40BD0D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]
40C8D1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]
5FB5E9 [Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.DeleteRange$qqrii]
2869336 [GetRawStackTrace]
5FA820 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.SetCount$qqri][675]
5FA79E [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.SetCapacity$qqri][664]
5FACE7 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.$bdtr$qqrv][817]
4085AF [System.pas][System][TObject.Free$qqrv][15655]
5F2EA8 [Project1.dpr][Project1][TParent.$bdtr$qqrv][52]
40E035 [System.pas][System][TInterfacedObject._Release$qqsv][36476]
40DF3B [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]
40BD0D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]
40C8D1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]
5FCDCD [Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.DeleteRange$qqrii]
5FC004 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCount$qqri][675]
5FBF82 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCapacity$qqri][664]
5FC4CB [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.$bdtr$qqrv][817]
4085AF [System.pas][System][TObject.Free$qqrv][15655]
The current thread ID is 0x9720, and the stack trace (return addresses) leading to this error is:
414EFE [FastMM4.pas][FastMM4][InternalScanMemoryPool$qqruiui][9109]
414FD9 [FastMM4.pas][FastMM4][ScanMemoryPoolForCorruptions$qqrv][9183]
414B0B [FastMM4.pas][FastMM4][DebugFreeMem$qqrpv][8852]
406A2A [System.pas][System][@FreeMem$qqrpv][4399]
40C8DA [System.pas][System][@DynArrayClear$qqrrpvpv][34241]
40BD1E [System.pas][System][@FinalizeArray$qqrpvt1ui][31517]
40BBFD [System.pas][System][@FinalizeRecord$qqrpvt1][31189]
408627 [System.pas][System][TObject.CleanupInstance$qqrv][15792]
4084A2 [System.pas][System][TObject.FreeInstance$qqrv][15586]
408C05 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]
5F0F23 [mORMot.pas][mORMot][TSetWeakZeroInstance.$bdtr$qqrv][39408]
4085AF [System.pas][System][TObject.Free$qqrv][15655]
574D10 [SynCommons.pas][SynCommons][TObjectListHashedAbstract.Delete$qqri][36443]
574D51 [SynCommons.pas][SynCommons][TObjectListHashedAbstract.Delete$qqrp14System.TObject][36450]
5F1120 [mORMot.pas][mORMot][TSetWeakZeroClass.HookedFreeInstance$qqrv][39465]
408C05 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]
5F2EC4 [Project1.dpr][Project1][TParent.$bdtr$qqrv][54]
40E035 [System.pas][System][TInterfacedObject._Release$qqsv][36476]
40DF3B [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]
40BD0D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]
40C8D1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]
5FCDCD [Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.DeleteRange$qqrii]
5FC004 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCount$qqri][675]
5FBF82 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCapacity$qqri][664]
5FC4CB [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.$bdtr$qqrv][817]
Current memory dump of 256 bytes starting at pointer address 7EF88BF0:
8C E2 60 00 80 E5 60 00 80 E5 60 00 00 00 00 00 80 E5 60 00 80 E5 60 00 87 53 DF 0F 80 E5 60 00
80 E5 60 00 80 E5 60 00 00 00 00 00 81 8F F8 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
83 01 00 00 0E 6A 40 00 DF A1 40 00 6C A6 40 00 67 B4 40 00 E2 11 5F 00 8B 14 5F 00 01 15 5F 00
1A 2F 5F 00 98 05 60 00 7A 33 CD 75 B2 92 86 77 85 92 86 77 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 20 97 00 00 20 97 00 00 2A 6A 40 00 FE A2 40 00 54 12 5F 00 8B 14 5F 00
01 15 5F 00 1A 2F 5F 00 98 05 60 00 7A 33 CD 75 B2 92 86 77 85 92 86 77 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Ś â ` . € ĺ ` . € ĺ ` . . . . . € ĺ ` . € ĺ ` . ‡ S ß . € ĺ ` .
€ ĺ ` . € ĺ ` . . . . . Ź ř ~ . . . . . . . . . . . . . . . .
. . . . j @ . ß ˇ @ . l ¦ @ . g ´ @ . â . _ . ‹ . _ . . . _ .
. / _ . . ` . z 3 Í u ˛ ’ † w … ’ † w . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . — . . — . . * j @ . ţ ˘ @ . T . _ . ‹ . _ .
. . _ . . / _ . . ` . z 3 Í u ˛ ’ † w … ’ † w . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
---------------------------
OK
---------------------------
I can not find where the bug is
Offline
I tested on version 1.18 and the latest from github
Offline
Please try to put all your interface variables in a single sub-procedure, called by the main procedure.
I guess you may be a victim of http://synopse.info/forum/viewtopic.php?pid=9174#p9174
Online
I changed to something like that ("LocalVariable" should be released at the exit of FillList), but still there is an error:
procedure FillList(const AList: TList<IParent>);
var
parent: IParent;
child: IChild;
begin
parent := TParent.Create;
AList.Add(parent);
child := TChild.Create(parent);
parent.getChildList.Add(child);
end;
var
list: TList<IParent>;
begin
FastMM4.FullDebugModeScanMemoryPoolBeforeEveryOperation := true;
list := TList<IParent>.Create;
FillList(list);
list.Free; // BOOM
end.
---------------------------
Project1.exe: Memory Error Detected
---------------------------
FastMM has detected an error during a free block scan operation. FastMM detected that a block has been modified after being freed.
Modified byte offsets (and lengths): 12(3)
The previous block size was: 24
This block was previously allocated by thread 0x2B98, and the stack trace (return addresses) at the time was:
406A0A [System.pas][System][@GetMem$qqri][4351]
408A77 [System.pas][System][TObject.NewInstance$qqrv][15578]
40E191 [System.pas][System][TInterfacedObject.NewInstance$qqrv][36448]
4091A6 [System.pas][System][@ClassCreate$qqrpvzc][16888]
5DBB6E [Project1.dpr][Project1][TChild.$bctr$qqrx44System.%DelphiInterface$t16Project1.IParent%][64]
5E2D40 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.Add$qqrx44System.%DelphiInterface$t16Project1.IParent%][845]
5DBC05 [Project1.dpr][Project1][FillList$qqrxp85System.Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%][76]
5E72B3
76D2337A [BaseThreadInitThunk]
772592B2 [Unknown function at RtlInitializeExceptionChain]
77259285 [Unknown function at RtlInitializeExceptionChain]
The block was previously used for an object of class: TChild
The allocation number was: 384
The block was previously freed by thread 0x2B98, and the stack trace (return addresses) at the time was:
406A26 [System.pas][System][@FreeMem$qqrpv][4399]
408A95 [System.pas][System][TObject.FreeInstance$qqrv][15587]
5D9D92 [mORMot.pas][mORMot][TSetWeakZeroClass.HookedFreeInstance$qqrv][49750]
4091F1 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]
408B8E [System.pas][System][TObject.$bdtr$qqrv][15647]
40E1FD [System.pas][System][TInterfacedObject._Release$qqsv][36476]
40E103 [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]
40C02D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]
40CBD1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]
5E1D05 [Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.DeleteRange$qqrii]
2579336 [GetRawStackTrace]
5E0F3C [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.SetCount$qqri][675]
5E0EBA [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.SetCapacity$qqri][664]
5E1403 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$43System.%DelphiInterface$t15Project1.IChild%%.$bdtr$qqrv][817]
408B9B [System.pas][System][TObject.Free$qqrv][15655]
5DBB20 [Project1.dpr][Project1][TParent.$bdtr$qqrv][52]
40E1FD [System.pas][System][TInterfacedObject._Release$qqsv][36476]
40E103 [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]
40C02D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]
40CBD1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]
5E34E9 [Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.DeleteRange$qqrii]
5E2720 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCount$qqri][675]
5E269E [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCapacity$qqri][664]
5E2BE7 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.$bdtr$qqrv][817]
408B9B [System.pas][System][TObject.Free$qqrv][15655]
The current thread ID is 0x2B98, and the stack trace (return addresses) leading to this error is:
41335A [FastMM4.pas][FastMM4][InternalScanMemoryPool$qqruiui][9109]
413435 [FastMM4.pas][FastMM4][ScanMemoryPoolForCorruptions$qqrv][9183]
412F67 [FastMM4.pas][FastMM4][DebugFreeMem$qqrpv][8852]
406A26 [System.pas][System][@FreeMem$qqrpv][4399]
40CBDA [System.pas][System][@DynArrayClear$qqrrpvpv][34241]
40C03E [System.pas][System][@FinalizeArray$qqrpvt1ui][31517]
40BF1D [System.pas][System][@FinalizeRecord$qqrpvt1][31189]
408C13 [System.pas][System][TObject.CleanupInstance$qqrv][15792]
408A8E [System.pas][System][TObject.FreeInstance$qqrv][15586]
4091F1 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]
5D9B5F [mORMot.pas][mORMot][TSetWeakZeroInstance.$bdtr$qqrv][49690]
408B9B [System.pas][System][TObject.Free$qqrv][15655]
52D424 [SynCommons.pas][SynCommons][TObjectListHashedAbstract.Delete$qqri][42486]
52D465 [SynCommons.pas][SynCommons][TObjectListHashedAbstract.Delete$qqrp14System.TObject][42493]
5D9D68 [mORMot.pas][mORMot][TSetWeakZeroClass.HookedFreeInstance$qqrv][49746]
4091F1 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16930]
5DBB3C [Project1.dpr][Project1][TParent.$bdtr$qqrv][54]
40E1FD [System.pas][System][TInterfacedObject._Release$qqsv][36476]
40E103 [System.pas][System][@IntfClear$qqrr45System.%DelphiInterface$t17System.IInterface%][35702]
40C02D [System.pas][System][@FinalizeArray$qqrpvt1ui][31488]
40CBD1 [System.pas][System][@DynArrayClear$qqrrpvpv][34232]
5E34E9 [Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.DeleteRange$qqrii]
5E2720 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCount$qqri][675]
5E269E [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.SetCapacity$qqri][664]
5E2BE7 [System.Generics.Collections.pas][Project1][Generics.Collections.%TList__1$44System.%DelphiInterface$t16Project1.IParent%%.$bdtr$qqrv][817]
Current memory dump of 256 bytes starting at pointer address 7EF127C0:
88 52 5F 00 7C 55 5F 00 7C 55 5F 00 00 00 00 00 7C 55 5F 00 7C 55 5F 00 14 55 8B 0F 7C 55 5F 00
7C 55 5F 00 7C 55 5F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R _ . | U _ . | U _ . . . . . | U _ . | U _ . . U ‹ . | U _ .
| U _ . | U _ . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
---------------------------
OK
---------------------------
Offline
Pages: 1