Subject: | CHI::Utils 0.33 not threading safe |
Hi,
I tracked down a bug related to Perl threading and
Data::UUID. In the system I'm working on I use CHI
and threading and got segmentation faults. CHI and
threading were used in very different parts of the
system. At no time did I set or get anything from a
cache in a thread. The "use"ing of CHI::Utils was
enough to cause a segmentation fault.
See the attached test case. The error messages vary
when I run it several times. On MacOS 10.6, system
Perl 5.10 it's usually a segmentation fault. On
Debian Lenny
"glibc detected *** perl: corrupted double-linked list: 0x000000000097a910"
I also attach a patch for CHI::Utils. Unloading $ug
immediately does the trick.
my $ug = Data::UUID->new();
my $uuid = $ug->create_hex();
$ug = undef;
If I understand CHI correctly the unique_id() function
is only used in CHI::Driver::File. Even if multiple
CHI::Driver::File instances call unique_id() they won't
overlap because $suffix is kept globally and
$ug->create_hex() was never meant to be run twice.
The attached test case is not ideal. We can't catch
the segfault in an eval{} block and I don't know if
it makes sense to add threading into the CHI test
cases. I take it's a weird coincidence between modules. I
found similar problems with other CPAN modules.
Thanks for creating CHI. We use it whenever we can.
marc tobias
Subject: | perl-version.txt |
Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
Platform:
osname=darwin, osvers=10.0, archname=darwin-thread-multi-2level
uname='darwin neige.apple.com 10.0 darwin kernel version 10.0.0d8: tue may 5 19:29:59 pdt 2009; root:xnu-1437.2~2release_i386 i386 '
config_args='-ds -e -Dprefix=/usr -Dccflags=-g -pipe -Dldflags= -Dman3ext=3pm -Duseithreads -Duseshrplib -Dinc_version_list=none -Dcc=gcc-4.2'
hint=recommended, useposix=true, d_sigaction=define
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc-4.2', ccflags ='-arch x86_64 -arch i386 -arch ppc -g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing -I/usr/local/include',
optimize='-Os',
cppflags='-g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing -I/usr/local/include'
ccversion='', gccversion='4.2.1 (Apple Inc. build 5646)', 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='gcc-4.2 -mmacosx-version-min=10.6', ldflags ='-arch x86_64 -arch i386 -arch ppc -L/usr/local/lib'
libpth=/usr/local/lib /usr/lib
libs=-ldbm -ldl -lm -lutil -lc
perllibs=-ldl -lm -lutil -lc
libc=/usr/lib/libc.dylib, so=dylib, useshrplib=true, libperl=libperl.dylib
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-arch x86_64 -arch i386 -arch ppc -bundle -undefined dynamic_lookup -L/usr/local/lib'
Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP USE_64_BIT_ALL
USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES
USE_PERLIO USE_REENTRANT_API
Locally applied patches:
/Library/Perl/Updates/<version> comes before system perl directories
installprivlib and installarchlib points to the Updates directory
Built under darwin
Compiled at Jun 24 2009 00:35:27
%ENV:
PERL5LIB="/sw/lib/perl5:/sw/lib/perl5/darwin"
@INC:
/sw/lib/perl5
/sw/lib/perl5/darwin
/Library/Perl/Updates/5.10.0
/System/Library/Perl/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/5.10.0
/Library/Perl/5.10.0/darwin-thread-multi-2level
/Library/Perl/5.10.0
/Network/Library/Perl/5.10.0/darwin-thread-multi-2level
/Network/Library/Perl/5.10.0
/Network/Library/Perl
/System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.10.0
.
Subject: | threads_and_chi.t |
#!/usr/bin/perl
use strict;
use feature qw(say);
use threads;
use CHI::Util qw( unique_id );
foreach (1..10){
say unique_id();
}
foreach (1..2){
threads->create( sub { say "doing nothing." } );
}
foreach (threads->list){
$_->join;
}
say "exit.";
Subject: | chi_utils_threadsafe.patch |
--- ./lib/CHI/Util.pm 2010-01-08 16:48:52.000000000 +0000
+++ ./lib/CHI/Util.pm 2010-01-08 16:49:58.000000000 +0000
@@ -42,13 +42,11 @@
# generate a series of 0x10000 unique ids. Not to be used for hard-to-guess ids, obviously.
my $ug = Data::UUID->new();
- my $uuid;
+ my $uuid = $ug->create_hex();
+ $ug = undef;
my $suffix = 0;
sub unique_id {
- if ( !$suffix || !defined($uuid) ) {
- $uuid = $ug->create_hex();
- }
my $hex = sprintf( '%s%04x', $uuid, $suffix );
$suffix = ( $suffix + 1 ) & 0xffff;
return $hex;