Jump to content
Alberto Paganini

Again with memory leaks and FastMM4

Recommended Posts

I have fixed all the leaks related to units I have developed but now I ran into the following:

 

--------------------------------2020/6/21 15:43:36--------------------------------
A memory block has been leaked. The size is: 36

This block was allocated by thread 0x26AC, and the stack trace (return addresses) at the time was:
404DA6 [System.pas][System][@GetMem$qqri][3454]
408BBB [System.pas][System][@NewUnicodeString$qqri][19030]
409E37 [System.pas][System][@UStrSetLength$qqrr20System.UnicodeStringi][24243]
409E8E [System.pas][System][@UStrCat$qqrr20System.UnicodeStringx20System.UnicodeString][24326]
C2B610 [IdURI.pas][IdURI][TIdURI.GetPathAndParams$qqrv][672]
C60593 [IdHttp.pas][IdHTTP][TIdCustomHTTP.PrepareRequest$qqrp21Idhttp.TIdHTTPRequest][1828]
C635FE [IdHttp.pas][IdHTTP][TIdCustomHTTP.DoRequest$qqrx20System.UnicodeString20System.UnicodeStringp22System.Classes.TStreamt3psxi][3156]
C1E193 [IdIOHandlerStack.pas][IdIOHandlerStack][TIdIOHandlerStack.Connected$qqrv][244]
C5DE5B [IdHttp.pas][IdHTTP][TIdCustomHTTP.Post$qqr20System.UnicodeStringp22System.Classes.TStreamt2][812]
C5E6E5 [IdHttp.pas][IdHTTP][TIdCustomHTTP.Post$qqr20System.UnicodeStringp23System.Classes.TStringsp22System.Classes.TStream52System.%DelphiInterface$t24Idglobal.IIdTextEncoding%][1067]
C5E804 [IdHttp.pas][IdHTTP][TIdCustomHTTP.Post$qqr20System.UnicodeStringp23System.Classes.TStrings52System.%DelphiInterface$t24Idglobal.IIdTextEncoding%][1084]

The block is currently used for an object of class: UnicodeString

The allocation number is: 58517

Current memory dump of 256 bytes starting at pointer address 7F35D810:
B0 04 02 00 01 00 00 00 0A 00 00 00 2F 00 61 00 70 00 69 00 2F 00 6C 00 6F 00 67 00 69 00 6E 00
00 00 E1 8F B9 72 80 80 00 00 00 00 F1 D8 35 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
48 E3 00 00 A6 4D 40 00 0F 6E 40 00 55 CC 40 00 7E 74 40 00 8E AA EB 00 CB 5E 73 00 09 9A EC 00
C3 FC ED 00 CB 2B 8D 00 51 64 8F 00 55 18 7B 00 AC 26 00 00 AC 26 00 00 C2 4D 40 00 2D 6E 40 00
C9 74 40 00 94 AB EB 00 BB CC 40 00 C7 CB 40 00 D5 A7 40 00 C5 A6 40 00 E3 6E 40 00 26 6E 40 00
C9 74 40 00 20 00 00 00 90 A8 EB 00 E8 0B 67 89 94 A2 F1 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 17 F4 98 76 80 80 80 80 00 00 00 00 C1 DD 35 7F
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 E3 00 00 A6 4D 40 00 0F 6E 40 00 55 CC 40 00
°  .  .  .  .  .  .  .  .  .  .  .  /  .  a  .  p  .  i  .  /  .  l  .  o  .  g  .  i  .  n  .
.  .  á  �  ¹  r  €  €  .  .  .  .  ñ  Ø  5  �  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
H  ã  .  .  ¦  M  @  .  .  n  @  .  U  Ì  @  .  ~  t  @  .  Ž  ª  ë  .  Ë  ^  s  .  .  š  ì  .
à  ü  í  .  Ë  +  �  .  Q  d  �  .  U  .  {  .  ¬  &  .  .  ¬  &  .  .  Â  M  @  .  -  n  @  .
É  t  @  .  ”  «  ë  .  »  Ì  @  .  Ç  Ë  @  .  Õ  §  @  .  Å  ¦  @  .  ã  n  @  .  &  n  @  .
É  t  @  .     .  .  .  �  ¨  ë  .  è  .  g  ‰  ”  ¢  ñ  .  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  .  ô  ˜  v  €  €  €  €  .  .  .  .  Á  Ý  5  �
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  ã  .  .  ¦  M  @  .  .  n  @  .  U  Ì  @  .


I haven't developed or amended any of the units mentioned in the report.

I strongly doubt there is a leak in the units mentioned in the report as they are either part of the VCL or part of Indy but at the same time, I don't know where I can find the leak in my code.

 

Can anybody help me?

 

Many thanks

Alberto

Share this post


Link to post
Guest

I don't have right answer for you here, as i am not versed in Indy, but you are started to debug and test your application the right way and you should be aware of two things about memory leaks, while waiting for someone with more information about that specific leak

1) you can increase the stack size in case 10 is not deep enough to reach your own code, it is one constant ( as i remember) in FastMM, just in case it is needed but rarely it does.

2) reaching your own code doesn't mean you have found the source of the leak, no.. some cases you did NOT finish or clean up in right way accordingly to that component or library, this is may be the case, as many component you need to close, deactivate (activate=false), disable..etc , before destroy.

 

Hope that helps.

Share this post


Link to post

In my personal experience, leaks pointing to some kind of a Sting routine are never the leaks you have to pay attention to. They are never the cause, they are the side effect - especially if the allocation is initiated in a in a component (let's hope 🙂 ). As @Kas Ob. said, most probably you forgot to release an instance which is keeping the reference count high. Unless if you are playing with reference counts yourself, that is.

And again supporting the statement above mine - I never had a leak which could be fixed in the same method. Because of messed up design, sometimes releasing the object had to go to a different unit!

 

Always handle allocation call stacks as a pointer only. You have to know what was allocated and why - and when that specific instance can be released.

Share this post


Link to post

maybe a non-graceful exit? maybe there were running some indy threads in the background?

the leaked string is in the dump, reference count: 1, string: "/api/login"

 

btw. debugging session could also lead to leaked strings.

 

 

 

 

Edited by Attila Kovacs

Share this post


Link to post
19 minutes ago, Attila Kovacs said:

maybe a non-graceful exit?

 

 

 

 

This is something I am rather sure not to be the case as I avoid exits as much as possible. I will check these too though.

 

I am running the application step by step and see the objects created at run time and see where/if they are released.

 

Thanks everybody for your help

Alberto

Edited by Alberto Paganini

Share this post


Link to post
Guest
Quote

C2B610 [IdURI.pas][IdURI][TIdURI.GetPathAndParams$qqrv][672]
C60593 [IdHttp.pas][IdHTTP][TIdCustomHTTP.PrepareRequest$qqrp21Idhttp.TIdHTTPRequest][1828]
C635FE [IdHttp.pas][IdHTTP][TIdCustomHTTP.DoRequest$qqrx20System.UnicodeString20System.UnicodeStringp22System.Classes.TStreamt3psxi][3156]

From that, you can find what to trace, DoRequest called PrepareRequest then GetPathAndParams, the string leak came from GetPathAndParams, but it is not a leak as much as not freed, because it is attached to a request,

So your question should be What is the fate of that request (TIdHTTPRequest) ?

Is it done, finished, canceled, freed...?

 

Did you called disconnect or close on IdHttp, i have no idea what it should be, but i am sure either it ( mean abort or cancel) will be called automatically from within destructor or you should do it manually, just something to check.

 

Share this post


Link to post
 
 
 
🤓
2
15 hours ago, Kas Ob. said:

Did you called disconnect or close on IdHttp, i have no idea what it should be, but i am sure either it ( mean abort or cancel) will be called automatically from within destructor or you should do it manually, just something to check.

 

I moved FreeAndNil(IdHttp) from the Destructor to the procedure where IdHttp is created and no more leaks. This suggests a bad design of the class (I made it) and I will look into that again because it seems the destructor is not invoked.

I double-checked and in the declaration section and the destructor has override in it, correctly.

Share this post


Link to post
1 hour ago, Lars Fosdal said:

Did the inherited destructor remember to call inherited?

Yes, the following is the destructor now

 

destructor TBetFairApi.Destroy;
begin
//if Assigned(FList) then
//  FList.Free;
//  if Assigned(FidHTTP) then
//    FidHTTP.Free;
//  {$IFDEF VER230}
//  if Assigned(FIdSSL) then
//
//  FIdSSL.Free;
//  {$ENDIF}
  inherited Destroy;
end;

 

before the code was not commented on.
 

Share this post


Link to post

Free is implemented as if Assigned(Foo) then Foo.Destroy; so those if statements in the previous post are pointless. Call Free unconditionally. 

  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×