leakfinder.pl

I wrote this to look for memory leaks.  Since it could be useful to
re-run it at some future time, I might as well put it somewhere where
it will not get lost.

It still needs a bit of work.  Currently, evaluating chunks of binary
code can cause memory leaks.  In those cases the binary code is dumped
straight to the terminal, which is not helpful.
Stop char classes from leaking

Since 5.10.0, this script has leaked:

$ perl -e 'warn$$; while(1){eval "/[:]/"}'

What exactly has leaked has changed over time.  In bleadperl
it is this:

SV = PV(0x8033c8) at 0x836170
  REFCNT = 1
  FLAGS = ()
  PV = 0x31c0b0 "\2\0\0\0\377\377\377\377\0\0\0\0\f\fS\21\1\0\0\0:\0\0\0;\0\0\0"\0
  CUR = 28
  LEN = 32

This only happens when the character class has only one character in
it, the same character repeated ([aa]), or a multicharacter fold.

A character class is usually compiled as an ANYOF node, but [A] is
optimised down to just A (and EXACT) and /[\xdf]/i is rewritten into a
more complex expression.

When the ANYOF node is abandoned, we need to free any temporary SVs
created in the mean time.  A few of them were leaking.
Stop statement labels from leaking

They have leaked since v5.15.9-35-g5db1eb8 (which probably broke mad
dumping of labels; to be addressed in the next commit).
Fix invalid token warning with PERL_XMLDUMP and label

Under mad builds, commit 5db1eb8 caused this warning:

$ PERL_XMLDUMP=/dev/null ./perl -Ilib -e 'foo:'
Invalid TOKEN object ignored at -e line 1.

Since I don’t understand the mad code so well, the easiest fix is to
revert back to using a PV, as we did before 5db1eb8.  To record the
utf8ness, we sneak it behind the trailing null.
svleak.t: re-evals leak under mad
Stop require nonexistent::module from leaking

This leak was caused by v5.17.4-125-gf7ee53b.
Use shared memory for sv_debug_file

With -DDEBUGGING -Accflags=-DDEBUG_LEAKING_SCALARS -Duseithreads:

use threads;
use threads::shared;
my @shared_ary :shared;
$shared_ary[0] = &threads::shared::share({});
@shared_ary = ();
__END__
panic: free from wrong pool, 881c00!=800000.
Scalars leaked: 1

threads::shared has to juggle multiple interpreters.  Sometimes the
interpreter it is calling into (and passing as the first argument
via pTHX) is not actually the current thread as far as the OS is
concerned.

Perl_safesysfree in util.c does not take a pTHX parameter, so it
fetches the current interpreter from the data associated with the cur-
rent thread.

The result is that PERL_TRACK_MEMPOOL complains that the file name
associated with an SV under DEBUG_LEAKING_SCALARS is being freed from
the wrong interpreter.

Using shared memory for the file name solves the issue.
svleak.t: Enable syntax error tests under -Dmad

Also use the fairly new eleak for brevity’s sake (and also because it
knows about the existing mad leak for string evals).
Don’t leak pattern buffer when invalid flags croak

Normally if there is a syntax error yyerror just records it and pars-
ing continues anyway.  If there are too many syntax errors, it croaks.

It just happened that if it croaked when encountering invalid flags
for quote-like operators it would leak the buffer containing the pat-
tern (and the substitution for s///).

Since those are stored in the parser struct and are set to null when-
ever something else takes ownership of the SV, these struct members
will only ever be non-null in parser_free when they have leaked.  So
we can free them there.  (I.e., these slots have always been refer-
ence-counted, so treat them that way.)
leakfinder.pl: Use DD for output

This solves the problem of binary code being dumped into the
terminal.
Don’t leak BEGIN blocks after syntax errors
gv.c:S_require_tie_mod: remove SPAGAIN

We are not using SP after this point.
Stop %! after syntax error from leaking the module name
op.c: Stop SAVEFREEOP from leaking slabs

When a CV is freed prematurely, it cleans up its op slab.  But
SAVEFREEOP may cause the savestack to point to an op in that slab
after the CV has been freed, so SAVEFREEOP is allowed to coun-
termand the freeing of the slab.  Every op that is not on the
savestack is freed.

The reference count of the slab was being left off by one.  The result
was that when the stack unwinding freed the op, it would leave the
slab behind and leak it.
op.c:opslab_force_free: Make paranoid code reflect reality

When opslab_force_free is called, the CV still has a reference count
on the slab.  In fact, we don’t even bother lowering it if all goes
well, but simply free the slab with the reference count set to 1.
So the paranoid code that increments the reference count before free-
ing an op is not necessary.  Also, the shortcut out of the loop
was never triggered, as it was checking for a reference count of 0,
rather than 1.
leakfinder.pl: Show file names

It can take a *very* long time to run, so give some indication
that it is actually doing something.
leakfinder.pl: Mair exceptions
Stop the glob operator from leaking GVs

It was adding GVs to the symbol table (via newGVgen), so they
would never be freed, even after the op was freed, unless done so
explicitly.

There is no reason for these GVs to be exposed.