Recent

Author Topic: FPC has a lot of memory leaks. What are we going to do about it?  (Read 1830 times)

Akira1364

  • Sr. Member
  • ****
  • Posts: 382
(This is a copy of something I also just posted on the mailing list.)

I was feeling inquisitive today, so I added

Code: Pascal  [Select]
  1. SetHeapTraceOutput('log.trc');

to the first line after the main "begin" in pp.pas and built myself a debug copy of the compiler using Lazarus. After using that copy to build the following very simple program:

Code: Pascal  [Select]
  1. program Test;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. procedure TestProc(const S: String);
  6. begin
  7.   WriteLn('The test string is: ', S);
  8. end;
  9.  
  10. begin
  11.   TestProc('Hello, world!');
  12. end.

I was honestly surprised to find that there was already an unfreed block:

140145 memory blocks allocated : 23669524/23770688
140144 memory blocks freed     : 23669468/23770632
1 unfreed memory blocks : 56
True heap size : 1114112 (192 used in System startup)
True free heap : 1113696
Should be : 1113736
Call trace for block $000000005E642220 size 56
  $000000010000DB6B
  $00000001000A35ED  TNODE__ALLOCOPTINFO,  line 973 of node.pas
  $0000000100164889  SETEXECUTIONWEIGHT,  line 366 of optutils.pas
  $00000001000C2873  FOREACHNODESTATIC,  line 321 of nutils.pas
  $00000001000C2DAA  PROCESS_CHILDREN,  line 308 of nutils.pas
  $00000001000C28BF  FOREACHNODESTATIC,  line 336 of nutils.pas
  $00000001000C2DF1  PROCESS_CHILDREN,  line 309 of nutils.pas
  $00000001000C28BF  FOREACHNODESTATIC,  line 336 of nutils.pas

So then I tried something just a little bit more complex:

Code: Pascal  [Select]
  1. program Test2;
  2.  
  3. procedure TestProc(const S: String);
  4. begin
  5.   WriteLn('The test string is: ', S);
  6. end;
  7.  
  8. generic procedure GenericTestProc<T>(const S: T);
  9. begin
  10.   WriteLn('The test value is: ', S);  
  11. end;
  12.  
  13. begin
  14.   TestProc('Hello, world!');
  15.   specialize GenericTestProc<LongInt>(15);
  16. end.

And unfortunately things got a lot worse very quickly:

141240 memory blocks allocated : 23794575/23896072
141219 memory blocks freed     : 23791692/23893176
21 unfreed memory blocks : 2883
True heap size : 2195456 (192 used in System startup)
True free heap : 2188992
Should be : 2189680
Call trace for block $000000007CECC6A0 size 56
  $000000010000DB6B
  $00000001000A35ED  TNODE__ALLOCOPTINFO,  line 973 of node.pas
  $0000000100164889  SETEXECUTIONWEIGHT,  line 366 of optutils.pas
  $00000001000C2873  FOREACHNODESTATIC,  line 321 of nutils.pas
  $00000001000C2DAA  PROCESS_CHILDREN,  line 308 of nutils.pas
  $00000001000C28BF  FOREACHNODESTATIC,  line 336 of nutils.pas
  $00000001000C2DF1  PROCESS_CHILDREN,  line 309 of nutils.pas
  $00000001000C28BF  FOREACHNODESTATIC,  line 336 of nutils.pas
Call trace for block $000000007CF57310 size 39
  $000000010000DA72
  $00000001000080C3
  $0000000100008FAB
  $00000001000088B4
  $00000001000D3950  PARSE_GENERIC_SPECIALIZATION_TYPES_INTERNAL,  line 394 of pgenutil.pas
  $00000001000D3F1E  GENERATE_SPECIALIZATION_PHASE1,  line 581 of pgenutil.pas
  $000000010018A6B7  FACTOR_READ_ID,  line 2850 of pexpr.pas
  $00000001001887ED  FACTOR,  line 3390 of pexpr.pas
Call trace for block $000000007CF57490 size 46
  $000000010000DA72
  $00000001000080C3
  $0000000100009052
  $000000010000842D
  $00000001000D38A0  PARSE_GENERIC_SPECIALIZATION_TYPES_INTERNAL,  line 391 of pgenutil.pas
  $00000001000D3F1E  GENERATE_SPECIALIZATION_PHASE1,  line 581 of pgenutil.pas
  $000000010018A6B7  FACTOR_READ_ID,  line 2850 of pexpr.pas
  $00000001001887ED  FACTOR,  line 3390 of pexpr.pas
