RTC Forums

Subscription => Support => Topic started by: ClementDoss on December 03, 2017, 07:41:22 PM



Title: Can't find what's causing this memory report
Post by: ClementDoss on December 03, 2017, 07:41:22 PM
Hi,
 FastMM is reporting that a block has been modified after being freed. I'm using Delphi Tokyo and RTC v9.01.

Here is my constructor:
Code:
constructor TRestServer.Create;
begin
  inherited;
  FLog := TDHS_Files_Log.Create(lfLogConfigFile,'RestServer',[loNormal, loError,loDebug]);
  Flog.LogMsgFMT('Creating %s %s instance',[DoGetServerFriendlyName, DoGetServerVersion]);

  FUsersManagement  := TRestServerUsers.Create;
  FCriticalSection  := TCriticalSection.Create;


  FRestServer := TRtcHttpServer.New;
  FRestServer.OnListenStart := event_OnListenStart;
  FRestServer.OnListenStop := event_OnListenStop;
  FRestServer.OnListenLost := event_OnListenLost;
  FRestServer.OnListenError := event_OnListenError;
  FRestServer.MultiThreaded := True;
  FRestServer.Blocking := False;
  FRestServer.RestartOn.ListenLost := True;

  FRESTprovider := TRtcDataProvider.Create(nil);
  FRESTprovider.Server := FRestServer;
  FRESTprovider.OnCheckRequest := RESTproviderCheckRequest;
  FRESTprovider.OnDataReceived := RESTproviderDataReceived;

  FFileProviderRootDoc := ExtractFilePath(ParamStr(0));


  FFileUploadprovider:= TRtcDataProvider.Create(nil);
  FFileUploadprovider.Server := FRestServer;
  FFileUploadprovider.OnCheckRequest := FileUploadProviderCheckRequest;
  FFileUploadprovider.OnDataReceived := FileUploadProviderDataReceived;

  FFileDnloadprovider:= TRtcDataProvider.Create(nil);
  FFileDnloadprovider.Server := FRestServer;
  FFileDnloadprovider.OnCheckRequest := event_FileDnloadProviderCheckRequest;
  FFileDnloadprovider.OnDataReceived := FileDnloadProviderSendData; // Responde a requisição e manda primeiro bloco.
  FFileDnloadProvider.OnDataSent     := FileDnloadProviderSendData; // Esse evento mandará os blocos subsequentes!

  FRESTprovider.CheckOrder := 0;
  FFileUploadProvider.CheckOrder := 100;
  FFileDnloadProvider.CheckOrder := 101;


end;

and the destructor
Code:
destructor TRestServer.Destroy;
begin
  Active := False;

  FRESTprovider.Free;
  FFileUploadProvider.Free;
  FFileDnloadProvider.Free;
  // As per RTC documentation
  FRestServer.Release; //#1
  FRestServer := nil;   // #2

  FUsersManagement.Free;
  FCriticalSection.Free;


  FLog.LogMsgFMT('Shutdown  %s',[DoGetServerFriendlyName]);
  FLog.Free;
  inherited;
end;

If I comment lines #1 and #2 then FastMM no longer reports a block modification after freed, but of course it reports memory leak from TRtcHttpServer.
I tried to follow the code comments to create and destroy rtc objects but I guess I missed something.
Can you help?

Thanks,
Clément



Code:

--------------------------------2017/12/3 16:31:04--------------------------------
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): 400(4)

The previous block size was: 636

