Recent

Author Topic: Memory Leak with CORBA Interface  (Read 880 times)

janasoft

  • New Member
  • *
  • Posts: 40
Memory Leak with CORBA Interface
« on: September 06, 2024, 08:13:41 pm »
I'm studying the use of interfaces and I think I'm not doing something right because when I run this code I get a memory leak
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$INTERFACES CORBA}
  5.  
  6. uses
  7.   SysUtils;
  8.  
  9.   type
  10.     IMyInterface = interface
  11.     ['{79352612-668B-4E8C-910A-26975E103CAC}']
  12.       procedure Shoot;
  13.     end;
  14.  
  15.     TMyClass1 = class(TObject, IMyInterface)
  16.       procedure Shoot;
  17.     end;
  18.  
  19.    procedure TMyClass1.Shoot;
  20.    begin
  21.      WriteLn('TMyClass1.Shoot');
  22.    end;
  23.  
  24.   var
  25.     I1:IMyInterface;
  26.  
  27.  begin
  28.    SetHeapTraceOutput('heap.trc');
  29.  
  30.    I1 := TMyClass1.Create;
  31. //   I1 := (TMyClass1.Create) as IMyInterface;
  32.    I1.Shoot;
  33.    I1:= nil;
  34. end.

Code: Pascal  [Select][+][-]
  1. D:\Lazarus_Proyectos\Pruebas\Temp\project1.exe
  2. Heap dump by heaptrc unit of D:\Lazarus_Proyectos\Pruebas\Temp\project1.exe
  3. 97 memory blocks allocated : 3491/3800
  4. 96 memory blocks freed     : 3475/3784
  5. 1 unfreed memory blocks : 16
  6. True heap size : 196608 (160 used in System startup)
  7. True free heap : 196224
  8. Should be : 196240
  9. Call trace for block $00000000015FBD40 size 16
  10.   $0000000100008DB2
  11.   $00000001000072FA
  12.   $0000000100007195
  13.   $000000010000179B  $main,  line 40 of project1.lpr
  14.   $00000001000017E6
  15.   $000000010000DE20
  16.   $0000000100001700
  17.   $00007FF863917374
  18.   $00007FF863C9CC91
  19.   $BAADF00DBAADF00D
  20.   $BAADF00DBAADF00D
  21.   $BAADF00DBAADF00D
  22.   $BAADF00DBAADF00D
  23.   $BAADF00DBAADF00D
  24.   $BAADF00DBAADF00D
  25.   $BAADF00DBAADF00D

If I use the comment code I get the same result

What I'm doing wrong?

Regards
Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-win64-win32/win64

korba812

  • Sr. Member
  • ****
  • Posts: 417
Re: Memory Leak with CORBA Interface
« Reply #1 on: September 06, 2024, 08:34:55 pm »
CORBA-type interfaces do not have reference counting, unlike COM-type interfaces.
https://www.freepascal.org/docs-html/3.2.0/ref/refse49.html

janasoft

  • New Member
  • *
  • Posts: 40
Re: Memory Leak with CORBA Interface
« Reply #2 on: September 06, 2024, 09:05:04 pm »
Quote
CORBA-type interfaces do not have reference counting, unlike COM-type interfaces.
I know. That's why I asign: I1:= nil before leaving the program.
I supose that this is not the correct way to free the interface.
I've tried with FreeAndNil but I get an AV
Regards
Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-win64-win32/win64

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11780
  • FPC developer.
Re: Memory Leak with CORBA Interface
« Reply #3 on: September 06, 2024, 09:35:43 pm »
(l1 as tcomponent).free;

janasoft

  • New Member
  • *
  • Posts: 40
Re: Memory Leak with CORBA Interface
« Reply #4 on: September 06, 2024, 10:28:41 pm »
Quote
(l1 as tcomponent).free;
Why TComponent?
Anyway i've tried (I1 as TObject).Free, but doesn´t compile
Casting in this way: TObject(I1), gives an AV
Regards
Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-win64-win32/win64