Call trace for block $000000007CEE93F0 size 128
  $0000000100015F5B
  $000000010000DB4B
  $00000001000282D5  TFPLIST__SETCAPACITY,  line 757 of cclasses.pas
  $00000001000287C3  TFPLIST__EXPAND,  line 846 of cclasses.pas
  $000000010002845C  TFPLIST__ADD,  line 784 of cclasses.pas
  $00000001000D368C  PARSE_GENERIC_SPECIALIZATION_TYPES_INTERNAL,  line 374 of pgenutil.pas
  $00000001000D3F1E  GENERATE_SPECIALIZATION_PHASE1,  line 581 of pgenutil.pas
  $000000010018A6B7  FACTOR_READ_ID,  line 2850 of pexpr.pas
Call trace for block $000000007CEEA950 size 128
  $0000000100015F5B
  $000000010000DB4B
  $00000001000282D5  TFPLIST__SETCAPACITY,  line 757 of cclasses.pas
  $00000001000287C3  TFPLIST__EXPAND,  line 846 of cclasses.pas
  $000000010002845C  TFPLIST__ADD,  line 784 of cclasses.pas
  $00000001000D35FF  PARSE_GENERIC_SPECIALIZATION_TYPES_INTERNAL,  line 366 of pgenutil.pas
  $00000001000D3F1E  GENERATE_SPECIALIZATION_PHASE1,  line 581 of pgenutil.pas
  $000000010018A6B7  FACTOR_READ_ID,  line 2850 of pexpr.pas
Call trace for block $000000007CF34A60 size 12
  $000000010000DB6B
  $00000001000D35DD  PARSE_GENERIC_SPECIALIZATION_TYPES_INTERNAL,  line 364 of pgenutil.pas
  $00000001000D3F1E  GENERATE_SPECIALIZATION_PHASE1,  line 581 of pgenutil.pas
  $000000010018A6B7  FACTOR_READ_ID,  line 2850 of pexpr.pas
  $00000001001887ED  FACTOR,  line 3390 of pexpr.pas
  $000000010018BA4A  SUB_EXPR,  line 4184 of pexpr.pas
  $000000010018BA72  SUB_EXPR,  line 4189 of pexpr.pas
  $000000010018BA72  SUB_EXPR,  line 4189 of pexpr.pas
Call trace for block $000000007CF57550 size 24
  $000000010000DA72
  $000000010000BF6A
  $000000010000BE05
  $000000010014E0A5  TSPECIALIZATIONCONTEXT__CREATE,  line 62 of pgentype.pas
  $00000001000D3EBB  GENERATE_SPECIALIZATION_PHASE1,  line 578 of pgenutil.pas
  $000000010018A6B7  FACTOR_READ_ID,  line 2850 of pexpr.pas
  $00000001001887ED  FACTOR,  line 3390 of pexpr.pas
  $000000010018BA4A  SUB_EXPR,  line 4184 of pexpr.pas
Call trace for block $000000007CF57790 size 24
  $000000010000DA72
  $000000010000BF6A
  $000000010000BE05
  $0000000100029063  TFPOBJECTLIST__CREATE,  line 1052 of cclasses.pas
  $0000000100028E74  TFPOBJECTLIST__CREATE,  line 1024 of cclasses.pas
  $000000010014E08A  TSPECIALIZATIONCONTEXT__CREATE,  line 61 of pgentype.pas
  $00000001000D3EBB  GENERATE_SPECIALIZATION_PHASE1,  line 578 of pgenutil.pas
  $000000010018A6B7  FACTOR_READ_ID,  line 2850 of pexpr.pas
Call trace for block $000000007CF576D0 size 24
  $000000010000DA72
  $000000010000BF6A
  $0000000100028E4C  TFPOBJECTLIST__CREATE,  line 1023 of cclasses.pas
  $000000010014E08A  TSPECIALIZATIONCONTEXT__CREATE,  line 61 of pgentype.pas
  $00000001000D3EBB  GENERATE_SPECIALIZATION_PHASE1,  line 578 of pgenutil.pas
  $000000010018A6B7  FACTOR_READ_ID,  line 2850 of pexpr.pas
  $00000001001887ED  FACTOR,  line 3390 of pexpr.pas
  $000000010018BA4A  SUB_EXPR,  line 4184 of pexpr.pas
