#1 2015-06-26 20:40:25

pszawa
Member
Registered: 2014-06-05
Posts: 10

I do not know how to use setWeak

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

#2 2015-06-27 00:00:02

pszawa
Member
Registered: 2014-06-05
Posts: 10

Re: I do not know how to use setWeak

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 sad

Offline

#3 2015-06-27 10:06:20

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,183
Website

Re: I do not know how to use setWeak

Are you using the latest nightly version of 1.18?

Offline

#4 2015-06-27 13:18:32

pszawa
Member
Registered: 2014-06-05
Posts: 10

Re: I do not know how to use setWeak

I tested on version 1.18 and the latest from github

Offline

#5 2015-06-28 09:51:53

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,183
Website

Re: I do not know how to use setWeak

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

Offline

#6 2015-06-28 10:09:09

pszawa
Member
Registered: 2014-06-05
Posts: 10

Re: I do not know how to use setWeak

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

Board footer

Powered by FluxBB