develooper Front page | perl.perl5.porters | Postings from August 2010

[perl #77352] Memory leaks in threaded Perl (cloning PVGVs and PL_my_cxt_list)

Thread Next
Jirka Hruška
August 22, 2010 05:06
[perl #77352] Memory leaks in threaded Perl (cloning PVGVs and PL_my_cxt_list)
Message ID:
# New Ticket Created by  Jirka Hruška 
# Please include the string:  [perl #77352]
# in the subject line of all future correspondence about this issue. 
# <URL: >

This is a bug report for perl from,
generated with the help of perlbug 1.39 running under perl 5.13.4.

[Please describe your issue here]

Hi all,

I would like to report two memory leaks in the threaded Perl
interpreter. They are not very important in an average script,
but in certain scenarios (like mine, running a long-term script
on a semi-embedded device with limited RAM), they can be deadly.

First problem is in S_sv_dup_common() [sv.c] - in the 2nd switch,
if sv_type is SVt_PVGV and isGV_with_GP(source) is not true,
Perl_rvpv_dup() is called to duplicate the value. This is wrong,
results in a memory leak and the statement shall be removed.
The value is first duplicated a bit above in an if statement:
    if (sv_type != SVt_PVAV && sv_type != SVt_PVHV     // (1)
        && !isGV_with_GP(dstr) && (...))               // (2)
      Perl_rvpv_dup(aTHX_ dstr, sstr, param);
And then duplicated again, leaking the previous copy:
    switch (sv_type) {
      case SVt_PVGV:                                   // (1)
        if(isGV_with_GP(sstr)) {                       // (2)
        } else
            Perl_rvpv_dup(aTHX_ dstr, sstr, param);    // !!!

The second issue deals with PL_my_cxt_list. As I understood,
this list is initialized when needed during module load and
correctly cloned when duplicating an interpreter for another
thread, however it is never freed. Because I didn't find a way
to release the contents properly (is there any?), I added at
least a simple free of the array itself - seemed to work well
enough (I probably haven't used any modules with context data).

Patch with my modifications against blead Perl from git should
be attached. The code has been running fine for months now on the
remote box, I also tested the changes on the internal test suite
and it seemed I did not break anything. On the contrary, valgrind
happily confirmed that some memory usage issues have been solved.

The problem can be easily replicated using the following command:
    valgrind --leak-check=full ./perl -we 'use threads; use CGI; \
        sub foo { }; threads->create(\&foo)->join;'
Note the CGI module is loaded only to add more symbols to the
interpreter to demonstrate the leak. Before my patches:
    definitely lost: 7,844 bytes in 65 blocks

After the patch:
    definitely lost: 0 bytes in 0 blocks

I hope my report is OK and will help to improve Perl.

Best regards,
Jiri Hruska

[Please do not change anything below this line]
Site configuration information for perl 5.13.4:

Configured by jirka at Fri May 14 00:16:55 CEST 2010.

Summary of my perl5 (revision 5 version 13 subversion 4) configuration:
  Derived from: ae5391ad3eac034928d0ad9aeb57e8d9f625142f
    osname=linux, osvers=2.6.26-2-686, archname=i686-linux-thread-multi
    uname='linux saturn 2.6.26-2-686 #1 smp tue mar 9 17:35:51 utc
2010 i686 gnulinux '
    config_args='-Dusedevel -Duseithreads'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing
-pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_F
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe
-fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.3.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/, so=so, useshrplib=true,
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E
    cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib

Locally applied patches:

@INC for perl 5.13.4:

Environment for perl 5.13.4:
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PERL_BADLANG (unset)

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About