xslate / p5-Mouse

Lightweight class builder for Perl, as a subset of Moose
https://metacpan.org/release/Mouse
Other
46 stars 32 forks source link

Mouse with threads does not work well Perl 5.21.2 #29

Closed syohex closed 9 years ago

syohex commented 10 years ago

This causes test failure of Text::Xslate.

Here is test program.

#!perl
package Foo;
use Mouse;

has syntax => (
    is      => 'rw',
    isa     => 'Str',
    default => 'Koron',
);

package main;
use strict;
use warnings;
use threads;

use Test::More;

my $foo = Foo->new;
is $foo->syntax, "Koron";

threads->create(sub{
    is $foo->syntax, "Koron";
})->join();

done_testing;

The test is failed with Perl 5.21.2

% perl -V
Summary of my perl5 (revision 5 version 21 subversion 2) configuration:

  Platform:
    osname=linux, osvers=3.13.0-32-generic, archname=x86_64-linux-thread-multi
    uname='linux vox 3.13.0-32-generic #57-ubuntu smp tue jul 15 03:51:08 utc 2014 x86_64 x86_64 x86_64 gnulinux '
    config_args='-Dprefix=/home/syohei/.plenv/versions/5.21.2-debug -de -Dusedevel -DDEBUGGING=-g -Dusethreads -A'eval:scriptdir=/home/syohei/.plenv/versions/5.21.2-debug/bin''
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.8.2', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
    libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=libc-2.19.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.19'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib -fstack-protector'

Characteristics of this binary (from libperl): 
  Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS
                        PERL_DONT_CREATE_GVSV
                        PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
                        PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
                        PERL_NEW_COPY_ON_WRITE PERL_PRESERVE_IVUV
                        PERL_USE_DEVEL USE_64_BIT_ALL USE_64_BIT_INT
                        USE_ITHREADS USE_LARGE_FILES USE_LOCALE
                        USE_LOCALE_COLLATE USE_LOCALE_CTYPE
                        USE_LOCALE_NUMERIC USE_LOCALE_TIME USE_PERLIO
                        USE_PERL_ATOF USE_REENTRANT_API
  Built under linux
  Compiled at Aug  5 2014 11:54:58
  %ENV:
    PERLDOC_PAGER="less -R"
  @INC:
    /home/syohei/.plenv/versions/5.21.2-debug/lib/perl5/site_perl/5.21.2/x86_64-linux-thread-multi
    /home/syohei/.plenv/versions/5.21.2-debug/lib/perl5/site_perl/5.21.2
    /home/syohei/.plenv/versions/5.21.2-debug/lib/perl5/5.21.2/x86_64-linux-thread-multi
    /home/syohei/.plenv/versions/5.21.2-debug/lib/perl5/5.21.2
    .
%  perl test.pl
ok 1
not ok 2
#   Failed test at test.pl line 22.
#          got: undef
#     expected: 'Koron'
1..2
# Looks like you failed 1 test of 2.

But the test is passed before Perl 5.21.2.

syohei@vox:% perl -V
Summary of my perl5 (revision 5 version 21 subversion 1) configuration:

  Platform:
    osname=linux, osvers=3.13.0-32-generic, archname=x86_64-linux-thread-multi
    uname='linux vox 3.13.0-32-generic #57-ubuntu smp tue jul 15 03:51:08 utc 2014 x86_64 x86_64 x86_64 gnulinux '
    config_args='-Dprefix=/home/syohei/.plenv/versions/5.21.1-debug -de -Dusedevel -DDEBUGGING=-g -Dusethreads -A'eval:scriptdir=/home/syohei/.plenv/versions/5.21.1-debug/bin''
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.8.2', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
    libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=libc-2.19.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.19'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib -fstack-protector'

Characteristics of this binary (from libperl): 
  Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS
                        PERL_DONT_CREATE_GVSV
                        PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
                        PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
                        PERL_NEW_COPY_ON_WRITE PERL_PRESERVE_IVUV
                        PERL_USE_DEVEL USE_64_BIT_ALL USE_64_BIT_INT
                        USE_ITHREADS USE_LARGE_FILES USE_LOCALE
                        USE_LOCALE_COLLATE USE_LOCALE_CTYPE
                        USE_LOCALE_NUMERIC USE_PERLIO USE_PERL_ATOF
                        USE_REENTRANT_API
  Built under linux
  Compiled at Aug  5 2014 12:55:02
  %ENV:
    PERLDOC_PAGER="less -R"
  @INC:
    /home/syohei/.plenv/versions/5.21.1-debug/lib/perl5/site_perl/5.21.1/x86_64-linux-thread-multi
    /home/syohei/.plenv/versions/5.21.1-debug/lib/perl5/site_perl/5.21.1
    /home/syohei/.plenv/versions/5.21.1-debug/lib/perl5/5.21.1/x86_64-linux-thread-multi
    /home/syohei/.plenv/versions/5.21.1-debug/lib/perl5/5.21.1
    .
% perl test.pl
ok 1
ok 2
1..2

Is this Perl issue or threads module ?

syohex commented 10 years ago

Perl 5.21.3 also fails this test.

iabyn commented 9 years ago

It's a thread safefy issue in Mouse. It has always had the potential for failure, but is more noticable in 5.21.2 onwards due to a new optimisation for looking up constant hash keys (just the HEK address is compared in the hash bucket entries, not the actual key string).

Mouse accessor XS subs have the constant key attached as magic to the CV, but also sets CvXSUBANY(xsub).any_ptr to the mg pointer as a shortcut. When a thread is cloned, the magic is cloned, but any_ptr continues pointing to the magic struct contained in the parent thread. This is bad generally (e.g. the parent thread might exit before the child thread, leaving any_ptr pointing at garbage), but specifically, the HEK embedded in the PVX field of the constant key SV points to the shared hek of the parent thread, so simple HEK pointer comparisons no longer work.

syohex commented 9 years ago

Thanks for information.

gfx commented 9 years ago

This issue is not reproduced in perl 5.21.8.

gfx commented 9 years ago

WTF. This is sometimes reproduced.