Call trace for block $000000007C9BAF50 size 312
  $000000010000DA72
  $000000010000BF6A
  $000000010014E058  TSPECIALIZATIONCONTEXT__CREATE,  line 60 of pgentype.pas
  $00000001000D3EBB  GENERATE_SPECIALIZATION_PHASE1,  line 578 of pgenutil.pas
  $000000010018A6B7  FACTOR_READ_ID,  line 2850 of pexpr.pas
  $00000001001887ED  FACTOR,  line 3390 of pexpr.pas
  $000000010018BA4A  SUB_EXPR,  line 4184 of pexpr.pas
  $000000010018BA72  SUB_EXPR,  line 4189 of pexpr.pas
Call trace for block $000000007CDCDD60 size 416
  $000000010000DA72
  $000000010000BF6A
  $0000000100217BB0  TCGCALLPARANODE__CREATE,  line 146 of ncgcal.pas
  $0000000100138E6D  TINLINENODE__HANDLE_READ_WRITE,  line 1364 of ninl.pas
  $000000010013F731  TINLINENODE__PASS_TYPECHECK,  line 3268 of ninl.pas
  $000000010014603C  TYPECHECKPASS_INTERNAL,  line 81 of pass_1.pas
  $0000000100146188  DO_TYPECHECKPASS_CHANGED,  line 124 of pass_1.pas
  $00000001001857D0  POSTFIXOPERATORS,  line 1994 of pexpr.pas
Call trace for block $000000007CCE9EA0 size 256
  $000000010000DA72
  $000000010000BF6A
  $00000001001035B0  TTYPECONVNODE__CREATE_INTERNAL,  line 966 of ncnv.pas
  $0000000100138E48  TINLINENODE__HANDLE_READ_WRITE,  line 1365 of ninl.pas
  $000000010013F731  TINLINENODE__PASS_TYPECHECK,  line 3268 of ninl.pas
  $000000010014603C  TYPECHECKPASS_INTERNAL,  line 81 of pass_1.pas
  $0000000100146188  DO_TYPECHECKPASS_CHANGED,  line 124 of pass_1.pas
  $00000001001857D0  POSTFIXOPERATORS,  line 1994 of pexpr.pas
Call trace for block $000000007CD23DC0 size 224
  $000000010000DA72
  $000000010000BF6A
  $000000010013341C  TDEREFNODE__CREATE,  line 755 of nmem.pas
  $0000000100138E2A  TINLINENODE__HANDLE_READ_WRITE,  line 1365 of ninl.pas
  $000000010013F731  TINLINENODE__PASS_TYPECHECK,  line 3268 of ninl.pas
  $000000010014603C  TYPECHECKPASS_INTERNAL,  line 81 of pass_1.pas
  $0000000100146188  DO_TYPECHECKPASS_CHANGED,  line 124 of pass_1.pas
  $00000001001857D0  POSTFIXOPERATORS,  line 1994 of pexpr.pas
Call trace for block $000000007CCEA040 size 256
  $000000010000DA72
  $000000010000BF6A
  $00000001000FCFCC  TTEMPREFNODE__CREATE,  line 1103 of nbas.pas
  $0000000100138E0C  TINLINENODE__HANDLE_READ_WRITE,  line 1365 of ninl.pas
  $000000010013F731  TINLINENODE__PASS_TYPECHECK,  line 3268 of ninl.pas
  $000000010014603C  TYPECHECKPASS_INTERNAL,  line 81 of pass_1.pas
  $0000000100146188  DO_TYPECHECKPASS_CHANGED,  line 124 of pass_1.pas
  $00000001001857D0  POSTFIXOPERATORS,  line 1994 of pexpr.pas
Call trace for block $000000007CEEA050 size 120
  $000000010000DB6B
  $00000001000FC14D  TTEMPCREATENODE__CREATE,  line 906 of nbas.pas
  $0000000100138CFA  TINLINENODE__HANDLE_READ_WRITE,  line 1341 of ninl.pas
  $000000010013F731  TINLINENODE__PASS_TYPECHECK,  line 3268 of ninl.pas
  $000000010014603C  TYPECHECKPASS_INTERNAL,  line 81 of pass_1.pas
  $0000000100146188  DO_TYPECHECKPASS_CHANGED,  line 124 of pass_1.pas
  $00000001001857D0  POSTFIXOPERATORS,  line 1994 of pexpr.pas
  $0000000100188A4A  FACTOR,  line 3431 of pexpr.pas
