Skip Menu |
Report information
Id: 127208
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: curtis_ovid_poe [at] yahoo.com
Cc:
AdminCc:

Severity: (no value)
Tag: testcommitted
Platform: (no value)
Patch Status: (no value)
VM: (no value)



From: Ovid <curtis_ovid_poe [...] yahoo.com>
To: Rakudobug <rakudobug [...] perl.org>
Date: Thu, 7 Jan 2016 23:29:28 +0000 (UTC)
Subject: Non-deterministic segfaults in parallel code
Download (untitled)
multipart/alternative 2.5k

Message body not shown because it is not plain text.

Download (untitled) / with headers
text/plain 568b
This code sometimes segfaults, sometimes tells me it's a malloc error:

    my @primes = grep { .is-prime }, 1 .. *; my @p = gather for 4000, 5, 100, 2000 -> $n { take start { @primes[$n] }; }; .say for await @p;
 
Yes, I know the code is stupid (since one promise might be trying to access data that's not yet been calculated), but I would hope for something other than random error messages :)

Best,
Ovid
-- 
IT consulting, training, specializing in Perl, databases, and agile development
Subject: Re: [perl #127208] Non-deterministic segfaults in parallel code
To: perl6-compiler [...] perl.org
Date: Fri, 8 Jan 2016 20:24:15 +0000
From: Nicholas Clark <nick [...] ccl4.org>
Download (untitled) / with headers
text/plain 4.9k
Something between your mail client and my mail client hates us: On Thu, Jan 07, 2016 at 03:29:49PM -0800, curtis_ovid_poe@yahoo.com wrote: Show quoted text
> This code sometimes segfaults, sometimes tells me it's a malloc error: >     my @primes = grep { .is-prime }, 1 .. *; my @p = gather for 4000, 5, 100, 2000 -> $n { take start { @primes[$n] }; }; .say for await @p; Yes, I know the code is stupid (since one promise might be trying to access data that's not yet been calculated), but I would hope for something other than random error messages :)
Nice find. ASAN says this, and memory corruption combined with concurrency would explain the non-deterministic results you're reporting: $ ./perl6-m -Ilib -e 'my @primes = grep { .is-prime }, 1 .. *; my @p = gather for 4000, 5, 100, 2000 -> $n { take start { @primes[$n] }; }; .say for await @p;' ================================================================= ==16988==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x619000168e80 at pc 0x7feef89ff829 bp 0x7feef24dbff0 sp 0x7feef24dbfe8 READ of size 8 at 0x619000168e80 thread T1 #0 0x7feef89ff828 in at_pos src/6model/reprs/MVMArray.c:133 #1 0x7feeedba94fd (+0x74fd) 0x619000168e80 is located 0 bytes to the right of 1024-byte region [0x619000168a80,0x619000168e80) freed by thread T3 here: #0 0x7feef94ae8e6 in __interceptor_realloc ../../.././libsanitizer/asan/asan_malloc_linux.cc:93 #1 0x7feef89fe3c6 in MVM_realloc src/core/alloc.h:20 #2 0x7feef8a011a9 in set_size_internal src/6model/reprs/MVMArray.c:334 #3 0x7feef8a020b9 in push src/6model/reprs/MVMArray.c:437 #4 0x7feef89ef36b in MVM_repr_push_o src/6model/reprconv.c:339 #5 0x7feeedb8e0cc (+0x40cc) #6 0x7feef8b2f290 in MVM_jit_enter_code src/jit/compile.c:125 #7 0x7feef89211a2 in MVM_interp_run src/core/interp.c:5402 #8 0x7feef8951ce7 in start_thread src/core/threads.c:77 #9 0x7feef8bfa94d in uv__thread_start 3rdparty/libuv/src/unix/thread.c:49 #10 0x7feef7cbc9d0 in start_thread (/lib64/libpthread.so.0+0x79d0) previously allocated by thread T1 here: #0 0x7feef94ae8e6 in __interceptor_realloc ../../.././libsanitizer/asan/asan_malloc_linux.cc:93 #1 0x7feef89fe3c6 in MVM_realloc src/core/alloc.h:20 #2 0x7feef8a011a9 in set_size_internal src/6model/reprs/MVMArray.c:334 #3 0x7feef8a020b9 in push src/6model/reprs/MVMArray.c:437 #4 0x7feef88d36ba in MVM_interp_run src/core/interp.c:2207 #5 0x7feef8951ce7 in start_thread src/core/threads.c:77 #6 0x7feef8bfa94d in uv__thread_start 3rdparty/libuv/src/unix/thread.c:49 #7 0x7feef7cbc9d0 in start_thread (/lib64/libpthread.so.0+0x79d0) Thread T1 created by T0 here: #0 0x7feef947d6ea in __interceptor_pthread_create ../../.././libsanitizer/asan/asan_interceptors.cc:183 #1 0x7feef8bfaa52 in uv_thread_create 3rdparty/libuv/src/unix/thread.c:66 #2 0x7feef895203f in MVM_thread_run src/core/threads.c:126 #3 0x7feef88fbd2b in MVM_interp_run src/core/interp.c:3933 #4 0x7feef8b942dd in MVM_vm_run_file src/moar.c:304 #5 0x401a4f in main src/main.c:191 #6 0x7feef80f8d5c in __libc_start_main (/lib64/libc.so.6+0x1ed5c) Thread T3 created by T0 here: #0 0x7feef947d6ea in __interceptor_pthread_create ../../.././libsanitizer/asan/asan_interceptors.cc:183 #1 0x7feef8bfaa52 in uv_thread_create 3rdparty/libuv/src/unix/thread.c:66 #2 0x7feef895203f in MVM_thread_run src/core/threads.c:126 #3 0x7feef88fbd2b in MVM_interp_run src/core/interp.c:3933 #4 0x7feef8b942dd in MVM_vm_run_file src/moar.c:304 #5 0x401a4f in main src/main.c:191 #6 0x7feef80f8d5c in __libc_start_main (/lib64/libc.so.6+0x1ed5c) SUMMARY: AddressSanitizer: heap-buffer-overflow src/6model/reprs/MVMArray.c:133 at_pos Shadow bytes around the buggy address: 0x0c3280025180: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c3280025190: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c32800251a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c32800251b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c32800251c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd =>0x0c32800251d0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c32800251e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c32800251f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c3280025200: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c3280025210: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c3280025220: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Contiguous container OOB:fc ASan internal: fe ==16988==ABORTING Nicholas Clark
RT-Send-CC: rakudobug [...] perl.org
Download (untitled) / with headers
text/plain 771b
It doesn't segfault for me on... Rakudo version 2016.04-155-gdc7346b built on MoarVM version 2016.04 implementing Perl 6.c. ...and instead prints this error: No such method 'is-prime' for invocant of type 'Any' (When removing the `start` and `await` to disable the parallelism, it works fine.) However, I don't think that's a bug. Arrays are only partially thread-safe in Perl 6, by design. As jnthn confirmed on IRC <http://irclog.perlgeek.de/perl6/2016-04-08#i_12307048>, it is only safe for multiple threads to read from the same array if they are NOT reading an unevaluated lazy part of it. But that's exactly what the threads are doing here. Thus, I believe this ticket can be closed. Do we need a Roast test for the "no longer segfaults" aspect?
[13:42] <moritz> a test would be appreciated, yes
Download (untitled) / with headers
text/plain 1.8k
I'm still getting segfaults after several runs on This is Rakudo version 2016.05-348-g41b685e built on MoarVM version 2016.06-9-g8fc21d5 zoffix@VirtualBox:~/CPANPRC/rakudo$ ./perl6-m -Ilib -e 'my @primes = grep { .is-prime }, 1 .. *; my @p = gather for 4000, 5, 100, 2000 -> $n { take start { @primes[$n] }; }; .say for await @p;' No such method 'is-prime' for invocant of type 'Mu' in block <unit> at -e line 1 zoffix@VirtualBox:~/CPANPRC/rakudo$ ./perl6-m -Ilib -e 'my @primes = grep { .is-prime }, 1 .. *; my @p = gather for 4000, 5, 100, 2000 -> $n { take start { @primes[$n] }; }; .say for await @p;' No such method 'is-prime' for invocant of type 'Mu' in block <unit> at -e line 1 zoffix@VirtualBox:~/CPANPRC/rakudo$ ./perl6-m -Ilib -e 'my @primes = grep { .is-prime }, 1 .. *; my @p = gather for 4000, 5, 100, 2000 -> $n { take start { @primes[$n] }; }; .say for await @p;' No such method 'is-prime' for invocant of type 'Mu' in block <unit> at -e line 1 zoffix@VirtualBox:~/CPANPRC/rakudo$ ./perl6-m -Ilib -e 'my @primes = grep { .is-prime }, 1 .. *; my @p = gather for 4000, 5, 100, 2000 -> $n { take start { @primes[$n] }; }; .say for await @p;' No such method 'is-prime' for invocant of type 'Mu' in block <unit> at -e line 1 zoffix@VirtualBox:~/CPANPRC/rakudo$ ./perl6-m -Ilib -e 'my @primes = grep { .is-prime }, 1 .. *; my @p = gather for 4000, 5, 100, 2000 -> $n { take start { @primes[$n] }; }; .say for await @p;' No such method 'is-prime' for invocant of type 'Mu' in block <unit> at -e line 1 zoffix@VirtualBox:~/CPANPRC/rakudo$ ./perl6-m -Ilib -e 'my @primes = grep { .is-prime }, 1 .. *; my @p = gather for 4000, 5, 100, 2000 -> $n { take start { @primes[$n] }; }; .say for await @p;' *** Error in `/home/zoffix/CPANPRC/rakudo/install/bin/moar': double free or corruption (fasttop): 0x00007f000800fa20 *** Aborted
Subject: [CONC][SEGV] Non-deterministic segfaults in parallel code
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 135b
Fudged tests added in https://github.com/perl6/roast/commit/02d698835e Still segfaults about once in 10 runs on 2016.08.1-145-g87f772e


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