Subject: | Invalid access with lazy attribute builder + threads |
Using a lazy attribute builder with threads causes invalid memory accesses.
For example, if you run this code with valgrind:
--------
package Foo;
use Any::Mouse;
has 'max' => (isa => 'Int', is => 'ro', lazy => 1, builder => '_build_max');
sub _build_max {
return 42;
}
package main;
use threads;
my $foo = Foo->new;
threads->create(sub { print $foo->max; })->join;
--------
you get:
==14648==
42==14648== Invalid read of size 4
==14648== at 0x4EE3289: Perl_sv_free (sv.c:5631)
==14648== by 0x4ED246F: Perl_av_undef (av.c:495)
==14648== by 0x4EE2F37: Perl_sv_clear (sv.c:5507)
==14648== by 0x4EE3211: Perl_sv_free2 (sv.c:5694)
==14648== by 0x4EC346A: Perl_mg_free (mg.c:529)
==14648== by 0x4EE2CD7: Perl_sv_clear (sv.c:5470)
==14648== by 0x4EE3211: Perl_sv_free2 (sv.c:5694)
==14648== by 0x4E7EDED: Perl_gp_free (gv.c:1600)
==14648== by 0x4EE30C4: Perl_sv_clear (sv.c:5522)
==14648== by 0x4EE3211: Perl_sv_free2 (sv.c:5694)
==14648== by 0x4EDC630: S_visit (sv.c:441)
==14648== by 0x4EDCB9A: Perl_sv_clean_all (sv.c:588)
==14648== Address 0x6f9c6a8 is 3,560 bytes inside a block of size 4,080
free'd
==14648== at 0x4C282ED: free (vg_replace_malloc.c:366)
==14648== by 0x4EDCBFA: Perl_sv_free_arenas (sv.c:655)
==14648== by 0x4E7A6BD: perl_destruct (perl.c:1338)
==14648== by 0x6FFC246: S_ithread_clear (threads.xs:166)
==14648== by 0x6FFE1EA: XS_threads_join (threads.xs:1154)
==14648== by 0x4EDB264: Perl_pp_entersub (pp_hot.c:2891)
==14648== by 0x4ED2CCF: Perl_runops_standard (run.c:40)
==14648== by 0x4E7E5FD: perl_run (perl.c:2431)
==14648== by 0x400CCB: main (perlmain.c:117)
==14648==
==14648== Invalid read of size 4
==14648== at 0x4EE3290: Perl_sv_free (sv.c:5632)
==14648== by 0x4ED246F: Perl_av_undef (av.c:495)
==14648== by 0x4EE2F37: Perl_sv_clear (sv.c:5507)
==14648== by 0x4EE3211: Perl_sv_free2 (sv.c:5694)
==14648== by 0x4EC346A: Perl_mg_free (mg.c:529)
==14648== by 0x4EE2CD7: Perl_sv_clear (sv.c:5470)
==14648== by 0x4EE3211: Perl_sv_free2 (sv.c:5694)
==14648== by 0x4E7EDED: Perl_gp_free (gv.c:1600)
==14648== by 0x4EE30C4: Perl_sv_clear (sv.c:5522)
==14648== by 0x4EE3211: Perl_sv_free2 (sv.c:5694)
==14648== by 0x4EDC630: S_visit (sv.c:441)
==14648== by 0x4EDCB9A: Perl_sv_clean_all (sv.c:588)
==14648== Address 0x6f9c6ac is 3,564 bytes inside a block of size 4,080
free'd
==14648== at 0x4C282ED: free (vg_replace_malloc.c:366)
==14648== by 0x4EDCBFA: Perl_sv_free_arenas (sv.c:655)
==14648== by 0x4E7A6BD: perl_destruct (perl.c:1338)
==14648== by 0x6FFC246: S_ithread_clear (threads.xs:166)
==14648== by 0x6FFE1EA: XS_threads_join (threads.xs:1154)
==14648== by 0x4EDB264: Perl_pp_entersub (pp_hot.c:2891)
==14648== by 0x4ED2CCF: Perl_runops_standard (run.c:40)
==14648== by 0x4E7E5FD: perl_run (perl.c:2431)
==14648== by 0x400CCB: main (perlmain.c:117)
==14648==
==14648==
==14648== HEAP SUMMARY:
==14648== in use at exit: 9,621 bytes in 56 blocks
==14648== total heap usage: 50,298 allocs, 50,242 frees, 4,625,064
bytes allocated
==14648==
==14648== LEAK SUMMARY:
==14648== definitely lost: 3,872 bytes in 35 blocks
==14648== indirectly lost: 0 bytes in 0 blocks
==14648== possibly lost: 0 bytes in 0 blocks
==14648== still reachable: 5,749 bytes in 21 blocks
==14648== suppressed: 0 bytes in 0 blocks
==14648== Rerun with --leak-check=full to see details of leaked memory