Skip Menu |
Report information
Id: 127708
Status: resolved
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: randir <sergey.aleynikov [at] gmail.com>
Cc:
AdminCc:

Operating System: darwin
PatchStatus: (no value)
Severity: medium
Type: library
Perl Version: 5.22.1
Fixed In: (no value)



Subject: Coredump in call_sv under threads
This is a bug report for perl from sergey.aleynikov@gmail.com, generated with the help of perlbug 1.40 running under perl 5.22.1. ----------------------------------------------------------------- [Please describe your issue here] %cat t/80-threads.t use threads; use Test::More; my @threads = map +threads->create(sub { sleep 0.1; for (1..5_000) { is(1, 1); } }), (0..1); $_->join for splice @threads; done_testing; LC_MESSAGES="en_US.UTF-8" perl t/80-threads.t Coredumps after ~10 attempts. This issue isn't present in 5.20.2 - i've tried ~50 runs on it. This seems to be darwin-specific, as i can't reproduce it on a linux box. Stack traces are following. (lldb) t 1 * thread #1: tid = 0x0000, 0x00007fff8a378a3a libsystem_kernel.dylib`__semwait_signal + 10, stop reason = signal SIGSTOP frame #0: 0x00007fff8a378a3a libsystem_kernel.dylib`__semwait_signal + 10 libsystem_kernel.dylib`__semwait_signal + 10: -> 0x7fff8a378a3a: jae 0x7fff8a378a44 ; __semwait_signal + 20 0x7fff8a378a3c: movq %rax, %rdi 0x7fff8a378a3f: jmp 0x7fff8a37519a ; cerror 0x7fff8a378a44: retq (lldb) bt * thread #1: tid = 0x0000, 0x00007fff8a378a3a libsystem_kernel.dylib`__semwait_signal + 10, stop reason = signal SIGSTOP * frame #0: 0x00007fff8a378a3a libsystem_kernel.dylib`__semwait_signal + 10 frame #1: 0x00007fff831367f3 libsystem_pthread.dylib`pthread_join + 433 frame #2: 0x000000010b04fa90 threads.bundle`XS_threads_join(my_perl=0x00007fabf1801200, cv=<unavailable>) + 464 at threads.xs:1268 frame #3: 0x000000010ae50952 perl`Perl_pp_entersub(my_perl=0x00007fabf1801200) + 4162 at pp_hot.c:3270 frame #4: 0x000000010ae14892 perl`Perl_runops_debug(my_perl=0x00007fabf1801200) + 370 at dump.c:2234 frame #5: 0x000000010ad806c5 perl`perl_run [inlined] S_run_body(my_perl=0x00007fabf1801200, oldscope=<unavailable>) + 162 at perl.c:2448 frame #6: 0x000000010ad80623 perl`perl_run(my_perl=0x00007fabf1801200) + 1379 at perl.c:2371 frame #7: 0x000000010ad4d2bb perl`main(argc=2, argv=0x00007fff54eb3760, env=0x00007fff54eb3778) + 155 at perlmain.c:116 frame #8: 0x00007fff8c1e15fd libdyld.dylib`start + 1 (lldb) t 2 * thread #2: tid = 0x0001, 0x00007fff8a378622 libsystem_kernel.dylib`__open_nocancel + 10, stop reason = signal SIGSTOP frame #0: 0x00007fff8a378622 libsystem_kernel.dylib`__open_nocancel + 10 libsystem_kernel.dylib`__open_nocancel + 10: -> 0x7fff8a378622: jae 0x7fff8a37862c ; __open_nocancel + 20 0x7fff8a378624: movq %rax, %rdi 0x7fff8a378627: jmp 0x7fff8a375175 ; cerror_nocancel 0x7fff8a37862c: retq (lldb) bt * thread #2: tid = 0x0001, 0x00007fff8a378622 libsystem_kernel.dylib`__open_nocancel + 10, stop reason = signal SIGSTOP * frame #0: 0x00007fff8a378622 libsystem_kernel.dylib`__open_nocancel + 10 frame #1: 0x00007fff8eaa1348 libsystem_c.dylib`__part_load_locale + 171 frame #2: 0x00007fff8eaa15f7 libsystem_c.dylib`__messages_load_locale + 205 frame #3: 0x00007fff8eaa3e05 libsystem_c.dylib`loadlocale + 282 frame #4: 0x000000010af3b8a1 perl`Perl_my_strerror(my_perl=<unavailable>, errnum=<unavailable>) + 257 at locale.c:1710 frame #5: 0x000000010ae23cbd perl`Perl_magic_get(my_perl=0x00007fabf2005a00, sv=0x00007fabf2195060, mg=<unavailable>) + 1069 at mg.c:934 frame #6: 0x000000010ae21eb0 perl`Perl_mg_get(my_perl=0x00007fabf2005a00, sv=0x00007fabf2195060) + 416 at mg.c:197 frame #7: 0x000000010aeafce4 perl`Perl_save_scalar(my_perl=0x00007fabf2005a00, gv=0x00007fabf2195048) + 292 at scope.c:225 frame #8: 0x000000010ae420cc perl`Perl_pp_gvsv(my_perl=0x00007fabf2005a00) + 284 at pp_hot.c:63 frame #9: 0x000000010ae14892 perl`Perl_runops_debug(my_perl=0x00007fabf2005a00) + 370 at dump.c:2234 frame #10: 0x000000010ad8134c perl`Perl_call_sv(my_perl=0x00007fabf2005a00, sv=<unavailable>, flags=11) + 1340 at perl.c:2769 frame #11: 0x000000010b0531a3 threads.bundle`S_ithread_run(arg=0x00007fabf1591140) + 899 at threads.xs:527 frame #12: 0x00007fff83132899 libsystem_pthread.dylib`_pthread_body + 138 frame #13: 0x00007fff8313272a libsystem_pthread.dylib`_pthread_start + 137 frame #14: 0x00007fff83136fc9 libsystem_pthread.dylib`thread_start + 13 (lldb) t 3 * thread #3: tid = 0x0002, 0x00007fff8eaa163d libsystem_c.dylib`__messages_load_locale + 275, stop reason = signal SIGSTOP frame #0: 0x00007fff8eaa163d libsystem_c.dylib`__messages_load_locale + 275 libsystem_c.dylib`__messages_load_locale + 275: -> 0x7fff8eaa163d: movq 0x8(%rdi), %rax 0x7fff8eaa1641: testq %rax, %rax 0x7fff8eaa1644: je 0x7fff8eaa164f ; __messages_load_locale + 293 0x7fff8eaa1646: callq *%rax (lldb) bt * thread #3: tid = 0x0002, 0x00007fff8eaa163d libsystem_c.dylib`__messages_load_locale + 275, stop reason = signal SIGSTOP * frame #0: 0x00007fff8eaa163d libsystem_c.dylib`__messages_load_locale + 275 frame #1: 0x00007fff8eaa3e05 libsystem_c.dylib`loadlocale + 282 frame #2: 0x000000010af3b861 perl`Perl_my_strerror(my_perl=0x00007fabf2173600, errnum=60) + 193 at locale.c:1704 frame #3: 0x000000010ae23cbd perl`Perl_magic_get(my_perl=0x00007fabf2173600, sv=0x00007fabf220a060, mg=<unavailable>) + 1069 at mg.c:934 frame #4: 0x000000010ae21eb0 perl`Perl_mg_get(my_perl=0x00007fabf2173600, sv=0x00007fabf220a060) + 416 at mg.c:197 frame #5: 0x000000010aeafce4 perl`Perl_save_scalar(my_perl=0x00007fabf2173600, gv=0x00007fabf220a048) + 292 at scope.c:225 frame #6: 0x000000010ae420cc perl`Perl_pp_gvsv(my_perl=0x00007fabf2173600) + 284 at pp_hot.c:63 frame #7: 0x000000010ae14892 perl`Perl_runops_debug(my_perl=0x00007fabf2173600) + 370 at dump.c:2234 frame #8: 0x000000010ad8134c perl`Perl_call_sv(my_perl=0x00007fabf2173600, sv=<unavailable>, flags=11) + 1340 at perl.c:2769 frame #9: 0x000000010b0531a3 threads.bundle`S_ithread_run(arg=0x00007fabf1604b40) + 899 at threads.xs:527 frame #10: 0x00007fff83132899 libsystem_pthread.dylib`_pthread_body + 138 frame #11: 0x00007fff8313272a libsystem_pthread.dylib`_pthread_start + 137 frame #12: 0x00007fff83136fc9 libsystem_pthread.dylib`thread_start + 13 Both t 2 and t 3 are on the following line: (lldb) f 2 frame #2: 0x000000010af3b861 perl`Perl_my_strerror(my_perl=0x00007fabf2173600, errnum=60) + 193 at locale.c:1704 1701 /* The next setlocale likely will zap this, so create a copy */ 1702 save_locale = savepv(save_locale); 1703 -> 1704 setlocale(LC_MESSAGES, "C"); 1705 1706 /* This points to the static space in Strerror, with all its 1707 * limitations */ [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=library severity=medium --- Site configuration information for perl 5.22.1: Configured by dur-randir at Mon Mar 14 04:43:48 MSK 2016. Summary of my perl5 (revision 5 version 22 subversion 1) configuration: Platform: osname=darwin, osvers=13.4.0, archname=darwin-thread-multi-2level uname='darwin isengard.local 13.4.0 darwin kernel version 13.4.0: wed mar 18 16:20:14 pdt 2015; root:xnu-2422.115.14~1release_x86_64 x86_64 ' config_args='-de -Dprefix=/Users/dur-randir/perlbrew/perls/perl-5.22.1-thr-dbg -Dusethreads -DDEBUGGING -Aeval:scriptdir=/Users/dur-randir/perlbrew/perls/perl-5.22.1-thr-dbg/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 ='-fno-common -DPERL_DARWIN -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include', optimize='-O3 -g', cppflags='-fno-common -DPERL_DARWIN -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -fstack-protector -L/usr/local/lib' libpth=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/lib /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/lib /usr/local/lib /usr/lib libs=-lpthread -lgdbm -ldbm -ldl -lm -lutil -lc perllibs=-lpthread -ldl -lm -lutil -lc libc=, so=dylib, useshrplib=false, libperl=libperl.a gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/usr/local/lib -fstack-protector' --- @INC for perl 5.22.1: /Users/dur-randir/perlbrew/perls/perl-5.22.1-thr-dbg/lib/site_perl/5.22.1/darwin-thread-multi-2level /Users/dur-randir/perlbrew/perls/perl-5.22.1-thr-dbg/lib/site_perl/5.22.1 /Users/dur-randir/perlbrew/perls/perl-5.22.1-thr-dbg/lib/5.22.1/darwin-thread-multi-2level /Users/dur-randir/perlbrew/perls/perl-5.22.1-thr-dbg/lib/5.22.1 . --- Environment for perl 5.22.1: DYLD_LIBRARY_PATH (unset) HOME=/Users/dur-randir LANG=en_US.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/Users/dur-randir/perlbrew/bin:/Users/dur-randir/perlbrew/perls/perl-5.22.1-thr-dbg/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/texbin PERLBREW_BASHRC_VERSION=0.69 PERLBREW_HOME=/Users/dur-randir/.perlbrew PERLBREW_MANPATH=/Users/dur-randir/perlbrew/perls/perl-5.22.1-thr-dbg/man PERLBREW_PATH=/Users/dur-randir/perlbrew/bin:/Users/dur-randir/perlbrew/perls/perl-5.22.1-thr-dbg/bin PERLBREW_PERL=perl-5.22.1-thr-dbg PERLBREW_ROOT=/Users/dur-randir/perlbrew PERLBREW_VERSION=0.69 PERL_BADLANG (unset) SHELL=/usr/local/bin/zsh
RT-Send-CC: perl5-porters [...] perl.org
On Mon Mar 14 05:24:12 2016, randir wrote: Show quoted text
> Both t 2 and t 3 are on the following line: > > (lldb) f 2 > frame #2: 0x000000010af3b861 > perl`Perl_my_strerror(my_perl=0x00007fabf2173600, errnum=60) + 193 at > locale.c:1704 > 1701 /* The next setlocale likely will zap this, so > create a copy */ > 1702 save_locale = savepv(save_locale); > 1703 > -> 1704 setlocale(LC_MESSAGES, "C"); > 1705 > 1706 /* This points to the static space in Strerror, > with all its > 1707 * limitations */
I suspect we have two bugs here: a) setlocale() isn't re-entrant, and we call it from multiple threads without any sort of guard b) setlocale() sets the process-wide locale, so we have possible race conditions between threads. The first could be fixed by guarding use of setlocale() with a mutex, but the second is more complex to fix. On system where they're supported we could use newlocale(), uselocale(), freelocale() etc, but we still support systems that don't have those functions and never will. Tony
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.8k
On Mon Mar 14 16:11:44 2016, tonyc wrote: Show quoted text
> On Mon Mar 14 05:24:12 2016, randir wrote:
> > Both t 2 and t 3 are on the following line: > > > > (lldb) f 2 > > frame #2: 0x000000010af3b861 > > perl`Perl_my_strerror(my_perl=0x00007fabf2173600, errnum=60) + 193 at > > locale.c:1704 > > 1701 /* The next setlocale likely will zap this, so > > create a copy */ > > 1702 save_locale = savepv(save_locale); > > 1703 > > -> 1704 setlocale(LC_MESSAGES, "C"); > > 1705 > > 1706 /* This points to the static space in Strerror, > > with all its > > 1707 * limitations */
> > I suspect we have two bugs here: > > a) setlocale() isn't re-entrant, and we call it from multiple threads > without any sort of guard > > b) setlocale() sets the process-wide locale, so we have possible race > conditions between threads. > > The first could be fixed by guarding use of setlocale() with a mutex, > but the second is more complex to fix. > > On system where they're supported we could use newlocale(), > uselocale(), freelocale() etc, but we still support systems that don't > have those functions and never will. > > Tony
I have tried to reproduce this on a Darwin Kernel Version 15.3.0, and can't. The particular machine doesn't have LC_MESSAGES translated into other than English, and that could explain it. There really is only one LC_MESSAGES locale on our machine. You can easily see if yours are translated, for example with LC_MESSAGES=de_DE.UTF-8 ./perl -le 'use locale; $!=1; print "$!"'; and see if English or German comes out. I have written some code that hopefully fixes this problem. It is available here: http://perl5.git.perl.org/perl.git/shortlog/refs/heads/smoke-me/khw-regcomp If it's possible, could you compile and try this to see if your problem is solved by it. -- Karl Williamson
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 2.9k
On Fri Mar 18 22:03:37 2016, khw wrote: Show quoted text
> On Mon Mar 14 16:11:44 2016, tonyc wrote:
> > On Mon Mar 14 05:24:12 2016, randir wrote:
> > > Both t 2 and t 3 are on the following line: > > > > > > (lldb) f 2 > > > frame #2: 0x000000010af3b861 > > > perl`Perl_my_strerror(my_perl=0x00007fabf2173600, errnum=60) + 193 > > > at > > > locale.c:1704 > > > 1701 /* The next setlocale likely will zap this, so > > > create a copy */ > > > 1702 save_locale = savepv(save_locale); > > > 1703 > > > -> 1704 setlocale(LC_MESSAGES, "C"); > > > 1705 > > > 1706 /* This points to the static space in Strerror, > > > with all its > > > 1707 * limitations */
> > > > I suspect we have two bugs here: > > > > a) setlocale() isn't re-entrant, and we call it from multiple threads > > without any sort of guard > > > > b) setlocale() sets the process-wide locale, so we have possible race > > conditions between threads. > > > > The first could be fixed by guarding use of setlocale() with a mutex, > > but the second is more complex to fix. > > > > On system where they're supported we could use newlocale(), > > uselocale(), freelocale() etc, but we still support systems that > > don't > > have those functions and never will. > > > > Tony
> > I have tried to reproduce this on a Darwin Kernel Version 15.3.0, and > can't. The particular machine doesn't have LC_MESSAGES translated > into other than English, and that could explain it. There really is > only one LC_MESSAGES locale on our machine. You can easily see if > yours are translated, for example with > > LC_MESSAGES=de_DE.UTF-8 ./perl -le 'use locale; $!=1; print "$!"'; > > and see if English or German comes out. I have written some code that > hopefully fixes this problem. It is available here: > > http://perl5.git.perl.org/perl.git/shortlog/refs/heads/smoke-me/khw- > regcomp > > If it's possible, could you compile and try this to see if your > problem is solved by it.
The current state of affairs is that the messages are displayed in English on the OP's machine, so my speculation that was behind the difference in results on the Darwin machine available to me, was wrong. However, I have experimental code that uses mutexes in the area that was failing, and there have been no failures on that. I also tried using the thread-only locale functions, but we got failures with those even so. I do not know why at this point. The whole design of perl locale handling can be considered flawed in this regard, but this is the only failure anyone has ever reported like this. This area was changed in 5.22, and now it's showing up. But it was based on how perl was intended to operate in other areas. Some of that was broken, and did not operate as intended, and that could avoid this bug. But the code was changed to operate as intended, and this was done before 5.22. And there have been no reports of failure. -- Karl Williamson
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 5.5k
On Sat Mar 19 22:20:16 2016, khw wrote: Show quoted text
> The current state of affairs is that the messages are displayed in > English on the OP's machine, so my speculation that was behind the > difference in results on the Darwin machine available to me, was > wrong. However, I have experimental code that uses mutexes in the > area that was failing, and there have been no failures on that. I > also tried using the thread-only locale functions, but we got failures > with those even so. I do not know why at this point.
I managed to reproduce the crash on the VM: grannysmith:perl tony$ ulimit -c unlimited grannysmith:perl tony$ while ./perl -Ilib ../127708.pl ; do date ; done ... ok 399 ok 400 ok 401 ok 402 ok 403 ok 404 ok 405 ok 406 ok 407 ok 408 ok 409 Segmentation fault: 11 (core dumped) grannysmith:perl tony$ ls -l /cores total 1267176 -r-------- 1 tony admin 648794112 21 Mar 09:30 core.8674 grannysmith:perl tony$ man gdb No manual entry for gdb grannysmith:perl tony$ gdb ./perl /cores/core.8674 -bash: gdb: command not found grannysmith:perl tony$ lldb ./perl /cores/core.8674 (lldb) target create "./perl" Current executable set to './perl' (x86_64). (lldb) settings set -- target.run-args "/cores/core.8674" (lldb) bt error: invalid process (lldb) q grannysmith:perl tony$ man lldb grannysmith:perl tony$ lldb -c /cores/core.8674 ./perl (lldb) target create "./perl" --core "/cores/core.8674" warning: (x86_64) /cores/core.8674 load command 67 LC_SEGMENT_64 has a fileoff + filesize (0x26abe000) that extends beyond the end of the file (0x26abd000), the segment will be truncated to match warning: (x86_64) /cores/core.8674 load command 68 LC_SEGMENT_64 has a fileoff (0x26abe000) that extends beyond the end of the file (0x26abd000), ignoring this section Core file '/cores/core.8674' (x86_64) was loaded. (lldb) bt * thread #1: tid = 0x0000, 0x00007fff832c4206 libsystem_kernel.dylib`__semwait_signal + 10, stop reason = signal SIGSTOP * frame #0: 0x00007fff832c4206 libsystem_kernel.dylib`__semwait_signal + 10 frame #1: 0x00007fff8738ec27 libsystem_pthread.dylib`pthread_join + 444 frame #2: 0x000000010e44793b threads.bundle`XS_threads_join(my_perl=0x00007fe182002600, cv=<unavailable>) + 539 at threads.xs:1317 frame #3: 0x000000010e00835c perl`Perl_pp_entersub(my_perl=0x00007fe182002600) + 4684 at pp_hot.c:3985 frame #4: 0x000000010dfc977f perl`Perl_runops_debug(my_perl=0x00007fe182002600) + 511 at dump.c:2239 frame #5: 0x000000010df3072d perl`perl_run [inlined] S_run_body(my_perl=0x00007fe182002600, oldscope=<unavailable>) + 493 at perl.c:2479 frame #6: 0x000000010df30540 perl`perl_run(my_perl=0x00007fe182002600) + 1072 at perl.c:2402 frame #7: 0x000000010defc8f1 perl`main(argc=<unavailable>, argv=<unavailable>, env=<unavailable>) + 145 at perlmain.c:116 frame #8: 0x00007fff86c3d5ad libdyld.dylib`start + 1 (lldb) t 2 * thread #2: tid = 0x0001, 0x000000010df050e0 perl`Perl_sawparens(my_perl=0x00007fe18203a200, o=0x00007fe181dc1e08) at op.c:3739, stop reason = signal SIGSTOP frame #0: 0x000000010df050e0 perl`Perl_sawparens(my_perl=0x00007fe18203a200, o=0x00007fe181dc1e08) at op.c:3739 3736 3737 OP * 3738 Perl_sawparens(pTHX_ OP *o) -> 3739 { 3740 PERL_UNUSED_CONTEXT; 3741 if (o) 3742 o->op_flags |= OPf_PARENS; (lldb) t 3 * thread #3: tid = 0x0002, 0x00007fff949554bb libsystem_c.dylib`__messages_load_locale + 262, stop reason = signal SIGSTOP frame #0: 0x00007fff949554bb libsystem_c.dylib`__messages_load_locale + 262 libsystem_c.dylib`__messages_load_locale: -> 0x7fff949554bb <+262>: movq 0x8(%rdi), %rax 0x7fff949554bf <+266>: testq %rax, %rax 0x7fff949554c2 <+269>: je 0x7fff949554cd ; <+280> 0x7fff949554c4 <+271>: callq *%rax (lldb) t 4 error: invalid thread #4. (lldb) bt warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available. * thread #3: tid = 0x0002, 0x00007fff949554bb libsystem_c.dylib`__messages_load_locale + 262, stop reason = signal SIGSTOP * frame #0: 0x00007fff949554bb libsystem_c.dylib`__messages_load_locale + 262 frame #1: 0x00007fff94957cdb libsystem_c.dylib`loadlocale + 216 frame #2: 0x000000010e100671 perl`Perl_my_strerror(my_perl=0x00007fe1822a4800, errnum=60) + 193 at locale.c:1825 frame #3: 0x000000010dfd8c96 perl`Perl_magic_get(my_perl=0x00007fe1822a4800, sv=0x00007fe182251bb0, mg=<unavailable>) + 1558 at mg.c:934 frame #4: 0x000000010dfd6c7d perl`Perl_mg_get(my_perl=0x00007fe1822a4800, sv=0x00007fe182251bb0) + 413 at mg.c:197 frame #5: 0x000000010e06de6f perl`Perl_save_scalar(my_perl=0x00007fe1822a4800, gv=0x00007fe182251b98) + 255 at scope.c:247 frame #6: 0x000000010dff78c8 perl`Perl_pp_gvsv(my_perl=0x00007fe1822a4800) + 216 at pp_hot.c:62 frame #7: 0x000000010dfc977f perl`Perl_runops_debug(my_perl=0x00007fe1822a4800) + 511 at dump.c:2239 frame #8: 0x000000010df31517 perl`Perl_call_sv(my_perl=0x00007fe1822a4800, sv=<unavailable>, flags=<unavailable>) + 1607 at perl.c:2803 frame #9: 0x000000010e44c370 threads.bundle`S_jmpenv_run(my_perl=0x00007fe1822a4800, action=<unavailable>, thread=<unavailable>, len_p=0x0000700000103eb0, exit_app_p=<unavailable>, exit_code_p=<unavailable>) + 528 at threads.xs:498 frame #10: 0x000000010e44ac62 threads.bundle`S_ithread_run(arg=0x00007fe181cd3ae0) + 658 at threads.xs:594 frame #11: 0x00007fff8738dc13 libsystem_pthread.dylib`_pthread_body + 131 frame #12: 0x00007fff8738db90 libsystem_pthread.dylib`_pthread_start + 168 frame #13: 0x00007fff8738b375 libsystem_pthread.dylib`thread_start + 13 (lldb) ^D Tony
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.8k
On Sat Mar 19 22:20:16 2016, khw wrote: Show quoted text
> On Fri Mar 18 22:03:37 2016, khw wrote:> The whole design of perl locale handling can be considered flawed in > this regard, but this is the only failure anyone has ever reported > like this. This area was changed in 5.22, and now it's showing up. > But it was based on how perl was intended to operate in other areas. > Some of that was broken, and did not operate as intended, and that > could avoid this bug. But the code was changed to operate as > intended, and this was done before 5.22. And there have been no > reports of failure.
The current code in khw-locale has a race, at least in Perl_my_strerror(): #ifdef USE_LOCALE_MESSAGES if (! IN_LC(LC_MESSAGES)) { char * save_locale = setlocale(LC_MESSAGES, NULL); if (! isNAME_C_OR_POSIX(save_locale)) { DECLARATION_FOR_SAVE_AND_SWITCH_LOCALE; char *errstr; SAVE_AND_SWITCH_LOCALE(LC_MESSAGES, save_locale, "C"); /* This points to the static space in Strerror, with all its * limitations */ errstr = Strerror(errnum); RESTORE_LOCALE; return errstr; } } #endif Here you're fetching the current locale without holding the mutex, this means that another thread could be in the process of changing the locale while we're calling setlocale(). This showed as a bad save_local value (in one case "enDIE__" followed by more junk) and a failed call to setlocale() when resetting the locale. Also, if we setlocale() to an external locale, it's possible the string returned by strerror() could be released or overwritten when we switch locale back to "C", so it should probably savepv() the result (and SAVEFREEPV() to free it). If the croaks() in the macros are caught it's possible for the mutex to remain locked, leading to horrible things happening (which I haven't tried to fix.) Tony
Subject: 0001-fix-some-races-in-the-new-locale-code.patch
From 0a75df19a87b13915b2538b3d25bcff881715270 Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Mon, 21 Mar 2016 11:33:28 +1100 Subject: fix some races in the new locale code --- locale.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/locale.c b/locale.c index 1bb3687..d000d93 100644 --- a/locale.c +++ b/locale.c @@ -67,6 +67,9 @@ freelocale(LoCaLe_ObJeCt); \ } STMT_END +#define LOCALE_LOCK +#define LOCALE_UNLOCK + #else #define LOCALE_LOCK MUTEX_LOCK(&PL_locale_mutex) @@ -79,16 +82,14 @@ STMT_START { \ SaVe_LoCaLe = savepv(old_locale); \ CaTeGoRy = category; \ - LOCALE_LOCK; \ if (! setlocale(category, new_locale)) Perl_croak(aTHX_ \ - "panic: setlocale failed; errno=%d", errno); \ + "panic: setlocale(%d, %s) failed; errno=%d", category, new_locale, errno); \ } STMT_END # define RESTORE_LOCALE \ STMT_START { \ if (! setlocale(CaTeGoRy, SaVe_LoCaLe)) Perl_croak(aTHX_ \ - "panic: setlocale failed; errno=%d", errno); \ - LOCALE_UNLOCK; \ + "panic: setlocale(%d, %s) failed; errno=%d", CaTeGoRy, SaVe_LoCaLe, errno); \ Safefree(SaVe_LoCaLe); \ } STMT_END @@ -447,12 +448,14 @@ Perl_new_ctype(pTHX_ const char *newctype) if (IN_LC(LC_CTYPE)) { DECLARATION_FOR_SAVE_AND_SWITCH_LOCALE; + LOCALE_LOCK; SAVE_AND_SWITCH_LOCALE(LC_CTYPE, newctype, "C"); /* The '0' below suppresses a bogus gcc compiler warning */ Perl_warner(aTHX_ packWARN(WARN_LOCALE), SvPVX(PL_warn_locale), 0); RESTORE_LOCALE; + LOCALE_UNLOCK; SvREFCNT_dec_NN(PL_warn_locale); PL_warn_locale = NULL; } @@ -1858,21 +1861,34 @@ Perl_my_strerror(pTHX_ const int errnum) { #ifdef USE_LOCALE_MESSAGES if (! IN_LC(LC_MESSAGES)) { - char * save_locale = setlocale(LC_MESSAGES, NULL); + char * save_locale; + char *errstr; + + LOCALE_LOCK; + + save_locale = setlocale(LC_MESSAGES, NULL); if (! isNAME_C_OR_POSIX(save_locale)) { DECLARATION_FOR_SAVE_AND_SWITCH_LOCALE; - char *errstr; SAVE_AND_SWITCH_LOCALE(LC_MESSAGES, save_locale, "C"); /* This points to the static space in Strerror, with all its - * limitations */ - errstr = Strerror(errnum); + * limitations. + * Or in a loaded locale, into something that might go away + * when we switch the locale back */ + errstr = savepv(Strerror(errnum)); RESTORE_LOCALE; - - return errstr; } + else { + errstr = savepv(Strerror(errnum)); + } + + LOCALE_UNLOCK; + + SAVEFREEPV(errstr); + + return errstr; } #endif -- 2.5.4 (Apple Git-61)
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 242b
On Fri Mar 18 22:03:37 2016, khw wrote: Show quoted text
> If it's possible, could you compile and try this to see if your > problem is solved by it.
With the my_strerror() fixes and changing to xlocale.h (probe patch attached) it seems to work for me. Tony
Subject: 0002-add-d_duplocale-and-i_locale-Configure-probes.patch
From c0a1b6c30e2074ad7fef7bb3f2bdeab5ebb92b2d Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Mon, 21 Mar 2016 12:12:58 +1100 Subject: add d_duplocale and i_locale Configure probes --- Configure | 12 ++++++++++++ Cross/config.sh-arm-linux | 2 ++ NetWare/config.wc | 2 ++ Porting/Glossary | 9 +++++++++ Porting/config.sh | 2 ++ config_h.SH | 11 +++++++++++ configure.com | 2 ++ plan9/config_sh.sample | 2 ++ symbian/config.sh | 2 ++ uconfig.h | 15 +++++++++++++-- uconfig.sh | 2 ++ uconfig64.sh | 2 ++ win32/config.ce | 2 ++ win32/config.gc | 2 ++ win32/config.vc | 2 ++ 15 files changed, 67 insertions(+), 2 deletions(-) diff --git a/Configure b/Configure index f8d4abd..06d3dbe 100755 --- a/Configure +++ b/Configure @@ -443,6 +443,7 @@ d_drand48_r='' drand48_r_proto='' d_drand48proto='' d_dup2='' +d_duplocale='' d_eaccess='' d_endgrent='' d_endgrent_r='' @@ -1073,6 +1074,7 @@ i_stdarg='' i_varargs='' i_varhdr='' i_vfork='' +i_xlocale='' d_inc_version_list='' inc_version_list='' inc_version_list_init='' @@ -16621,6 +16623,10 @@ eval $inlibc set nearbyint d_nearbyint eval $inlibc +: see if this is an xlocale.h system +set xlocale.h i_xlocale +eval $inhdr + : see if newlocale exists set newlocale d_newlocale eval $inlibc @@ -16633,6 +16639,10 @@ eval $inlibc set uselocale d_uselocale eval $inlibc +: see if duplocale exists +set duplocale d_duplocale +eval $inlibc + : see if nextafter exists set nextafter d_nextafter eval $inlibc @@ -24303,6 +24313,7 @@ d_dosuid='$d_dosuid' d_drand48_r='$d_drand48_r' d_drand48proto='$d_drand48proto' d_dup2='$d_dup2' +d_duplocale='$d_duplocale' d_eaccess='$d_eaccess' d_endgrent='$d_endgrent' d_endgrent_r='$d_endgrent_r' @@ -24942,6 +24953,7 @@ i_values='$i_values' i_varargs='$i_varargs' i_varhdr='$i_varhdr' i_vfork='$i_vfork' +i_xlocale='$i_xlocale' ignore_versioned_solibs='$ignore_versioned_solibs' inc_version_list='$inc_version_list' inc_version_list_init='$inc_version_list_init' diff --git a/Cross/config.sh-arm-linux b/Cross/config.sh-arm-linux index 1a4718b..3a719d3 100644 --- a/Cross/config.sh-arm-linux +++ b/Cross/config.sh-arm-linux @@ -172,6 +172,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='define' d_dup2='define' +d_duplocale='undef' d_eaccess='undef' d_endgrent='define' d_endgrent_r='undef' @@ -802,6 +803,7 @@ i_values='define' i_varargs='undef' i_varhdr='stdarg.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='y' inc_version_list=' ' inc_version_list_init='0' diff --git a/NetWare/config.wc b/NetWare/config.wc index bf8dc11..f0ac374 100644 --- a/NetWare/config.wc +++ b/NetWare/config.wc @@ -159,6 +159,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='undef' d_dup2='define' +d_duplocale='undef' d_eaccess='undef' d_endgrent='undef' d_endgrent_r='undef' @@ -784,6 +785,7 @@ i_values='undef' i_varargs='undef' i_varhdr='varargs.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='' inc_version_list='' inc_version_list_init='0' diff --git a/Porting/Glossary b/Porting/Glossary index 4ff252f..316e195 100644 --- a/Porting/Glossary +++ b/Porting/Glossary @@ -714,6 +714,11 @@ d_dup2 (d_dup2.U): This variable conditionally defines HAS_DUP2 if dup2() is available to duplicate file descriptors. +d_duplocale (d_newlocale.U): + This variable conditionally defines the HAS_DUPLOCALE symbol, which + indicates to the C program that the duplocale() routine is available + to duplicate a locale object. + d_eaccess (d_eaccess.U): This variable conditionally defines the HAS_EACCESS symbol, which indicates to the C program that the eaccess() routine is available. @@ -3692,6 +3697,10 @@ i_vfork (i_vfork.U): This variable conditionally defines the I_VFORK symbol, and indicates whether a C program should include vfork.h. +i_xlocale (newlocale.U): + This symbol, if defined, indicates to the C program that it should + include <xlocale.h> to get uselocale() and it's friends + ignore_versioned_solibs (libs.U): This variable should be non-empty if non-versioned shared libraries (libfoo.so.x.y) are to be ignored (because they diff --git a/Porting/config.sh b/Porting/config.sh index b123dc3..eec626a 100644 --- a/Porting/config.sh +++ b/Porting/config.sh @@ -181,6 +181,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='define' d_dup2='define' +d_duplocale='undef' d_eaccess='define' d_endgrent='define' d_endgrent_r='undef' @@ -817,6 +818,7 @@ i_values='define' i_varargs='undef' i_varhdr='stdarg.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='y' inc_version_list='' inc_version_list_init='0' diff --git a/config_h.SH b/config_h.SH index 532238e..74f18c4 100755 --- a/config_h.SH +++ b/config_h.SH @@ -4163,9 +4163,20 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un * This symbol, if defined, indicates that the uselocale routine is * available to set the current locale for the calling thread. */ +/* HAS_DUPLOCALE: + * This symbol, if defined, indicates that the duplocale routine is + * available to duplicate a locale object. + */ #$d_newlocale HAS_NEWLOCALE /**/ #$d_freelocale HAS_FREELOCALE /**/ #$d_uselocale HAS_USELOCALE /**/ +#$d_duplocale HAS_DUPLOCALE /**/ + + /* I_XLOCALE: + * This symbol, if defined, indicates to the C program that it should + * include <xlocale.h> to get uselocale() and it's friends + */ +#$i_xlocale I_XLOCALE /**/ /* HAS_NEXTAFTER: * This symbol, if defined, indicates that the nextafter routine is diff --git a/configure.com b/configure.com index 0128c64..2478057 100644 --- a/configure.com +++ b/configure.com @@ -6576,6 +6576,7 @@ $ WC "i_values='undef'" $ WC "i_varargs='undef'" $ WC "i_varhdr='stdarg.h'" $ WC "i_vfork='undef'" +$ WC "i_xlocale='undef'" $ WC "inc_version_list='0'" $ WC "inc_version_list_init='0'" $ WC "installarchlib='" + installarchlib + "'" @@ -6860,6 +6861,7 @@ $ ENDIF $ WC "d_crypt_r='undef'" $ WC "d_ctermid_r='undef'" $ WC "d_drand48_r='undef'" +$ WC "d_duplocale='undef'" $ WC "d_endgrent_r='undef'" $ WC "d_endhostent_r='undef'" $ WC "d_endnetent_r='undef'" diff --git a/plan9/config_sh.sample b/plan9/config_sh.sample index a0b0bf3..2e14bf4 100644 --- a/plan9/config_sh.sample +++ b/plan9/config_sh.sample @@ -172,6 +172,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='undef' d_dup2='define' +d_duplocale='undef' d_eaccess='undef' d_endgrent='define' d_endgrent_r='undef' @@ -796,6 +797,7 @@ i_values='undef' i_varargs='undef' i_varhdr='stdarg.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='' inc_version_list=' ' inc_version_list_init='0' diff --git a/symbian/config.sh b/symbian/config.sh index 603ef44..459e7e0 100644 --- a/symbian/config.sh +++ b/symbian/config.sh @@ -116,6 +116,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='undef' d_dup2='undef' +d_duplocale='undef' d_eaccess='undef' d_endgrent='undef' d_endgrent_r='undef' @@ -723,6 +724,7 @@ i_values='undef' i_varargs='undef' i_varhdr='stdarg.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='y' inc_version_list='' inc_version_list_init='0' diff --git a/uconfig.h b/uconfig.h index f87fb1a..2418a53 100644 --- a/uconfig.h +++ b/uconfig.h @@ -4128,9 +4128,20 @@ * This symbol, if defined, indicates that the uselocale routine is * available to set the current locale for the calling thread. */ +/* HAS_DUPLOCALE: + * This symbol, if defined, indicates that the duplocale routine is + * available to duplicate a locale object. + */ /*#define HAS_NEWLOCALE / **/ /*#define HAS_FREELOCALE / **/ /*#define HAS_USELOCALE / **/ +/*#define HAS_DUPLOCALE / **/ + + /* I_XLOCALE: + * This symbol, if defined, indicates to the C program that it should + * include <xlocale.h> to get uselocale() and it's friends + */ +/*#define I_XLOCALE / **/ /* HAS_NEXTAFTER: * This symbol, if defined, indicates that the nextafter routine is @@ -5241,6 +5252,6 @@ #endif /* Generated from: - * 01a33ec4d20289fa524203757339606daef1a014ff6b693d38234495023ac9e7 config_h.SH - * d2f05caf5dc56031d3338c8f42e9e317ae1e53faa7b51285d0d6ebc343f8a333 uconfig.sh + * 7ed39513c0949dfd5f9cfe8d639eb5ad61bc71d6ac6b0b524a4f95ed2197e38b config_h.SH + * e38c64797e19f0328be3383bd28b402329af4d771163f7596ec5e6357235698d uconfig.sh * ex: set ro: */ diff --git a/uconfig.sh b/uconfig.sh index 12bbfd1..98c471d 100644 --- a/uconfig.sh +++ b/uconfig.sh @@ -110,6 +110,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='undef' d_dup2='undef' +d_duplocale='undef' d_eaccess='undef' d_endgrent='undef' d_endgrent_r='undef' @@ -709,6 +710,7 @@ i_values='undef' i_varargs='undef' i_varhdr='stdarg.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='y' inc_version_list_init='NULL' installstyle='lib/perl5' diff --git a/uconfig64.sh b/uconfig64.sh index 4b8c3ac..bb512f2 100644 --- a/uconfig64.sh +++ b/uconfig64.sh @@ -111,6 +111,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='undef' d_dup2='undef' +d_duplocale='undef' d_eaccess='undef' d_endgrent='undef' d_endgrent_r='undef' @@ -710,6 +711,7 @@ i_values='undef' i_varargs='undef' i_varhdr='stdarg.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='y' inc_version_list_init='NULL' installstyle='lib/perl5' diff --git a/win32/config.ce b/win32/config.ce index 7e6fe40..37c0a43 100644 --- a/win32/config.ce +++ b/win32/config.ce @@ -157,6 +157,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='undef' d_dup2='define' +d_duplocale='undef' d_eaccess='undef' d_endgrent='undef' d_endgrent_r='undef' @@ -780,6 +781,7 @@ i_values='undef' i_varargs='undef' i_varhdr='varargs.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='' inc_version_list='' inc_version_list_init='0' diff --git a/win32/config.gc b/win32/config.gc index e8179cc..09290b6 100644 --- a/win32/config.gc +++ b/win32/config.gc @@ -159,6 +159,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='undef' d_dup2='define' +d_duplocale='undef' d_eaccess='undef' d_endgrent='undef' d_endgrent_r='undef' @@ -792,6 +793,7 @@ i_values='undef' i_varargs='undef' i_varhdr='varargs.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='' inc_version_list='' inc_version_list_init='0' diff --git a/win32/config.vc b/win32/config.vc index 4972db8..04592e8 100644 --- a/win32/config.vc +++ b/win32/config.vc @@ -159,6 +159,7 @@ d_dosuid='undef' d_drand48_r='undef' d_drand48proto='undef' d_dup2='define' +d_duplocale='undef' d_eaccess='undef' d_endgrent='undef' d_endgrent_r='undef' @@ -791,6 +792,7 @@ i_values='undef' i_varargs='undef' i_varhdr='varargs.h' i_vfork='undef' +i_xlocale='undef' ignore_versioned_solibs='' inc_version_list='' inc_version_list_init='0' -- 2.5.4 (Apple Git-61)
Subject: 0003-it-seems-to-work-for-me.patch
From d167b16949bc7747fd47d8607a212088112f26ad Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Mon, 21 Mar 2016 14:28:47 +1100 Subject: it seems to work for me I expected to need duplocale(), but I guess we don't --- locale.c | 4 ++++ perl.h | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/locale.c b/locale.c index d000d93..7518897 100644 --- a/locale.c +++ b/locale.c @@ -42,6 +42,10 @@ # include <langinfo.h> #endif +#ifdef I_XLOCALE +# include <xlocale.h> +#endif + #include "reentr.h" #ifdef USE_LOCALE diff --git a/perl.h b/perl.h index 32d8419..abf4f37 100644 --- a/perl.h +++ b/perl.h @@ -6043,7 +6043,6 @@ typedef struct am_table_short AMTS; # define HAS_THREAD_SAFE_LOCALE #endif -#undef HAS_THREAD_SAFE_LOCALE /* Not seeming to work */ #else /* No locale usage */ # define IN_LOCALE_RUNTIME 0 -- 2.5.4 (Apple Git-61)
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 118b
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 516b
This should now be fixed by commit a0b5329765c5b5a7cbb69a2d628d4cea8f0323c1 I don't know how to add a test for this, so am leaving the ticket open for now, but not a 5.24 blocker. The script that fails is required to be run multiple times until a failure appears or you think enough tries have happened that it isn't going to fail. The solution committed has been tested for lengthy periods by both the OP and Tony Cook, so we know it works. I would appreciate hearing suggestions for a test. -- Karl Williamson
CC: perl5-porters [...] perl.org
To: Karl Williamson via RT <perlbug-followup [...] perl.org>
From: Dave Mitchell <davem [...] iabyn.com>
Subject: Re: [perl #127708] Coredump in call_sv under threads
Date: Fri, 17 Jun 2016 15:29:56 +0100
On Sat, Apr 09, 2016 at 01:15:39PM -0700, Karl Williamson via RT wrote: Show quoted text
> This should now be fixed by commit a0b5329765c5b5a7cbb69a2d628d4cea8f0323c1 > > I don't know how to add a test for this, so am leaving the ticket open > for now, but not a 5.24 blocker. The script that fails is required to > be run multiple times until a failure appears or you think enough tries > have happened that it isn't going to fail. The solution committed has > been tested for lengthy periods by both the OP and Tony Cook, so we know > it works. I would appreciate hearing suggestions for a test.
I'd suggest just adding a test that loops for a bit doing the sort of thing that used to cause a crash. There would be no expectation that the test would consistently fail, but that test would cause an occasional smoke failure if the bug crept back in - where anyone looking at the failing test number, would see a description that explains that this test is for a race condition or whatever. -- Little fly, thy summer's play my thoughtless hand has terminated with extreme prejudice. (with apologies to William Blake)
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 286b
Thanks for reporting this and helping me debug the solution. Commit 706055ce526ecd141030ea93bddf940bb955ae72 added a test for this, so am now closing. This bug was fixed in 5.24, but re-broken recently, and fixed finally by ffdde3068076349ae00c2cd96695f84a7ace347d -- Karl Williamson


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org