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

Re: Confused by eval behavior

Thread Previous | Thread Next
November 14, 2016 19:46
Re: Confused by eval behavior
Message ID:

Le 14/11/2016 à 13:50, Dave Mitchell a écrit :
 > 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.

Hi Dave,

Sorry for the delay, I've been quite busy and completely forgot about 
your message.

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

 From the Perl side, this example should behave as closely as possible 
as a pure Perl example where you replace wiz1 with a destructor.

(And now that I write this, I realize that in the pure Perl case the 
exception is not propagated outside eval, while V::M resets $@ outside 
to the value of the inner exception. You may consider this as a bug in 
V::M if it helps fixing the issue).

>> 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?).

Both, with or without wiz1 deactivated. To ensure thread safety, V::M 
need to handle the vtable manually, so the magic callback needs to see 
the magic struct.

>> 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)?

This is kind of tricky, but I guess when the C free magic callback 
returns, just like what would happen when the SV isn't resurrected.

>> And is it intended that the free anon sub should called exactly once?



Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About