Call trace for block $000000007CEC2680 size 66
  $0000000100015F5B
  $000000010000DB4B
  $0000000100029649  TFPHASHLIST__SETSTRCAPACITY,  line 1369 of cclasses.pas
  $0000000100029DA2  TFPHASHLIST__STREXPAND,  line 1538 of cclasses.pas
  $000000010002991A  TFPHASHLIST__ADDSTR,  line 1433 of cclasses.pas
  $0000000100029A5A  TFPHASHLIST__ADD,  line 1464 of cclasses.pas
  $00000001000D5BBA  PARSE_GENERIC_PARAMETERS,  line 1220 of pgenutil.pas
  $00000001001691C6  CONSUME_PROC_NAME,  line 714 of pdecsub.pas
Call trace for block $000000007CF525D0 size 32
  $00000001000160C5
  $000000010000DB4B
  $00000001000296FB  TFPHASHLIST__SETHASHCAPACITY,  line 1387 of cclasses.pas
  $00000001000295E7  TFPHASHLIST__SETCAPACITY,  line 1327 of cclasses.pas
  $0000000100029D1A  TFPHASHLIST__EXPAND,  line 1526 of cclasses.pas
  $0000000100029A04  TFPHASHLIST__ADD,  line 1459 of cclasses.pas
  $00000001000D5BBA  PARSE_GENERIC_PARAMETERS,  line 1220 of pgenutil.pas
  $00000001001691C6  CONSUME_PROC_NAME,  line 714 of pdecsub.pas
Call trace for block $000000007CDCC860 size 576
  $0000000100015F5B
  $000000010000DB4B
  $000000010002959D  TFPHASHLIST__SETCAPACITY,  line 1323 of cclasses.pas
  $0000000100029D1A  TFPHASHLIST__EXPAND,  line 1526 of cclasses.pas
  $0000000100029A04  TFPHASHLIST__ADD,  line 1459 of cclasses.pas
  $00000001000D5BBA  PARSE_GENERIC_PARAMETERS,  line 1220 of pgenutil.pas
  $00000001001691C6  CONSUME_PROC_NAME,  line 714 of pdecsub.pas
  $00000001001671AA  PARSE_PROC_HEAD,  line 881 of pdecsub.pas
Call trace for block $000000007CEBF580 size 64
  $000000010000DA72
  $000000010000BF6A
  $00000001000297D8  TFPHASHLIST__CREATE,  line 1404 of cclasses.pas
  $000000010002A73B  TFPHASHOBJECTLIST__CREATE,  line 1840 of cclasses.pas
  $00000001000D5B30  PARSE_GENERIC_PARAMETERS,  line 1209 of pgenutil.pas
  $00000001001691C6  CONSUME_PROC_NAME,  line 714 of pdecsub.pas
  $00000001001671AA  PARSE_PROC_HEAD,  line 881 of pdecsub.pas
  $000000010016A841  PARSE_PROC_DEC,  line 1597 of pdecsub.pas
Call trace for block $000000007CF52690 size 24
  $000000010000DA72
  $000000010000BF6A
  $000000010002A6FC  TFPHASHOBJECTLIST__CREATE,  line 1838 of cclasses.pas
  $00000001000D5B30  PARSE_GENERIC_PARAMETERS,  line 1209 of pgenutil.pas
  $00000001001691C6  CONSUME_PROC_NAME,  line 714 of pdecsub.pas
  $00000001001671AA  PARSE_PROC_HEAD,  line 881 of pdecsub.pas
  $000000010016A841  PARSE_PROC_DEC,  line 1597 of pdecsub.pas
  $000000010017FD47  READ_PROC,  line 2157 of psub.pas
Call trace for block $000000007CEC2220 size 56
  $000000010000DB6B
  $00000001000A35ED  TNODE__ALLOCOPTINFO,  line 973 of node.pas
  $0000000100164889  SETEXECUTIONWEIGHT,  line 366 of optutils.pas
  $00000001000C2873  FOREACHNODESTATIC,  line 321 of nutils.pas
  $00000001000C2DAA  PROCESS_CHILDREN,  line 308 of nutils.pas
  $00000001000C28BF  FOREACHNODESTATIC,  line 336 of nutils.pas
  $00000001000C2DF1  PROCESS_CHILDREN,  line 309 of nutils.pas
  $00000001000C28BF  FOREACHNODESTATIC,  line 336 of nutils.pas