cdbc

  • Hero Member
  • *****
  • Posts: 1534
    • http://www.cdbc.dk
Re: Memory Leak with CORBA Interface
« Reply #5 on: September 06, 2024, 10:58:27 pm »
Hi
The quick'n'dirty:
Code: Pascal  [Select][+][-]
  1.   type
  2.     IMyInterface = interface
  3.     ['{79352612-668B-4E8C-910A-26975E103CAC}']
  4.       procedure Free;
  5.       procedure Shoot;
  6.     end;
Free is implemented in TObject.
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

korba812

  • Sr. Member
  • ****
  • Posts: 417
Re: Memory Leak with CORBA Interface
« Reply #6 on: September 06, 2024, 11:00:32 pm »
(l1 as tcomponent).free;
I'm not sure if this will work with CORBA interfaces, since CORBA interfaces are not bound to IUnknown like COM interfaces are.

cdbc

  • Hero Member
  • *****
  • Posts: 1534
    • http://www.cdbc.dk
Re: Memory Leak with CORBA Interface
« Reply #7 on: September 06, 2024, 11:06:19 pm »
Hi
Quote
I'm not sure if this will work with CORBA interfaces
It doesn't, tried and error'ed with that myself.
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

jamie

  • Hero Member
  • *****
  • Posts: 6580
Re: Memory Leak with CORBA Interface
« Reply #8 on: September 06, 2024, 11:28:02 pm »
Works fine if you create the item local to your procedure. the FREE member shows and works as it should.

The compiler for some reason isn't seeing the instance like that outside of the procedure call.

The only true wisdom is knowing you know nothing

janasoft

  • New Member
  • *
  • Posts: 40
Re: Memory Leak with CORBA Interface
« Reply #9 on: September 07, 2024, 12:28:19 am »
Hi
The quick'n'dirty:
Code: Pascal  [Select][+][-]
  1.   type
  2.     IMyInterface = interface
  3.     ['{79352612-668B-4E8C-910A-26975E103CAC}']
  4.       procedure Free;
  5.       procedure Shoot;
  6.     end;
Benny, this works fine. But does it mean that all corba interface must implement a Free Method?
I haven't read about it in any documentation
Regards.
« Last Edit: September 07, 2024, 12:30:11 am by janasoft »
Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-win64-win32/win64

cdbc

  • Hero Member
  • *****
  • Posts: 1534
    • http://www.cdbc.dk
Re: Memory Leak with CORBA Interface
« Reply #10 on: September 07, 2024, 12:53:02 am »
Hi
Well, that entirely depends on the use case, but the key point is: You are responsible for the memory management! How you do that, is totally up to you.
In this thread @ #68 there's some more explaining...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Thaddy

  • Hero Member
  • *****
  • Posts: 15722
  • Censorship about opinions does not belong here.
Re: Memory Leak with CORBA Interface
« Reply #11 on: September 07, 2024, 07:36:45 am »
One other important thing to note is that you use a guid, which although it is allowed, does not work like a guid, it works as a string. With corba style interfaces, using guids, which are really not guids can confuse you.
https://www.freepascal.org/docs-html/ref/refse50.html
More in general, you should not use memory management over a CORBA interface but over the class itself, using Tobject.create and Tobject.free. The use of CORBA interfaces is usually not recommended for beginners and its use case is very limited as opposed to COM. Almost all interface examples in FreePascal or Delphi assume COM, which makes good use of CORBA interfaces hard to find.In your own example, when the interface was declared as COM your code would work as expected: instantiation to an interface variable and releasing it by setting to nil is COM and works. With CORBA you instatiate to a Tobject descendant and free the object by Tobject.free.Again, using a GUID is really not CORBA, it works somewhat, and only by accident since it is interpreted as a string, not GUID.
So better use a string identifier that does not look like a guid, because it is not a guid at all.
It will only confuse your code further. If you are a beginner, stay away from CORBA.
« Last Edit: September 07, 2024, 07:41:15 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

