develooper Front page | perl.perl5.porters | Postings from January 2019

[perl #133789] Memory leak in concatenation operator overload

Thread Previous | Thread Next
From:
Tony Cook via RT
Date:
January 23, 2019 00:17
Subject:
[perl #133789] Memory leak in concatenation operator overload
Message ID:
rt-4.0.24-24820-1548202667-725.133789-15-0@perl.org
On Tue, 22 Jan 2019 02:50:40 -0800, zdm@softvisio.net wrote:
> New memory leak was introduces in perl 5.28.
> Please, see the discussion here:
> https://stackoverflow.com/questions/54304341/perl-overload-
> concatenation-operator-problem
> 
> #!/usr/bin/env perl
> 
> use strict;
> use warnings;
> use Devel::Refcount qw[refcount];
> 
> package AAA {
>     use Devel::Refcount qw[refcount];
> 
> use overload
>   '.' => sub {
>     print 'CONCAT, REFCOUNT: ', refcount( $_[0] ), "\n";
> 
> # return AAA->new;
> return $_[0];
> },
> fallback => 0;
> 
> sub new { return bless {}, $_[0] }
> 
> sub DESTROY { print "DESTROY\n" }
> }
> 
> print "--- start\n";
> 
> {
>     my $o = AAA->new;
> 
> my $s = '1' . ( '2' . ( '3' . ( '4' . ( '5' . $o ) ) ) );
> 
> print "--- exit scope\n";
> print 'REFCOUNT: ', refcount($o), "\n";
> }
> 
> print "--- end\n";
> 
> 1;
> 
> Output:
> 
> --- start
> CONCAT, REFCOUNT: 1
> CONCAT, REFCOUNT: 3
> CONCAT, REFCOUNT: 5
> CONCAT, REFCOUNT: 7
> CONCAT, REFCOUNT: 9
> --- exit scope
> REFCOUNT: 6
> --- end
> DESTROY
> 
> Refs count should stay untouched, but it increased on each iteration.

This is present in blead too.

There's two places the reference count is being incremented.

The first is in leave_adjust_stacks() as the return from the '.' overload is being processed:

(gdb) bt
#0  S_SvREFCNT_inc (sv=0x555555d204a8) at inline.h:194
#1  0x0000555555760634 in Perl_leave_adjust_stacks (from_sp=0x555555d4ae10, 
    to_sp=0x555555d4ae08, gimme=2 '\002', pass=0) at pp_hot.c:4793
#2  0x0000555555760a48 in Perl_pp_leavesub () at pp_hot.c:4902
#3  0x00005555556f4b41 in Perl_runops_debug () at dump.c:2536
#4  0x0000555555607358 in Perl_amagic_call (left=0x555555d39c40, 
    right=0x555555d43580, method=70, flags=0) at gv.c:3525
#5  0x0000555555748b19 in Perl_pp_multiconcat () at pp_hot.c:1060

Each of these is added to the tmps stack.

The second is in Perl_pp_multiconcat at the end of the magical value fallback code:

(gdb) bt
#0  S_SvREFCNT_inc (sv=0x555555d204a8) at inline.h:194
#1  0x000055555578ab26 in Perl_sv_setsv_flags (dstr=0x555555d43580, 
    sstr=0x555555d39880, flags=1538) at sv.c:4261
#2  0x0000555555748d85 in Perl_pp_multiconcat () at pp_hot.c:1106

        if (is_append)
            SvTAINT(targ);
        else {
            sv_setsv(targ, left); <---
            SvSETMAGIC(targ);
        }

targ here comes from the PAD:

        SV **svp = &(PAD_SVl(PL_op->op_targ));
        targ = *svp;

Tony

---
via perlbug:  queue: perl5 status: new
https://rt.perl.org/Ticket/Display.html?id=133789

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About