I tried other, more complex things after this, some of the Heaptrc logs for which are just too long to even be reasonably posted on the mailing list (Edit: or here on the forums!)

This raises a couple of big questions:

Considering that FPC provides optional built-in memory tracking that will take you directly to the exact source line number of a leak origin, the fact that there's so many either means people have simply not been doing leak checks on the compiler at all, or have just been actively ignoring them for quite a while. Neither of those are "good news", but which is it?

Secondly, are there any plans to try to clean up and refactor the compiler codebase in general? After diving in to take a look at the files where some of these leaks originated, it's not at all surprising they exist. The entire compiler essentially revolves around "nodes" and various subclasses of them, that are created in too many different places and ways to count, and that have no top-level infrastructure that allows for them to be tracked in any kind of meaningful way. (As in, they're generally not actually children of some kind of tree class, but are mostly just globally scoped neighbors of each other.)

Don't get me wrong, the general "tree" approach to things is perfectly valid and relatively common in compilers, but the specific way FPC does it frankly leaves more than a few things to be desired.

I was actually able to successfully fix some of the more "what you see is what you get" kind of leaks quite easily and quickly, but others boiled down to a "node" being created as a local variable in the middle of some 1000+ line method, getting assigned to the left or right property of some other globally visible node (that could have been created anywhere else), and then never being freed.

To add to that, some of the ones at the lines Heaptrc indicated were problems simply could not be freed even when I tried to do so without raising an untraceable access violation later in the compilation process, which means the compiler is basically knowingly relying on intentional memory leaks and undebuggable undefined behavior in multiple places that could easily be affected or altered by anything else anywhere else in the codebase at any time.

The way-too-short, highly undescriptive naming of variables doesn't exactly help, either! "hp" and "p" are not good variable names. They really aren't!

Overall, I'm not trying to put blame on anyone in particular here, but as someone who loves using FPC and would like to see it continue to grow (and be even more stable in general), it would be nice if we could collectively as a community address some of these basic, fundamental issues (which I'd be more than happy to help with myself, of course.)
« Last Edit: July 30, 2018, 05:26:25 am by Akira1364 »

Thaddy

  • Hero Member
  • *****
  • Posts: 7178
Re: FPC has a lot of memory leaks. What are we going to do about it?
« Reply #1 on: July 30, 2018, 06:01:22 am »
In both cases there ARE no memory leaks, provided you use heaptrc correctly:
SetHeaptraceOutPut(log.trc) will give you only reliable trace logs when you have specified heaptrace in the Lazarus options or when using -glh from the command-line and an optimization level of -O2. Without the heaptrc unit (which you should not include by hand) code that needs finalisation is not properly marked and that gives wrong results. High optimization settings may also give false positives.
In your case you are not using the tools correctly as this demonstrates:
Given:
Code: Pascal  [Select]
  1. program httest;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. procedure TestProc(const S: String);
  6. begin
  7.   WriteLn('The test string is: ', S);
  8. end;
  9.  
  10. begin
  11.   SetHeaptraceOutput('log.trc');
  12.   TestProc('Hello, world!');
  13. end.

compiled like:
Code: Bash  [Select]
  1.  $ fpc -glh -O2 httest.pas
Then the output is:
Code: Bash  [Select]
  1. $ ./httest
  2. The test string is: Hello, world!
And the log is:
Code: Bash  [Select]
  1. $ cat log.trc
  2. /home/pi/httest
  3. Heap dump by heaptrc unit of /home/pi/httest
  4. 3 memory blocks allocated : 68/80
  5. 3 memory blocks freed     : 68/80
  6. 0 unfreed memory blocks : 0
  7. True heap size : 65536
  8. True free heap : 65536

For your other example:
Code: Bash  [Select]
  1. fpc -glh -O2 httest2.pas
Code: Bash  [Select]
  1. $ ./httest2
  2. The test string is: Hello, world!
  3. The test value is: 15
  4. Heap dump by heaptrc unit of /home/pi/httest2
  5. 0 memory blocks allocated : 0/0
  6. 0 memory blocks freed     : 0/0
  7. 0 unfreed memory blocks : 0
  8. True heap size : 0
  9. True free heap : 0

So you are doing something seriously wrong like keeping SetHeaptraceOutput() in production code! or not properly using heaptrc.

