[perl #97020] Carp (actually caller) leaking memory
authorFather Chrysostomos <sprout@cpan.org>
Thu, 18 Aug 2011 15:50:02 +0000 (08:50 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Wed, 31 Aug 2011 20:28:52 +0000 (13:28 -0700)
commit790db5db7e6fc8402a2044ebc8cace4cdf563f50
tree2866a9565e2c8fd418cec49b2471fca1f4dffc57
parentfe2b14024013434281bd9a6383f9d4d84312b355
[perl #97020] Carp (actually caller) leaking memory

Commit eff7e72c3 (Detect incomplete caller overrides in Carp) used
this little trick for detecting a @DB::args that an overridden
caller() failed to set:

+  @args = \$i; # A sentinal, which no-one else has the address of

But there is a bug in caller().  The first time caller tries to write
to @DB::args, it calls Perl_init_dbargs first.  That function checks
whether @DB::args is AvREAL, in case someone has assigned to it, and
takes appropriate measures.  But caller doesn’t bother calling
Perl_init_dbargs more than once.  So manually-assigned items in
@DB::args would leak, starting with the *second* call to caller.

Commit eff7e72c3 triggered that bug, resulting in a regression in
Carp, in that it started leaking.  eff7e72c3 was backported to 5.12.2
with commit 97705941a4, so in both 5.12 and 5.14 Carp is affected.

This bug (the caller bug, not Carp’s triggering thereof) also affects
any caller overrides that set @DB::args themselves, if there are
alternate calls to the overridden caller and CORE::caller.

This commit fixes that by changing the if (!PL_dbargs) condition
in pp_caller to if (!PL_dbargs || AvREAL(PL_dbargs)).  I.e., if
@args is either uninitialised or AvREAL then call Perl_init_dbargs.
Perl_init_dbargs also has a bug in it, that this fixes: The array not
only needs AvREAL turned off, but also AvREIFY turned on, so that
assignments to it that occur after its initialisation turn AvREAL back
on again.  (In fact, Larry Wall added a comment suggesting this back
in perl 5.000.)

(cherry-picked from af80dd863acea8450a9f41ae03645f4d69dad091)
av.h
perl.c
pp_ctl.c
t/op/caller.t