This block was previously allocated by thread 0x3654, and the stack trace (return addresses) at the time was:
407492 [System.pas][System][@GetMem$qqri][4749]
4095E7 [System.pas][System][TObject.NewInstance][16913]
409E06 [System.pas][System][@ClassCreate$qqrpvzc][18246]
8ADD5A [rtcHttpSrv.pas][rtcHttpSrv][TRtcHttpServer.Create][253]
5285AD [System.SyncObjs.pas][System.SyncObjs][Syncobjs.TCriticalSection.Create][1035]
8ADD3B [rtcHttpSrv.pas][rtcHttpSrv][TRtcHttpServer.New][247]
A1EE7A [rest.server.pas][rest.server][Server.TRestServer.Create][149]
A39FEC [web.Server.pas][web.server][Server.TWebServerThread.DoBeforeMessage][70]
7C8D12 [dhs.threads.pas][DHS.Threads][Threads.TDHSThreadMessageEx.ProcessMessage][474]
7C8D35 [dhs.threads.pas][DHS.Threads][Threads.TDHSThreadMessageEx.ProcessMessage][478]
7C8BFC [dhs.threads.pas][DHS.Threads][Threads.TDHSThreadMessageEx.HandleMessage][433]

The block was previously used for an object of class: TRtcHttpServer

The allocation number was: 24208

The block was previously freed by thread 0x3654, and the stack trace (return addresses) at the time was:
4074AE [System.pas][System][@FreeMem$qqrpv][4797]
409605 [System.pas][System][TObject.FreeInstance][16922]
409E51 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][18289]
8ADE6C [rtcHttpSrv.pas][rtcHttpSrv][TRtcHttpServer.Destroy][280]
40977F [System.pas][System][TObject.Free][16985]
87BDF3 [rtcConn.pas][rtcConn][TRtcConnection.TriggerAfterDestroy][5793]
86C193 [rtcConnProv.pas][rtcConnProv][TRtcConnectionProvider.TriggerAfterDestroy][759]
86BD45 [rtcConnProv.pas][rtcConnProv][TRtcConnectionProvider.Destroy][597]
86C816 [rtcConnProv.pas][rtcConnProv][TRtcThrServerProvider.inThread][1228]
40977F [System.pas][System][TObject.Free][16985]
7CAD7D [rtcTypes.pas][rtcTypes][RtcFreeAndNil$qqrpv][321]

The current thread ID is 0x33A8, and the stack trace (return addresses) leading to this error is:
41C5F0 [FastMM4.pas][FastMM4][CheckBlocksOnShutdown$qqro][11396]
41D3A2 [FastMM4.pas][FastMM4][FinalizeMemoryManager$qqrv][12930]
41D404 [FastMM4.pas][FastMM4][Finalization$qqrv][13029]
40AFF4 [System.pas][System][FinalizeUnits$qqrv][22696]
CB76C3
76D88654 [BaseThreadInitThunk]
76FF4A47 [RtlGetAppContainerNamedObjectPath]
76FF4A17 [RtlGetAppContainerNamedObjectPath]

Current memory dump of 256 bytes starting at pointer address 7FE567B0:
6C 4C CD 00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
l  L  Í  .  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €



Title: Re: Can't find what's causing this memory report
Post by: D.Tkalcec (RTC) on December 03, 2017, 08:35:38 PM
Change your class destructor to this (code below) and let me know if you still get memory overwrites or leaks ...

Code:
destructor TRestServer.Destroy;
begin
  Active := False;

  // STOP the Server listener, BEFORE destroying ANY components linked to it, or objects used by it ...
  FRestServer.StopListenNow; //#1

  // Detach and/or destroy all components using the Server ...
  FRESTprovider.Free;
  FFileUploadProvider.Free;
  FFileDnloadProvider.Free;

  // Now, you can free the Server listener (Server stopped and all components removed/destroyed)
  FreeAndNil(FRestServer); //#2

  // Clean-up the rest ...
  FUsersManagement.Free;
  FCriticalSection.Free;

  FLog.LogMsgFMT('Shutdown  %s',[DoGetServerFriendlyName]);
  FLog.Free;
  inherited;
end;

See this Quick Start topic (https://rtcforum.teppi.net/index.php?topic=95.0) for more info.

Best Regards,
Danijel Tkalcec


Title: Re: Can't find what's causing this memory report
Post by: ClementDoss on December 03, 2017, 09:29:58 PM
And once again you solved it! Amazing!

Thank you very much,  :D
Clément