This is repeatable on linux-arm linux x86_64 and x86_64-win64. (for windows add {$apptype console}

There are no leaks... There seem to be leaks, because you did not use it properly, which gives false positives.
See the manuals https://www.freepascal.org/docs-html/current/rtl/heaptrc/index.html
and the wiki http://wiki.lazarus.freepascal.org/heaptrc (this wiki entry is up to date: I recently updated it)

To detect if you are using heaptrc correctly you can write:
Code: Pascal  [Select]
  1. program detectht;
  2. begin
  3. {$if declared(UseHeapTrace)}  //set by the compiler when it includes the heaptrc unit.
  4. SetHeaptraceOutput('log.trc'); // only now this makes sense!
  5. writeln('Yes I am using heaptrc correctly');
  6. {$else}
  7. wtiteln('I am NOT using heaptrc correctly');
  8. {$endif}
  9. end.
Note that the 3.0.4 documentation is incorrect, but the documentation is fixed for 3.1.1.
So ignore http://lazarus-ccr.sourceforge.net/docs/rtl/heaptrc/usage.html because that's wrong.
I updated the wiki to reflect the newer documentation based on the fix by Michael after my bug report.
The reference for heaptrc here http://lazarus-ccr.sourceforge.net/docs/rtl/heaptrc/usage.html is correct, though. See the last line.

« Last Edit: July 30, 2018, 06:35:35 am by Thaddy »
inline variables like in D10.3 are a bit like Brexit: if you are given the wrong information it sounds like a good idea. Every kid loves candy, but it makes you fat and your teeth will disappear.

mse

  • Sr. Member
  • ****
  • Posts: 286
Re: FPC has a lot of memory leaks. What are we going to do about it?
« Reply #2 on: July 30, 2018, 06:47:12 am »
@Thaddy:
Please read the post again before writing nonsense. ;-)

Thaddy

  • Hero Member
  • *****
  • Posts: 7178
Re: FPC has a lot of memory leaks. What are we going to do about it?
« Reply #3 on: July 30, 2018, 09:28:12 am »
@mse
Where is the nonsense? Can't reproduce his issue with his code.
So where? Show me.... Unless you mean there are some in the compiler itself compiled in debug mode?
In that case use top on linux or the process manager on windows to see any actual effect between start and program termination.
« Last Edit: July 30, 2018, 09:33:19 am by Thaddy »
inline variables like in D10.3 are a bit like Brexit: if you are given the wrong information it sounds like a good idea. Every kid loves candy, but it makes you fat and your teeth will disappear.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 6608
Re: FPC has a lot of memory leaks. What are we going to do about it?
« Reply #4 on: July 30, 2018, 10:23:48 am »
Thaddy: it is indeed about the compiler, and quite clear from the tracebacks. Please read better before replying.

Thaddy

  • Hero Member
  • *****
  • Posts: 7178
Re: FPC has a lot of memory leaks. What are we going to do about it?
« Reply #5 on: July 30, 2018, 10:48:10 am »
Thaddy: it is indeed about the compiler, and quite clear from the tracebacks. Please read better before replying.
I did (eventually). Hence top and process manager. I can't see the harm. (Also note the compiler compiles -Sew: leaks are on purpose?)
« Last Edit: July 30, 2018, 02:09:45 pm by Thaddy »
inline variables like in D10.3 are a bit like Brexit: if you are given the wrong information it sounds like a good idea. Every kid loves candy, but it makes you fat and your teeth will disappear.

Nitorami

  • Sr. Member
  • ****
  • Posts: 346
Re: FPC has a lot of memory leaks. What are we going to do about it?
« Reply #6 on: July 30, 2018, 07:32:48 pm »
Quote
(This is a copy of something I also just posted on the mailing list.)

It would be interesting to follow the discussion on the mailing list, but I cannot find it there.

valdir.marcos

  • Hero Member
  • *****
  • Posts: 534
Re: FPC has a lot of memory leaks. What are we going to do about it?
« Reply #7 on: July 30, 2018, 08:09:46 pm »
Quote
(This is a copy of something I also just posted on the mailing list.)

It would be interesting to follow the discussion on the mailing list, but I cannot find it there.
fpc-devel  ->  FPC developers' list
http://lists.freepascal.org/mailman/listinfo

[fpc-devel] Why/how does the compiler have a non-trivial number of memory leaks after over two decades of development?
Ben Grasset
Mon Jul 30 02:58:43 CEST 2018
http://lists.freepascal.org/pipermail/fpc-devel/2018-July/039369.html