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

Weird 'Reading from filehandle failed: Bad file descriptor' Error Affected by Comments in Code #6394

Closed
p6rt opened this issue Jul 15, 2017 · 7 comments

Comments

@p6rt
Copy link

p6rt commented Jul 15, 2017

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

Searchable as RT131755$

@p6rt
Copy link
Author

p6rt commented Jul 15, 2017

From @zoffixznet

The original failure was in t/spec/S32-io/open.t test that I golfed down to the following​:

-----------------------8<---------------------------------
$*IN = IO​::Handle.new​: :path('-'.IO);
$*IN.open;
$*OUT.open​: :w;

my $w = '-'.IO.open​: :w;
my $r = '-'.IO.open;
$*IN.slurp(​:close); #
$w.put​: 'meow w';
$*OUT.put​: 'x';
-----------------------8<---------------------------------

Save that code to file named open.t and then run it like this​:

  $ echo "x" | ./perl6 --ll-exception open.t

And it'll die with 'Reading from filehandle failed​: Bad file descriptor'

This is on Rakudo version 2017.06-252-g83502cc built on MoarVM version 2017.06-91-g146c8fc.

Most notably, removing `--ll-exception` parameter or even removing the `#` comment on line 6 causes the bug to disappear.

@p6rt
Copy link
Author

p6rt commented Jul 15, 2017

From @zoffixznet

I fudged the flopping test for this ticket in Raku/roast@4748a283e1

@p6rt
Copy link
Author

p6rt commented Jul 17, 2017

From @jnthn

On Sat, 15 Jul 2017 12​:07​:19 -0700, cpan@​zoffix.com wrote​:

The original failure was in t/spec/S32-io/open.t test that I golfed
down to the following​:

-----------------------8<---------------------------------
$*IN = IO​::Handle.new​: :path('-'.IO);
$*IN.open;
$*OUT.open​: :w;

my $w = '-'.IO.open​: :w;
my $r = '-'.IO.open;
$*IN.slurp(​:close); #
$w.put​: 'meow w';
$*OUT.put​: 'x';
-----------------------8<---------------------------------

Save that code to file named open.t and then run it like this​:

$ echo "x" | ./perl6 --ll-exception open.t

And it'll die with 'Reading from filehandle failed​: Bad file
descriptor'

This is on Rakudo version 2017.06-252-g83502cc built on MoarVM version
2017.06-91-g146c8fc.

Most notably, removing `--ll-exception` parameter or even removing the
`#` comment on line 6 causes the bug to disappear.

I investigated this a bit, wondering if the flakiness was a MoarVM bug. It turns out that no, MoarVM is doing precisely what is asked of it by Rakudo. :-)

The code in question makes the original handle bound in $*IN unreachable. At some point GC runs and collects it. Except it doesn't right away, because IO​::Handle has a DESTROY method. That DESTROY method runs and closes the underlying VM handle. However, because the standard handles don't open a new handle, but rather obtain the VM-level handles for stdin/stderr/stdout, we can end up with two IO​::Handle instances pointing to the same underlying handle. The DESTROY closes it, busting the other handle that holds it.

The various tweaks that hide the issue are simply moving when GC takes place, meaning it's too early or too late to collect the object and run DESTROY at the time that causes the breakage.

/jnthn

@p6rt
Copy link
Author

p6rt commented Jul 17, 2017

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

@p6rt
Copy link
Author

p6rt commented Jul 17, 2017

From @zoffixznet

On Mon, 17 Jul 2017 02​:19​:39 -0700, jnthn@​jnthn.net wrote​:

On Sat, 15 Jul 2017 12​:07​:19 -0700, cpan@​zoffix.com wrote​:

The original failure was in t/spec/S32-io/open.t test that I golfed
down to the following​:

-----------------------8<---------------------------------
$*IN = IO​::Handle.new​: :path('-'.IO);
$*IN.open;
$*OUT.open​: :w;

my $w = '-'.IO.open​: :w;
my $r = '-'.IO.open;
$*IN.slurp(​:close); #
$w.put​: 'meow w';
$*OUT.put​: 'x';
-----------------------8<---------------------------------

Save that code to file named open.t and then run it like this​:

$ echo "x" | ./perl6 --ll-exception open.t

And it'll die with 'Reading from filehandle failed​: Bad file
descriptor'

This is on Rakudo version 2017.06-252-g83502cc built on MoarVM
version
2017.06-91-g146c8fc.

Most notably, removing `--ll-exception` parameter or even removing
the
`#` comment on line 6 causes the bug to disappear.

I investigated this a bit, wondering if the flakiness was a MoarVM
bug. It turns out that no, MoarVM is doing precisely what is asked of
it by Rakudo. :-)

The code in question makes the original handle bound in $*IN
unreachable. At some point GC runs and collects it. Except it doesn't
right away, because IO​::Handle has a DESTROY method. That DESTROY
method runs and closes the underlying VM handle. However, because the
standard handles don't open a new handle, but rather obtain the VM-
level handles for stdin/stderr/stdout, we can end up with two
IO​::Handle instances pointing to the same underlying handle. The
DESTROY closes it, busting the other handle that holds it.

The various tweaks that hide the issue are simply moving when GC takes
place, meaning it's too early or too late to collect the object and
run DESTROY at the time that causes the breakage.

/jnthn

Thanks.

Fix​: rakudo/rakudo@0e578c4fea72e36
Test​: Raku/roast@f739f03ff439e75a7

@p6rt
Copy link
Author

p6rt commented Jul 17, 2017

From @zoffixznet

More explicit tests​: Raku/roast@9a85e42a6e

@p6rt p6rt closed this as completed Jul 17, 2017
@p6rt
Copy link
Author

p6rt commented Jul 17, 2017

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

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

No branches or pull requests

1 participant