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

Non-deterministic segfaults in parallel code #5020

Open
p6rt opened this issue Jan 7, 2016 · 7 comments
Open

Non-deterministic segfaults in parallel code #5020

p6rt opened this issue Jan 7, 2016 · 7 comments

Comments

@p6rt
Copy link

@p6rt p6rt commented Jan 7, 2016

Migrated from rt.perl.org#127208 (status was 'open')

Searchable as RT127208$

@p6rt
Copy link
Author

@p6rt p6rt commented Jan 7, 2016

From @Ovid

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 developmenthttp://www.allaroundtheworld.fr/. 
Buy my book! - http://bit.ly/beginning_perl

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented Jan 8, 2016

From @nwc10

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​:

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

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented Jan 8, 2016

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

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented May 11, 2016

From @smls

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?

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented May 11, 2016

From @smls

[13​:42] <moritz> a test would be appreciated, yes

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented Jul 7, 2016

From @zoffixznet

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

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented Sep 10, 2016

From @zoffixznet

Fudged tests added in Raku/roast@02d6988

Still segfaults about once in 10 runs on 2016.08.1-145-g87f772e

Loading

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

Successfully merging a pull request may close this issue.

None yet
1 participant