Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coredump in call_sv under threads #15229

Closed
p5pRT opened this issue Mar 14, 2016 · 16 comments
Closed

Coredump in call_sv under threads #15229

p5pRT opened this issue Mar 14, 2016 · 16 comments

Comments

@p5pRT
Copy link

p5pRT commented Mar 14, 2016

Migrated from rt.perl.org#127708 (status was 'resolved')

Searchable as RT127708$

@p5pRT
Copy link
Author

p5pRT commented Mar 14, 2016

From @dur-randir

Created by @dur-randir

%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 */

Perl Info

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

@p5pRT
Copy link
Author

p5pRT commented Mar 14, 2016

From @tonycoz

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

@p5pRT
Copy link
Author

p5pRT commented Mar 14, 2016

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Mar 19, 2016

From @khwilliamson

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.
--
Karl Williamson

@p5pRT
Copy link
Author

p5pRT commented Mar 20, 2016

From @khwilliamson

On Fri Mar 18 22​:03​:37 2016, khw wrote​:

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

@p5pRT
Copy link
Author

p5pRT commented Mar 20, 2016

From @tonycoz

On Sat Mar 19 22​:20​:16 2016, khw wrote​:

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

@p5pRT
Copy link
Author

p5pRT commented Mar 21, 2016

From @tonycoz

On Sat Mar 19 22​:20​:16 2016, khw wrote​:

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

@p5pRT
Copy link
Author

p5pRT commented Mar 21, 2016

From @tonycoz

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)

@p5pRT
Copy link
Author

p5pRT commented Mar 21, 2016

From @tonycoz

On Fri Mar 18 22​:03​:37 2016, khw wrote​:

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

@p5pRT
Copy link
Author

p5pRT commented Mar 21, 2016

From @tonycoz

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)

@p5pRT
Copy link
Author

p5pRT commented Mar 21, 2016

From @tonycoz

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)

@p5pRT
Copy link
Author

p5pRT commented Mar 29, 2016

From @tonycoz

There's further discussion of this issue at​:

http​://www.nntp.perl.org/group/perl.perl5.porters/2016/03/msg235289.html

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2016

From @khwilliamson

This should now be fixed by commit a0b5329

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

@p5pRT
Copy link
Author

p5pRT commented Jun 17, 2016

From @iabyn

On Sat, Apr 09, 2016 at 01​:15​:39PM -0700, Karl Williamson via RT wrote​:

This should now be fixed by commit a0b5329

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)

@p5pRT
Copy link
Author

p5pRT commented Aug 10, 2016

From @khwilliamson

Thanks for reporting this and helping me debug the solution.

Commit 706055c added a test for this, so am now closing. This bug was fixed in 5.24, but re-broken recently, and fixed finally by ffdde30
--
Karl Williamson

@p5pRT
Copy link
Author

p5pRT commented Aug 10, 2016

@khwilliamson - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant