develooper Front page | perl.perl5.porters | Postings from November 2016

Re: Confused by eval behavior

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
November 14, 2016 15:50
Subject:
Re: Confused by eval behavior
Message ID:
20161114155013.GF24916@iabyn.com
On Mon, Aug 22, 2016 at 05:37:16PM +0100, Dave Mitchell wrote:
> On Mon, Jul 18, 2016 at 01:29:19PM -0300, Vincent Pit (VPIT) wrote:
> > Le 18/07/2016 à 12:37, Dave Mitchell a écrit :
> > > > The failing Variable::Magic test can be reduced to:
> > > > 
> > > >     use Variable::Magic qw<wizard cast>;
> > > > 
> > > >     my $wiz2 = wizard;
> > > >     my $wiz1 = wizard free => sub { warn "recasting\n"; &cast($_[0], $wiz2); die; };
> > > > 
> > > >     eval {
> > > >      my $v = do { my $val = 123; \$val };
> > > >      &cast($v, $wiz1);
> > > >     };
> > > > 
> > > > When $v goes out scope, the free magic method is called, which attached
> > > > new magic then dies. vmg_call_sv catches the error, then croaks.
> > > > The croak calls die_unwind, which now does FREETMPS, which triggers
> > > > another call to the free method, and so it recurses infinitely.
> > > > 
> > > > I haven't looked closely to see what is being freed by the FREETMPS and
> > > > why.
> > > 
> > > Vincent, will you have any opportunity to look at this?
> > > 
> > 
> > I looked at it but I have no definite answer about how to solve it.
> > 
> > The part of the code that goes into infinite recursion is there to ensure
> > that the Variable::Magic objects survive long enough that it is possible to
> > still manipulate magic during free callbacks (note that in particular magic
> > vtables have to be handled with extra care because they are shared across
> > threads). In order to work around the issue covered by this very "Confused
> > by eval behaviour" bug, the case where the free callback is invoked at the
> > end of an eval scope is treated specifically in vmg_svt_free_cleanup() (in
> > the branch where ud->in_eval is true). Then it uses different strategies
> > (trampoline op, destructor added to $@) to delay magic cleanup after eval is
> > done. Prior to your change, ud->in_eval was true in your example, but now
> > it's false. I guess that the heuristic used to see if the destruction
> > happens at the eval boundary has to be adjusted. I reckon that all this
> > stuff is pretty hacky and brittle, but it used to work well enough that
> > nobody complained.
> > 
> > As a data point, note that if you change the eval part of your test case by
> > 
> >   eval {
> >     my $v = 123;
> >     cast($v, $wiz1);
> >   };
> > 
> > then the infinite recursion disappears but the free magic is called twice.
> 
> Well, in an ideal world with a perfect perl and a perfect V::M,
> what is the  code at the top of this email supposed to do? In particular:
> 
> At the point where die is about to be called, is the magic var supposed
> to have both wizards still attached, or just wiz2? (Or with both attached,
> but $wiz1 in some way deactivated?).
> 
> And when exactly is the magic var supposed to be freed for the second
> time (after having been temporarily resurrected by the free magic
> creating a mortal reference to it)?
> 
> And is it intended that the free anon sub should called exactly once?

Hi Vincent,

are you able to answer my above questions? Until I know what the intended
behaviour is, I can't fix (or suggest how to fix) Variable::Magic, which
means I can't pull my fix into blead since it break V::M.

-- 
print+qq&$}$"$/$s$,$a$d$g$s$@$.$q$,$:$.$q$^$,$@$a$~$;$.$q$m&if+map{m,^\d{0\,},,${$::{$'}}=chr($"+=$&||1)}q&10m22,42}6:17a2~2.3@3;^2dg3q/s"&=~m*\d\*.*g

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About