cdbc

  • Hero Member
  • *****
  • Posts: 1534
    • http://www.cdbc.dk
Re: Memory Leak with CORBA Interface
« Reply #12 on: September 07, 2024, 08:05:42 am »
Hi
That's a dang good writeup Thaddy, good link too, I never found that, but had to learn it the hard way  %)
...And I think you've covered all the 'Gotcha's  8)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Thaddy

  • Hero Member
  • *****
  • Posts: 15722
  • Censorship about opinions does not belong here.
Re: Memory Leak with CORBA Interface
« Reply #13 on: September 07, 2024, 09:03:39 am »
I thought to add a CORBA example.
Here I use a CORBA  interface that exposes code that is otherwise hidden from use.
Also shows how CORBA memory management is handled. (not!)
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$interfaces corba}
  2. uses
  3.   sysutils; // for supports(), that works for CORBA too.
  4. type
  5.   ITest = interface
  6.   ['ITest']
  7.     procedure Show;
  8.   end;
  9.    
  10.   TTest = class(TObject, ITest)
  11.   strict private
  12.     procedure Show;
  13.   end;
  14.  
  15.   procedure TTest.Show;
  16.   begin
  17.     writeln('test');
  18.   end;
  19.  
  20. var
  21.   T:TTest;
  22.   I:ITest;
  23. begin
  24.   T:=TTest.create;
  25.   { note that CORBA is case sensitive! }
  26.   { this fails: Supports(T, 'itest' }
  27.   writeln(Supports(T,'ITest'));
  28.   I:=T;
  29.   { T.show; will not work }
  30.   { I.show will work }
  31.   I.Show;
  32. { CORBA interfaces are assignment compatible to string, not TGUID }
  33.   writeln(string(I));
  34.   T.free;
  35.   readln;
  36. end.
1. The memory management is handled through T (create, free )
2. The show method is exposed by assignment of the class variable T to the interface variable I
3. Since the interface is not reference counted, there is no memory management involved on the interface
4. CORBA interface names are case sensitive and not TGUIDS, they can be assigned to a string.
5. Supports() works,  as works one way - through Tobject.getinterfacestr -  is won't work.
6. Although creating to the interface variable I is allowed, that is usually a bug, since you can not call free on the interface variable and even a hardcast will fail. (try it... 8-) )
Let's demo that:
Code: Pascal  [Select][+][-]
  1. var
  2.   T:TTest;
  3.   I:ITest;
  4. begin
  5.   I:=TTest.create; // works, is a bug when using CORBA style interfaces
  6.   I.Show;
  7.   //T:= I  // because this does not work
  8.   //T.free;// so you can not do this
  9.   // and we have a leak..
  10.   // since this is not allowed T:=TTest(I);
  11.   // nor this: (I as TTest).Free;
  12.   // nor this TTest(I).Free; // this compiles but crashes.
  13. end.


Just like using COM interfaces properly requires discipline, CORBA is no different and also requires discipline. Never mix up the two paradigms.
« Last Edit: September 07, 2024, 01:43:33 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Thaddy

  • Hero Member
  • *****
  • Posts: 15722
  • Censorship about opinions does not belong here.
Re: Memory Leak with CORBA Interface
« Reply #14 on: September 07, 2024, 04:23:01 pm »
All of this was not necessary if the wiki entry was correct, which it isn't: it makes most if not all of the mistakes as outlined above.
When given time I will rewrite that:
https://wiki.freepascal.org/Interfaces <----- this is very wrong and should be done again; properly.
It displays a thorough misunderstanding about how CORBA interfaces work. Actually how both types of interfaces work.
Since the author is an esteemed member, I will not change it without his consent, but I suggest an explanation along the lines as I have expressed above. And that is the correct interpretation.
I did open a discussion subject for that in the wiki.
« Last Edit: September 07, 2024, 04:29:58 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

 

TinyPortal © 2005-2018