Re: [fpc-pascal] Where and Why is there a memory leak?
Am 07.09.2017 03:48 schrieb "Ryan Joseph" : > > > > On Sep 6, 2017, at 10:20 PM, Sven Barth via fpc-pascal < fpc-pascal@lists.freepascal.org> wrote: > > > > You're missing that FHook was declared as IHook, not THook. > > > > In terms of memory why does it matter how it was declared? The memory was allocated in Create() so the declaration is just relevant for the assignment of the new memory. Is FPC doing something magic behind the scenes? a) since it's an interface it doesn't *have* a Free method b) COM interfaces are reference counted and the compiler (both Delphi and FPC) does automatic reference counting with them (that's the purpose of TInterfacedObject, it calls Free on itself once the reference count reaches 0) Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On Wed, Sep 6, 2017 at 10:17 PM, Ryan Joseph wrote: > >> On Sep 6, 2017, at 10:20 PM, Sven Barth via fpc-pascal >> wrote: >> >> You're missing that FHook was declared as IHook, not THook. >> > > In terms of memory why does it matter how it was declared? The memory was > allocated in Create() so the declaration is just relevant for the assignment > of the new memory. Is FPC doing something magic behind the scenes? > Because COM interface variables are automatically released. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
> On Sep 6, 2017, at 10:20 PM, Sven Barth via fpc-pascal > wrote: > > You're missing that FHook was declared as IHook, not THook. > In terms of memory why does it matter how it was declared? The memory was allocated in Create() so the declaration is just relevant for the assignment of the new memory. Is FPC doing something magic behind the scenes? Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
On 09/06/2017 05:21 PM, Marc Santhoff wrote: On Mi, 2017-09-06 at 23:06 +0200, Bo Berglund wrote: On Wed, 06 Sep 2017 22:52:12 +0200, Bo Berglund wrote: I have now added extra binary logging to the relaying program only to find that the data received and processed are missing about 50 k of the 1M transmission. Next I will edit serial.pp and up the buffers from 2K to 60K or so. By the way: I have sent the Delphi test program I am debugging over to people at the remote location and they have connected their laptop directly to the data system and with that setup there is no data loss. So this leaves me with only the Lazarus/FPC network relaying app to fix... Could that be some sort of timeout? You're setting FTcpComm.ReadTimeout := 30; but I have no idea what order of magnitude this 30 is. Maybe streching the timeout a little bit can help? I had several cases of timeout problems using RS232 over TCP. I could also create another test program, a serial sniffer that could be set up to just log whatever appears on the serial lines. I need a 3-way cable for that of course. Such thing does exists, I only forgot the name(s), ;) HTH, Marc There are two links in the bottom paragraph on this page: http://ctrlterm.com/custom.htm Regards, Paul www.ControlPascal.com ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
El 06/09/2017 a las 21:22, Bo Berglund escribió: Inc(RxTcp, Length(Buf)); SerWrite(FComH, Buf[0], Length(Buf)); Inc(TxSer, Length(Buf)); Where could I be losing incoming serial data? Hello, Where do you check that "Length(Buf)" has been sent ? if SerWrite(FComH, Buf[0], Length(Buf))<>Length(Buf) then Raise Exception.Create("KBOOM"); -- ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
On Mi, 2017-09-06 at 23:06 +0200, Bo Berglund wrote: > On Wed, 06 Sep 2017 22:52:12 +0200, Bo Berglund > wrote: > > >I have now added extra binary logging to the relaying program only to > >find that the data received and processed are missing about 50 k of > >the 1M transmission. > >Next I will edit serial.pp and up the buffers from 2K to 60K or so. > > By the way: > I have sent the Delphi test program I am debugging over to people at > the remote location and they have connected their laptop directly to > the data system and with that setup there is no data loss. > So this leaves me with only the Lazarus/FPC network relaying app to > fix... Could that be some sort of timeout? You're setting FTcpComm.ReadTimeout := 30; but I have no idea what order of magnitude this 30 is. Maybe streching the timeout a little bit can help? I had several cases of timeout problems using RS232 over TCP. > I could also create another test program, a serial sniffer that could > be set up to just log whatever appears on the serial lines. I need a > 3-way cable for that of course. Such thing does exists, I only forgot the name(s), ;) HTH, Marc ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
On Wed, 06 Sep 2017 22:52:12 +0200, Bo Berglund wrote: >I have now added extra binary logging to the relaying program only to >find that the data received and processed are missing about 50 k of >the 1M transmission. >Next I will edit serial.pp and up the buffers from 2K to 60K or so. By the way: I have sent the Delphi test program I am debugging over to people at the remote location and they have connected their laptop directly to the data system and with that setup there is no data loss. So this leaves me with only the Lazarus/FPC network relaying app to fix... I could also create another test program, a serial sniffer that could be set up to just log whatever appears on the serial lines. I need a 3-way cable for that of course. -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
On Wed, 06 Sep 2017 22:52:12 +0200, Bo Berglund wrote: >Next I will edit serial.pp and up the buffers from 2K to 60K or so. Question: If I edit the content of serial.pp (the one that is brought up by right clicking and "Find declaration") such that it looks like this: const bufSize= 61440; //2048; will it be used the next time I test run my application or must I do some kind of "installation" like updating Lazarus or similar for it to be used? -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
On Wed, 06 Sep 2017 22:27:49 +0200, Marc Santhoff wrote: >On Mi, 2017-09-06 at 21:22 +0200, Bo Berglund wrote: >> Where could I be losing incoming serial data? > >Only for completeness: > >Can you rule out problems reagrding the hardware side? Mabe there are >some weak line drivers or a faulty cable involved? > >Worth checking, at least. > Well, I am using a 4-way USB to Serial unit and the cable (nullmodem) connects two adjacent ports and is about 50 mm long... This cable has never failed ever before. I have now added extra binary logging to the relaying program only to find that the data received and processed are missing about 50 k of the 1M transmission. Next I will edit serial.pp and up the buffers from 2K to 60K or so. -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
On Mi, 2017-09-06 at 21:22 +0200, Bo Berglund wrote: > Where could I be losing incoming serial data? Only for completeness: Can you rule out problems reagrding the hardware side? Mabe there are some weak line drivers or a faulty cable involved? Worth checking, at least. HTH anyhow, Marc ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
On Wed, 6 Sep 2017 18:58:57 +, Mark Morgan Lloyd wrote: >> Is there some hidden property that makes it possible to increase thisvalue? >>What is the maximum size one can set it too? > >Not that I was responsible for. Refer to the Windows API for any limits. I might add that the problem manifests itself on transmission from the Windows application (Delphi XE5). I.e. the relaying Lazarus/FPC application loses incoming bytes after some time of processing the streams. Small data sizes work just fine but with the 1 Mbytes packet some kbytes are lost. And here is the core procedure where the relaying happens: procedure TfrmMain.RelayData; {This procedure is responsible for transferring the data from one side to the other. It will run until one of the ports are closed as indicated by the flags FTcpConnected and FComOpen} var Buf: TIdBytes; LenRd, BufLen: integer; RxSer, TxSer, RXTcp, TxTcp: integer; begin RxSer := 0; TxSer := 0; RxTcp := 0; TxTcp := 0; BufLen := 50; FTcpComm.ReadTimeout := 30; while (FComOpen and FTcpConnected and FRelayOn) do begin //First check TCP data try SetLength(Buf, 0); if FTcpComm.IOHandler.CheckForDataOnSource(10) then begin FTcpComm.IOHandler.ReadBytes(Buf, -1, false); if Length(Buf) > 0 then begin Inc(RxTcp, Length(Buf)); SerWrite(FComH, Buf[0], Length(Buf)); Inc(TxSer, Length(Buf)); LogHex('Rx', Buf); SetLength(Buf, 0); end; end; except on E: Exception do Showmessage('TCP read exception: '#13 + E.Message); end; //Next check serial data SetLength(Buf, BufLen); LenRd := SerRead(FComH, Buf[0], BufLen); if LenRd > 0 then begin SetLength(Buf, LenRd); Inc(RxSer, LenRd); try FTcpComm.IOHandler.Write(Buf, LenRd); Inc(TxTcp, LenRd); LogHex('Tx', Buf); SetLength(Buf, 0); except on E: Exception do Showmessage('TCP write exception: '#13 + E.Message); end; end; //Finally show data and check events stxSerRx.Caption := IntToStr(RxSer); stxSerTx.Caption := IntToStr(TxSer); stxTcpRx.Caption := IntToStr(RxTcp); stxTcpTx.Caption := IntToStr(TxTcp); Application.ProcessMessages; end; end; Where could I be losing incoming serial data? -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
On 06/09/17 18:45, Bo Berglund wrote: I have created a simple application which relays data from anapplication I am debugging in Windows7 to/from a remotely locatedembedded data system.I use the built-in fpc Serial unit to handle the serial data and anIndy10 TIdTcpClient for the network part.Data coming in on the serial port are mirrored out to the remote TCPserver and data returned from that server are mirrored to the serialport.The Windows application only uses RS232 for this type ofcommunication.At the remote location I have a Raspberry Pi uint where I haveinstalled and configured ser2net to do the same job in the remotelocation. My relaying application displays the number of bytes received andtransmitted on the interfaces so I can see what is going on. This scheme has worked fine for most commands and data transfers Ihave checked, but now I have run against a brick wall... There is a pair of commands designed to read and write a large sectionof the system CMOS RAM memory (where the data file system resides).When I try to write a 1 Mbytes big buffer the byte count in my relayerdoes not reach the correct number. The Windows application I amdebugging sends all of the bytes out the serial port (I have loggedthis), but the relayer seems to lose some data and therefore thetransfer fails. The binary protocol specifies at the start how manybytes are to be transferred (0x0FF000 or 1044486 decimal), then itsends the data followed by a two-byte checksum. The data system shallrespond with NAK or ACK depending on the outcome of the checksumverification.The problem is that when the Windows app is done sending the datasystem is still missing many kilobytesSo no ACK is returned, it is still in receive mode. Now I am looking at the Serial unit in order to figure out how buffersizes influence the performance. Apparently both Tx and Rx buffers areset (hardcoded) to 2048, which feels like a bit low to me. Is there some hidden property that makes it possible to increase thisvalue?What is the maximum size one can set it too? Not that I was responsible for. Refer to the Windows API for any limits. -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
[fpc-pascal] Using Serial in a TCP/RS232 gateway, how to set buffer sizes?
I have created a simple application which relays data from an application I am debugging in Windows7 to/from a remotely located embedded data system. I use the built-in fpc Serial unit to handle the serial data and an Indy10 TIdTcpClient for the network part. Data coming in on the serial port are mirrored out to the remote TCP server and data returned from that server are mirrored to the serial port. The Windows application only uses RS232 for this type of communication. At the remote location I have a Raspberry Pi uint where I have installed and configured ser2net to do the same job in the remote location. My relaying application displays the number of bytes received and transmitted on the interfaces so I can see what is going on. This scheme has worked fine for most commands and data transfers I have checked, but now I have run against a brick wall... There is a pair of commands designed to read and write a large section of the system CMOS RAM memory (where the data file system resides). When I try to write a 1 Mbytes big buffer the byte count in my relayer does not reach the correct number. The Windows application I am debugging sends all of the bytes out the serial port (I have logged this), but the relayer seems to lose some data and therefore the transfer fails. The binary protocol specifies at the start how many bytes are to be transferred (0x0FF000 or 1044486 decimal), then it sends the data followed by a two-byte checksum. The data system shall respond with NAK or ACK depending on the outcome of the checksum verification. The problem is that when the Windows app is done sending the data system is still missing many kilobytes So no ACK is returned, it is still in receive mode. Now I am looking at the Serial unit in order to figure out how buffer sizes influence the performance. Apparently both Tx and Rx buffers are set (hardcoded) to 2048, which feels like a bit low to me. Is there some hidden property that makes it possible to increase this value? What is the maximum size one can set it too? -- Bo Berglund Developer in Sweden ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On 2017-09-06 16:27, Tony Whyman wrote: Is history repeating itself: Quite likely. It did all sound awfully familiar. :-) I've now [finally] added this to my "Personal Programming Notes" archive (yes, I actually have such a file). So hopefully now I will not forget about the gotcha of memory leaks and reference counted objects. Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On Wed, 6 Sep 2017, Tony Whyman wrote: Is history repeating itself: http://lists.freepascal.org/pipermail/fpc-pascal/2016-August/048579.html Any historian will confirm this :) Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
Is history repeating itself: http://lists.freepascal.org/pipermail/fpc-pascal/2016-August/048579.html On 06/09/17 09:31, Graeme Geldenhuys wrote: Hi, Playing with this small sample application to answer another question in this mailing list, I noticed the sample application has a memory leak. For the life of me I can't see why or how to resolve it. I tested with FPC 2.6.4, 3.0.2 and 3.0.4-rc1 under 64-bit FreeBSD. ===[ project1.pas ] program project1; {$mode objfpc}{$H+} {$interfaces COM} type IHook = interface ['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}'] procedure DoIt; end; type THook = class(TInterfacedObject, IHook) private procedure DoIt; end; procedure THook.DoIt; begin writeln(ClassName + ' did it'); end; type TBaseClass = class(TInterfacedObject, IHook) private FHook: IHook; property Hook: IHook read FHook implements IHook; public constructor Create; destructor Destroy; override; end; constructor TBaseClass.Create; begin FHook := THook.Create; // FPC 2.6.4 reports a memory leak here end; destructor TBaseClass.Destroy; begin // nothing to do here end; var base: IHook; begin base := TBaseClass.Create; base.DoIt; base := nil; // just to see if it helped with the memory leak - it doesn't end. ==[ end ]== When I run the program, the output is as follows: [t1]$ ./project1 THook did it Heap dump by heaptrc unit 4 memory blocks allocated : 115/120 2 memory blocks freed : 51/56 2 unfreed memory blocks : 64 True heap size : 1114112 (32 used in System startup) True free heap : 1113696 Should be : 1113760 Call trace for block $00080072F180 size 32 $00400379 line 35 of project1.lpr Call trace for block $00080072F0C0 size 32 Personally I always use CORBA style interfaces, never reference counted COM style interfaces. So my programs normally don't have this issue, and I use interfaces a lot. Regards, Graeme ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
Am 06.09.2017 17:03 schrieb "Ryan Joseph" : > > > > On Sep 6, 2017, at 8:03 PM, Graeme Geldenhuys < mailingli...@geldenhuys.co.uk> wrote: > > > > I couldn't call .Free because FHook was a interface reference type of type IHook, not THook. > > But TInterfacedObject is a class isn’t it? Then you call FHook := THook.Create; so a I’d expect a Free(). What am I missing? > > type > THook = class(TInterfacedObject, IHook) > private >procedure DoIt; > end; You're missing that FHook was declared as IHook, not THook. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
> On Sep 6, 2017, at 8:03 PM, Graeme Geldenhuys > wrote: > > I couldn't call .Free because FHook was a interface reference type of type > IHook, not THook. But TInterfacedObject is a class isn’t it? Then you call FHook := THook.Create; so a I’d expect a Free(). What am I missing? type THook = class(TInterfacedObject, IHook) private procedure DoIt; end; Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On 2017-09-06 11:33, Marcos Douglas B. Santos wrote: You have resolved just by change FHookInstance as a class, not an Interface, plus using TAggregatedObject too. Ah yes, that seems to work too. Many thanks for pointing that out. So here is another implementation that works with NO memory leaks. [ project1.pas ] program project1; {$mode objfpc}{$H+} {$interfaces COM} type IHook = interface ['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}'] procedure DoIt; end; type THook = class(TAggregatedObject, IHook) private procedure DoIt; end; procedure THook.DoIt; begin writeln(ClassName + ' did it'); end; type TBaseClass = class(TInterfacedObject, IHook) private FHookInstance: THook; property Hook: THook read FHookInstance implements IHook; public constructor Create; destructor Destroy; override; end; constructor TBaseClass.Create; begin inherited Create; FHookInstance := THook.Create(self); end; destructor TBaseClass.Destroy; begin FHookInstance.Free; inherited Destroy; end; var base: IHook; begin base := TBaseClass.Create; base.DoIt; end. ==[ end ]=== Yeah, just as I said Interfaces are an advanced feature of the Object Pascal language. Lots of traps! Bottom line: NEVER code without enabling memory leak detection!!! :) Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On 2017-09-06 10:30, Ryan Joseph wrote: FHook := THook.Create; so you need a FHook.Free call? The class is THook = class(TInterfacedObject, IHook) right? I couldn't call .Free because FHook was a interface reference type of type IHook, not THook. Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On Wed, Sep 6, 2017 at 6:55 AM, Graeme Geldenhuys < mailingli...@geldenhuys.co.uk> wrote: > > I can't remember ever [while using Delphi] being forced to implement a > getter method in the "property ... implements..." line, but it seems that > is the only way it remove memory leaks under FPC. Weird. :-/ You don't need this getter. You have resolved just by change FHookInstance as a class, not an Interface, plus using TAggregatedObject too. I wrote an article about it http://objectpascalprogramming.com/posts/interfaces-delegacao-problemas-solucoes/ (use Google Translator). Best regards, Marcos Douglas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On 2017-09-06 10:55, Graeme Geldenhuys wrote: On 2017-09-06 10:41, Sven Barth via fpc-pascal wrote: I think THook needs to derive from TAggregatedObject, cause that couples the reference counting to that of the controlling instance. That seems to be heading in the right direction, but such a change on its own doesn't seem to solve the two memory leaks either. I'll test under Delphi XE which can report memory leaks to see what it does Testing with Delphi XE - simply by changing THook to descend from TAggregatedObject. Under Delphi it also still reports a memory leak. Either way, modifying the example to use a getter method AND TAggregatedObject, I managed to get rid of both memory leaks. Here is the working [memory leak free] code now: Under Delphi XE, that was the only way to get rid of the memory leaks too. So it seems for delegation and using "implements" you are forced to use a getter method and object variable (not interface reference variable) - under both FPC and Delphi. At least they are consistent. ;-) ps: For those that didn't know Since Delphi 2006, add ReportMemoryLeaksOnShutdown := True; in your *.dpr file to enable memory leak detection. Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
Didn’t you say: FHook := THook.Create; so you need a FHook.Free call? The class is THook = class(TInterfacedObject, IHook) right? > On Sep 6, 2017, at 4:24 PM, Graeme Geldenhuys > wrote: > > I changed the destructor to the code shown below. Just so you know, I tried > this before I posted the message, and it didn't make any difference. FHook is > a IHook interface reference, not a object reference. I can't change it > either, otherwise FPC gives me a compiler error on the property ... > implements...; line. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
> On Sep 6, 2017, at 4:55 PM, Graeme Geldenhuys > wrote: > > Either way, modifying the example to use a getter method AND > TAggregatedObject, I managed to get rid of both memory leaks. Here is the > working [memory leak free] code now: Does the original code work if you just add the Free() call? I would expect it to leak without that. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On 2017-09-06 10:41, Sven Barth via fpc-pascal wrote: I think THook needs to derive from TAggregatedObject, cause that couples the reference counting to that of the controlling instance. That seems to be heading in the right direction, but such a change on its own doesn't seem to solve the two memory leaks either. I'll test under Delphi XE which can report memory leaks to see what it does with that same code. So this might end up being a bug in FPC somewhere. Either way, modifying the example to use a getter method AND TAggregatedObject, I managed to get rid of both memory leaks. Here is the working [memory leak free] code now: ===[ project1.pas ]=== program project1; {$mode objfpc}{$H+} {$interfaces COM} type IHook = interface ['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}'] procedure DoIt; end; type THook = class(TAggregatedObject, IHook) private procedure DoIt; end; procedure THook.DoIt; begin writeln(ClassName + ' did it'); end; type TBaseClass = class(TInterfacedObject, IHook) private FHookInstance: THook; function GetHook: IHook; property Hook: IHook read GetHook implements IHook; public destructor Destroy; override; end; function TBaseClass.GetHook: IHook; begin if FHookInstance = nil then FHookInstance := THook.Create(self); Result := FHookInstance; end; destructor TBaseClass.Destroy; begin FHookInstance.Free; inherited Destroy; end; var base: IHook; begin base := TBaseClass.Create; base.DoIt; base := nil; // just to see if it helped with the memory leak - it doesn't end. [ end ]=== And the program output: [t1]$ ./project1 THook did it Heap dump by heaptrc unit 4 memory blocks allocated : 107/112 4 memory blocks freed : 107/112 0 unfreed memory blocks : 0 True heap size : 1114112 (32 used in System startup) True free heap : 1114080 I can't remember ever [while using Delphi] being forced to implement a getter method in the "property ... implements..." line, but it seems that is the only way it remove memory leaks under FPC. Weird. :-/ Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
Am 06.09.2017 10:31 schrieb "Graeme Geldenhuys" < mailingli...@geldenhuys.co.uk>: > type > IHook = interface > ['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}'] > procedure DoIt; > end; > > type > THook = class(TInterfacedObject, IHook) > private > procedure DoIt; > end; > > procedure THook.DoIt; > begin > writeln(ClassName + ' did it'); > end; I think THook needs to derive from TAggregatedObject, cause that couples the reference counting to that of the controlling instance. See here: http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Implementing_Interfaces Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] implements
On 2017-09-06 09:03, Ryan Joseph wrote: For the sake of discussion can you see why it makes sense that “hook.” syntax would be implied because the class does indeed supposedly implement the interface? Everything about the syntax says that the methods in IHook should be in TBaseClass so I can’t help but feel like it was an omission or not fully finished. "implements" in that example says that the implementation of the IHook interface is delegated to another class - THook. If you didn't define the property... implements in TBaseClass, then TBaseClass would have had to explicitly implement all methods of IHook. The implements means you can reuse the IHook implementation (thanks to THook) in many other classes too. Granted I personally don't like the syntax for "implements", but that's what Borland came up with for Delphi, and FPC follows that syntax for compatibility reasons. The other annoying thing of Object Pascal's Interface support is that you need to specify which interfaces you implement, even in descendant classes where the parent already implements a specific interface. But that's a whole other discussion. ;-) Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] implements
Am 06.09.2017 10:34 schrieb "Ryan Joseph" : > > > > On Sep 6, 2017, at 2:50 PM, Graeme Geldenhuys < mailingli...@geldenhuys.co.uk> wrote: > > > > There is NO need to make Hook public, because you can always get access to that functionality via the Supports() call and get a reference to IHook. > > The Supports() call is the key takeaway here. > > For the sake of discussion can you see why it makes sense that “hook.” syntax would be implied because the class does indeed supposedly implement the interface? Everything about the syntax says that the methods in IHook should be in TBaseClass so I can’t help but feel like it was an omission or not fully finished. It would be messy to implement probably because you would risk a number of name collisions with existing methods. No it's definitely by design. If you use alias clauses ("procedure IMyIntf.Foobar = Blubb") then you also won't have the interface's method in your class, but only the alias. The method can only be accesssed by the interface's method name by using an interface instance not the class instance. The "implements" clause is just an advanced variant of that in that it allows you to use a complete class (though you're still able to implement selected methods of the interface in the base class which aren't delegated then). Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On 2017-09-06 09:37, Michael Van Canneyt wrote: type TBaseClass = class(TInterfacedObject, IHook) private FHook: IHook; property Hook: IHook read FHook implements IHook; public constructor Create; destructor Destroy; override; end; constructor TBaseClass.Create; begin FHook := THook.Create; // FPC 2.6.4 reports a memory leak here end; destructor TBaseClass.Destroy; begin // nothing to do here end; You must free FHook here, because you are keeping a reference to the object, not the interface. I changed the destructor to the code shown below. Just so you know, I tried this before I posted the message, and it didn't make any difference. FHook is a IHook interface reference, not a object reference. I can't change it either, otherwise FPC gives me a compiler error on the property ... implements...; line. destructor TBaseClass.Destroy; begin inherited; FHook := nil; end; And the program output gives: [t1]$ ./project1 THook did it Heap dump by heaptrc unit 4 memory blocks allocated : 115/120 2 memory blocks freed : 51/56 2 unfreed memory blocks : 64 True heap size : 1114112 (32 used in System startup) True free heap : 1113696 Should be : 1113760 Call trace for block $00080072F180 size 32 $00400379 line 35 of project1.lpr Call trace for block $00080072F0C0 size 32 Still 2 memory leaks. :-( Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Where and Why is there a memory leak?
On Wed, 6 Sep 2017, Graeme Geldenhuys wrote: Hi, Playing with this small sample application to answer another question in this mailing list, I noticed the sample application has a memory leak. For the life of me I can't see why or how to resolve it. I tested with FPC 2.6.4, 3.0.2 and 3.0.4-rc1 under 64-bit FreeBSD. ===[ project1.pas ] program project1; {$mode objfpc}{$H+} {$interfaces COM} type IHook = interface ['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}'] procedure DoIt; end; type THook = class(TInterfacedObject, IHook) private procedure DoIt; end; procedure THook.DoIt; begin writeln(ClassName + ' did it'); end; type TBaseClass = class(TInterfacedObject, IHook) private FHook: IHook; property Hook: IHook read FHook implements IHook; public constructor Create; destructor Destroy; override; end; constructor TBaseClass.Create; begin FHook := THook.Create; // FPC 2.6.4 reports a memory leak here end; destructor TBaseClass.Destroy; begin // nothing to do here end; You must free FHook here, because you are keeping a reference to the object, not the interface. And you must call inherited. You must always call inherited in the destructor. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] implements
> On Sep 6, 2017, at 2:50 PM, Graeme Geldenhuys > wrote: > > There is NO need to make Hook public, because you can always get access to > that functionality via the Supports() call and get a reference to IHook. The Supports() call is the key takeaway here. For the sake of discussion can you see why it makes sense that “hook.” syntax would be implied because the class does indeed supposedly implement the interface? Everything about the syntax says that the methods in IHook should be in TBaseClass so I can’t help but feel like it was an omission or not fully finished. It would be messy to implement probably because you would risk a number of name collisions with existing methods. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Free Pascal 3.0.4-rc1 released!
On 2017-09-06 09:19, Graeme Geldenhuys wrote: For example: ** Compiled with FPC 3.0.2 or FPC 3.0.4 - no line info The complete sample application is here: ===[ project1.pas ] program project1; {$mode objfpc}{$H+} {$interfaces COM} type IHook = interface ['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}'] procedure DoIt; end; type THook = class(TInterfacedObject, IHook) private procedure DoIt; end; procedure THook.DoIt; begin writeln(ClassName + ' did it'); end; type TBaseClass = class(TInterfacedObject, IHook) private FHook: IHook; property Hook: IHook read FHook implements IHook; public constructor Create; destructor Destroy; override; end; constructor TBaseClass.Create; begin FHook := THook.Create; // FPC 2.6.4 reports a memory leak here end; destructor TBaseClass.Destroy; begin // nothing to do here end; var base: IHook; begin base := TBaseClass.Create; base.DoIt; base := nil; // just to see if it helped with the memory leak - it doesn't end. ==[ end ]== Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
[fpc-pascal] Where and Why is there a memory leak?
Hi, Playing with this small sample application to answer another question in this mailing list, I noticed the sample application has a memory leak. For the life of me I can't see why or how to resolve it. I tested with FPC 2.6.4, 3.0.2 and 3.0.4-rc1 under 64-bit FreeBSD. ===[ project1.pas ] program project1; {$mode objfpc}{$H+} {$interfaces COM} type IHook = interface ['{4BCAEDD8-92D8-11E7-88D3-C86000E37EB0}'] procedure DoIt; end; type THook = class(TInterfacedObject, IHook) private procedure DoIt; end; procedure THook.DoIt; begin writeln(ClassName + ' did it'); end; type TBaseClass = class(TInterfacedObject, IHook) private FHook: IHook; property Hook: IHook read FHook implements IHook; public constructor Create; destructor Destroy; override; end; constructor TBaseClass.Create; begin FHook := THook.Create; // FPC 2.6.4 reports a memory leak here end; destructor TBaseClass.Destroy; begin // nothing to do here end; var base: IHook; begin base := TBaseClass.Create; base.DoIt; base := nil; // just to see if it helped with the memory leak - it doesn't end. ==[ end ]== When I run the program, the output is as follows: [t1]$ ./project1 THook did it Heap dump by heaptrc unit 4 memory blocks allocated : 115/120 2 memory blocks freed : 51/56 2 unfreed memory blocks : 64 True heap size : 1114112 (32 used in System startup) True free heap : 1113696 Should be : 1113760 Call trace for block $00080072F180 size 32 $00400379 line 35 of project1.lpr Call trace for block $00080072F0C0 size 32 Personally I always use CORBA style interfaces, never reference counted COM style interfaces. So my programs normally don't have this issue, and I use interfaces a lot. Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Free Pascal 3.0.4-rc1 released!
On 2017-07-18 09:44, Marco van de Voort wrote: You can help improve the upcoming 3.0.4 release by downloading and testing this release. I've been using FPC 3.0.4 for a while now under 64-bit FreeBSD. I've noticed that a tracelog with line info generated by the applications are not working as they did in FPC 2.6.4. I then tested with FPC 3.0.2, and it seems broken there too (I've never really used FPC 3.0.x for production code yet). The problem - there is no line information. For example: ** Compiled with FPC 3.0.2 or FPC 3.0.4 - no line info [t1]$ ./project1 THook did it Heap dump by heaptrc unit 4 memory blocks allocated : 115/120 2 memory blocks freed : 67/72 2 unfreed memory blocks : 48 True heap size : 1146880 (32 used in System startup) True free heap : 1146496 Should be : 1146544 Call trace for block $0008007390C0 size 32 Call trace for block $0008007310C0 size 16 ** Compiled with FPC 2.6.4 - not the line info pointing to ** the originating point of a memory leak [t1]$ ./project1 THook did it Heap dump by heaptrc unit 4 memory blocks allocated : 99/104 2 memory blocks freed : 51/56 2 unfreed memory blocks : 48 True heap size : 1146880 (32 used in System startup) True free heap : 1146496 Should be : 1146544 Call trace for block $0008007370C0 size 32 $00400379 line 35 of project1.lpr Call trace for block $00080072F0C0 size 16 Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] implements
On 2017-09-05 05:05, Ryan Joseph wrote: That’s what I was looking for in terms of a practical use patterns for “implements properties”. I should have seen that at the start but I’m still hung up on how it’s implemented. And to come back to your example in your first post: // your code TBaseClass = class (IHook) private m_hook: IHook; public constructor Create; property Hook: IHook read m_hook implements IHook; end; What I do, and I suggest you try it too. Because you are using interfaces, the idea is that you use the Interface Reference variable only, never the property. To help you with that, move the "Hook" property from the Public section of the class, to the Private section. // with my changes TBaseClass = class (IHook) private m_hook: IHook; property Hook: IHook read m_hook implements IHook; public constructor Create; end; There is NO need to make Hook public, because you can always get access to that functionality via the Supports() call and get a reference to IHook. Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal