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

Segfault/Null PMC access when CATCH interrupts binder and accesses an unbound variable in Rakudo #2828

Closed
p6rt opened this issue Jul 13, 2012 · 9 comments

Comments

@p6rt
Copy link

p6rt commented Jul 13, 2012

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

Searchable as RT114134$

@p6rt
Copy link
Author

p6rt commented Jul 13, 2012

From @masak

<masak> I've golfed the segfault from a few days ago.
<masak> it might be the strangest I've ever seen. but it's very
consistent. lots of components, though.
<masak> r​: use Test; class A {}; (-> &c, $m { A.new()(); CATCH {
default { ok 1, $m } } })(A, "")
<p6eval> rakudo 74e183​: OUTPUT«(signal SEGV)»
* masak submits rakudobug
<[Coke]> masak++
<masak> feel free to submit shorter versions to the channel if you
find any. I will add them to the RT ticket.
<gfldex> Segmentation fault (core dumped) # under cygwin
<moritz> r​: class A {}; (-> &c, $m { A.new()(); CATCH { default { say
$m } } } )(Mu.new, '')
22​:06 <+p6eval> rakudo 74e183​: OUTPUT«Null PMC access in
find_method('gist') [...]
<masak> that looks like a clue of some sort.
<masak> note that A is sent in as &c, and that was the original issue​:
a non-Callable was invoked.
<moritz> masak​: but shouldn't it fail to bind in the first place?
<moritz> I mean, A to &c
<masak> yes.
masak> and maybe it does, I dunno.
<moritz> r​: sub f(&c) { }; f(class { })
<p6eval> rakudo 74e183​: OUTPUT«Nominal type check failed for parameter
'&c'; expected Callable but got <anon> instead [...]
<masak> but the A.new()(); these is necessary.
<masak> which indicates the first line gets run.
<masak> r​: use Test; class A {}; (-> &c, $m { CATCH { default { ok 1,
$m } } })(A, "")
<p6eval> rakudo 74e183​: OUTPUT«(signal SEGV)»
<masak> I stand corrected. :)
<masak> that explains a lot. the CATCH catches binding errors.
<masak> and then the $m never gets bound, because the binder wasn't done!
<moritz> erm, what?
<masak> I couldn't have trolled Rakudo better if I had wanted to! :D
<moritz> a CATCH block catches... no way
<masak> yes way.
<masak> that's what happens.
<masak> it's so obvious now.
<moritz> I... hope that it's not supposed to catch those.
<masak> no, I don't think it is.
<moritz> ah, and that's why I got the null PMC access
<masak> but I can see why that falls out. I think binding is lexically
done inside of the callee.
<moritz> r​: sub f(&x) { CATCH { default { say "OH NOES" } } }; f 3
<p6eval> rakudo 74e183​: OUTPUT«===SORRY!===␤CHECK FAILED​:␤Calling 'f'
will never work with argument types (int) (line 1)␤ Expected​:
:(&x)␤»
<jnthn> Huh, I thought exception handlers weren't set up until after
the binding...
<moritz> r​: sub f(&x) { CATCH { default { say "OH NOES" } } }; f Mu.new
<p6eval> rakudo 74e183​: OUTPUT«OH NOES␤»
<moritz> that's a short version :-)
<moritz> masak++
<masak> now without the segv :)
<moritz> aye
<moritz> jnthn​: looking at the generate code, it seems it 1) does a
capture_lex 2) sets up the exception handler 3) calls
perl6_take_dipatcher 4) declares $_, $/, $! and call_sig and 5) calls
bind_signature
<jnthn> hah
<moritz> new $P1043, 'ExceptionHandler'
<moritz> set_label $P1043, control_1042
<moritz> $P1043."handle_types_except"(.CONTROL_ALL)
<moritz> I guess the binder does not generate a CONTROL exception
<jnthn> I...don't think they should be control exceptions.
<jnthn> Failing to bind is a real exception.
* moritz thinks so too
<jnthn> It's that the handler shouldn't be set up at that point.

@p6rt
Copy link
Author

p6rt commented Aug 5, 2012

From @jnthn

On Fri Jul 13 13​:19​:28 2012, masak wrote​:

<masak> I've golfed the segfault from a few days ago.
<masak> it might be the strangest I've ever seen. but it's very
consistent. lots of components, though.
<masak> r​: use Test; class A {}; (-> &c, $m { A.new()(); CATCH {
default { ok 1, $m } } })(A, "")
<p6eval> rakudo 74e183​: OUTPUT«(signal SEGV)»
* masak submits rakudobug
<[Coke]> masak++
<masak> feel free to submit shorter versions to the channel if you
find any. I will add them to the RT ticket.
<gfldex> Segmentation fault (core dumped) # under cygwin
<moritz> r​: class A {}; (-> &c, $m { A.new()(); CATCH { default { say
$m } } } )(Mu.new, '')
22​:06 <+p6eval> rakudo 74e183​: OUTPUT«Null PMC access in
find_method('gist') [...]
<masak> that looks like a clue of some sort.
<masak> note that A is sent in as &c, and that was the original issue​:
a non-Callable was invoked.
<moritz> masak​: but shouldn't it fail to bind in the first place?
<moritz> I mean, A to &c
<masak> yes.
masak> and maybe it does, I dunno.
<moritz> r​: sub f(&c) { }; f(class { })
<p6eval> rakudo 74e183​: OUTPUT«Nominal type check failed for parameter
'&c'; expected Callable but got <anon> instead [...]
<masak> but the A.new()(); these is necessary.
<masak> which indicates the first line gets run.
<masak> r​: use Test; class A {}; (-> &c, $m { CATCH { default { ok 1,
$m } } })(A, "")
<p6eval> rakudo 74e183​: OUTPUT«(signal SEGV)»
<masak> I stand corrected. :)
<masak> that explains a lot. the CATCH catches binding errors.
<masak> and then the $m never gets bound, because the binder wasn't done!
<moritz> erm, what?
<masak> I couldn't have trolled Rakudo better if I had wanted to! :D
<moritz> a CATCH block catches... no way
<masak> yes way.
<masak> that's what happens.
<masak> it's so obvious now.
<moritz> I... hope that it's not supposed to catch those.
<masak> no, I don't think it is.
<moritz> ah, and that's why I got the null PMC access
<masak> but I can see why that falls out. I think binding is lexically
done inside of the callee.
<moritz> r​: sub f(&x) { CATCH { default { say "OH NOES" } } }; f 3
<p6eval> rakudo 74e183​: OUTPUT«===SORRY!===␤CHECK FAILED​:␤Calling 'f'
will never work with argument types (int) (line 1)␤ Expected​:
:(&x)␤»
<jnthn> Huh, I thought exception handlers weren't set up until after
the binding...
<moritz> r​: sub f(&x) { CATCH { default { say "OH NOES" } } }; f Mu.new
<p6eval> rakudo 74e183​: OUTPUT«OH NOES␤»
<moritz> that's a short version :-)
<moritz> masak++
<masak> now without the segv :)
<moritz> aye
<moritz> jnthn​: looking at the generate code, it seems it 1) does a
capture_lex 2) sets up the exception handler 3) calls
perl6_take_dipatcher 4) declares $_, $/, $! and call_sig and 5) calls
bind_signature
<jnthn> hah
<moritz> new $P1043, 'ExceptionHandler'
<moritz> set_label $P1043, control_1042
<moritz> $P1043."handle_types_except"(.CONTROL_ALL)
<moritz> I guess the binder does not generate a CONTROL exception
<jnthn> I...don't think they should be control exceptions.
<jnthn> Failing to bind is a real exception.
* moritz thinks so too
<jnthn> It's that the handler shouldn't be set up at that point.

These were fixed as part of the QAST changes​:

sub f(&x) { CATCH { default { say "OH NOES" } } }; f Mu.new
Nominal type check failed for parameter '&x'; expected Callable but got
Mu instead
use Test; class A {}; (-> &c, $m { A.new()(); CATCH { default { ok 1,
$m } } } )(A, "")
Nominal type check failed for parameter '&c'; expected Callable but got
A instead

Tagging testneeded.

/jnthn

@p6rt
Copy link
Author

p6rt commented Aug 5, 2012

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

@p6rt
Copy link
Author

p6rt commented Jul 13, 2014

From @coke

S06-routine-modifiers/lvalue-subroutines.t

had this​:

#?rakudo skip 'hangs, probably due to [RT #​114134]'
dies_ok {checklastval("octopus") = 10 }, 'checklastval STORE can die';

Which is now unskipped and passing.

1 similar comment
@p6rt
Copy link
Author

p6rt commented Jul 13, 2014

From @coke

S06-routine-modifiers/lvalue-subroutines.t

had this​:

#?rakudo skip 'hangs, probably due to [RT #​114134]'
dies_ok {checklastval("octopus") = 10 }, 'checklastval STORE can die';

Which is now unskipped and passing.

@p6rt
Copy link
Author

p6rt commented Jul 17, 2014

From @coke

Recent parrot failure from S32-exceptions/misc.t --

  1..2
  ok 1 - 'my class A {}; (-> &c, $m { A.new()(); CATCH { default {
$m } } } )(A, "")' died
  not ok 2 - right exception type (X​::TypeCheck​::Binding)
  # Got​: (X​::AdHoc)
  # Expected​: (X​::TypeCheck​::Binding)
  # Exception message​: Nominal type check failed for parameter '&c';
expected Callable but got A instead
  # Looks like you failed 1 tests of 2
not ok 227 - did we throws_like X​::TypeCheck​::Binding?

--
Will "Coke" Coleda

@p6rt
Copy link
Author

p6rt commented Jul 17, 2014

From @FROGGS

Fixed for parrot​: rakudo/rakudo@2647500744
It still needs to be done for JVM.

@p6rt
Copy link
Author

p6rt commented Jul 17, 2014

From @FROGGS

Also done for jvm now​: rakudo/rakudo@1b01e7aff7

@p6rt
Copy link
Author

p6rt commented Jul 17, 2014

@FROGGS - 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