Front page | perl.perl5.porters |
Postings from August 2013
[perl #119155] threads::shared never frees the shared space interpreter
Thread Next
From:
Nicholas Clark
Date:
August 5, 2013 14:44
Subject:
[perl #119155] threads::shared never frees the shared space interpreter
Message ID:
rt-3.6.HEAD-2552-1375713853-1726.119155-75-0@perl.org
# New Ticket Created by Nicholas Clark
# Please include the string: [perl #119155]
# in the subject line of all future correspondence about this issue.
# <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=119155 >
With $ENV{PERL_DESTRUCT_LEVEL} set to 2, perl should free everything:
$ PERL_DESTRUCT_LEVEL=2 valgrind --leak-check=full --show-reachable=yes ./perl -Ilib -e0
==10636== Memcheck, a memory error detector
==10636== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==10636== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==10636== Command: ./perl -Ilib -e0
==10636==
==10636==
==10636== HEAP SUMMARY:
==10636== in use at exit: 0 bytes in 0 blocks
==10636== total heap usage: 666 allocs, 666 frees, 177,332 bytes allocated
==10636==
==10636== All heap blocks were freed -- no leaks are possible
==10636==
==10636== For counts of detected and suppressed errors, rerun with: -v
==10636== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
Note the pleasing "All heap blocks were freed -- no leaks are possible".
Somewhat frustratingly, glibc's dl_open implementation has 6 still reachable
blocks:
$ PERL_DESTRUCT_LEVEL=2 valgrind --leak-check=full ./perl -Ilib -Mthreads -e0
==28896== Memcheck, a memory error detector
==28896== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==28896== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==28896== Command: ./perl -Ilib -Mthreads -e0
==28896==
==28896==
==28896== HEAP SUMMARY:
==28896== in use at exit: 1,572 bytes in 6 blocks
==28896== total heap usage: 6,932 allocs, 6,926 frees, 1,500,001 bytes allocated
==28896==
==28896== LEAK SUMMARY:
==28896== definitely lost: 0 bytes in 0 blocks
==28896== indirectly lost: 0 bytes in 0 blocks
==28896== possibly lost: 0 bytes in 0 blocks
==28896== still reachable: 1,572 bytes in 6 blocks
==28896== suppressed: 0 bytes in 0 blocks
==28896== Reachable blocks (those to which a pointer was found) are not shown.
==28896== To see them, rerun with: --leak-check=full --show-reachable=yes
==28896==
==28896== For counts of detected and suppressed errors, rerun with: -v
==28896== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
so in what follows, 6 reachable objects are not our concern. But 55 blocks
and 87M are:
$ PERL_DESTRUCT_LEVEL=2 valgrind --leak-check=full ./perl -Ilib -Mthreads -Mthreads::shared -e0
==4378== Memcheck, a memory error detector
==4378== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==4378== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==4378== Command: ./perl -Ilib -Mthreads -Mthreads::shared -e0
==4378==
==4378==
==4378== HEAP SUMMARY:
==4378== in use at exit: 88,775 bytes in 61 blocks
==4378== total heap usage: 8,818 allocs, 8,757 frees, 2,046,301 bytes allocated
==4378==
==4378== LEAK SUMMARY:
==4378== definitely lost: 0 bytes in 0 blocks
==4378== indirectly lost: 0 bytes in 0 blocks
==4378== possibly lost: 0 bytes in 0 blocks
==4378== still reachable: 88,775 bytes in 61 blocks
==4378== suppressed: 0 bytes in 0 blocks
==4378== Reachable blocks (those to which a pointer was found) are not shown.
==4378== To see them, rerun with: --leak-check=full --show-reachable=yes
==4378==
==4378== For counts of detected and suppressed errors, rerun with: -v
==4378== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
With --show-reachable=yes the leaks all look like this:
==17136== 26 bytes in 1 blocks are still reachable in loss record 1 of 51
==17136== at 0x4C25D8C: malloc (vg_replace_malloc.c:270)
==17136== by 0x546226: Perl_safesysmalloc (util.c:90)
==17136== by 0x5488BC: Perl_savepv (util.c:929)
==17136== by 0x71E083: Perl_new_collate (locale.c:228)
==17136== by 0x71FE8A: Perl_init_i18nl10n (locale.c:501)
==17136== by 0x45859B: perl_construct (perl.c:264)
==17136== by 0x66B59FF: Perl_sharedsv_init (shared.xs:1252)
==17136== by 0x66BEA25: boot_threads__shared (shared.xs:1715)
==17136== by 0x5AF1C3: Perl_pp_entersub (pp_hot.c:2743)
==17136== by 0x545852: Perl_runops_debug (dump.c:2258)
==17136== by 0x460463: Perl_call_sv (perl.c:2816)
==17136== by 0x46B7DB: Perl_call_list (perl.c:4898)
And of those 45 loss records that are from threads::shared:
$ PERL_DESTRUCT_LEVEL=2 valgrind --leak-check=full --show-reachable=yes ./perl -Ilib -Mthreads -Mthreads::shared -e0 2>&1 | fgrep -c 'Perl_sharedsv_init (shared.xs:1252)'
44
$ PERL_DESTRUCT_LEVEL=2 valgrind --leak-check=full --show-reachable=yes ./perl -Ilib -Mthreads -Mthreads::shared -e0 2>&1 | fgrep -c 'Perl_sharedsv_init (shared.xs:1251)'
1
The lines in question being the last two of:
void
Perl_sharedsv_init(pTHX)
{
dTHXc;
/* This pair leaves us in shared context ... */
PL_sharedsv_space = perl_alloc();
perl_construct(PL_sharedsv_space);
I'm not sure what the best solution is. One way would be to move
PL_sharedsv_space from shared.xs into perlvar.h, and have perl_destruct()
be responsible for freeing it at the right time. The other way I can think of
is to have shared.xs attach magic to a global SV, and have that magic be
responsible for freeing it at the right time.
Am I correct in thinking that under ithreads PL_curinterp is NULL only in
the topmost parent thread? If so, the "right time" is when the C code is
called and PL_curinterp is NULL. Yes, this is only a 90% solution, as it will
only clean up properly if threads::shared was loaded by the top level thread,
but it's 90% better than what we have at the moment.
Nicholas Clark
Thread Next
-
[perl #119155] threads::shared never frees the shared space interpreter
by Nicholas Clark