Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Perl: porters

[perl #60374] Safe.pm sort {} bug with -Dusethreads

 

 

First page Previous page 1 2 Next page Last page  View All Perl porters RSS feed   Index | Next | Previous | View Threaded


ben at morrow

Nov 7, 2009, 10:44 AM

Post #26 of 30 (48 views)
Permalink
Re: [perl #60374] Safe.pm sort {} bug with -Dusethreads [In reply to]

Quoth badalex[at]gmail.com (Alex Hunsaker):
> my $evalsub = lexless_anon_sub($root,$strict, $expr);
> - return Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub);
> + my $ret = Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub);
> +
> + if ($Config{usethreads} && ref $ret eq 'CODE') {

This should use Scalar::Util::reftype, in case the coderef is blessed.

Ben


Tim.Bunce at pobox

Nov 8, 2009, 3:36 PM

Post #27 of 30 (47 views)
Permalink
Re: [perl #60374] Safe.pm sort {} bug with -Dusethreads [In reply to]

On Fri, Nov 06, 2009 at 02:30:47PM -0700, Alex Hunsaker wrote:
>
> Um the last patch I posted should...
> http://rt.perl.org/rt3/Ticket/Display.html?id=60374#txn-612980. And
> while I found it quite ugly and im sure there are better ways to fix
> this... (namely we could fix Opcode::_safe_call_sv to do something
> similar, or fix it as diagnosed in
> http://rt.perl.org/rt3/Ticket/Display.html?id=60374#txn-491794)
> I was more or less looking for some kind of validation as to the
> approach :).

I don't think the "detect if we are returning an anon sub" approach will
work because the reval() may have compiled some named subs that will be
invoked later. That's the case with PostgrSQL's embedded plperl, for example.

http://rt.perl.org/rt3/Public/Bug/Display.html?id=60374#txn-491794 says
"pp_sort uses CopSTASH(PL_curcop) to get the package stash (symbol
table) in order to locate the $a and $b variables in it."

While pp_sort does call CopSTASH(PL_curcop) directly, all it does with
it is store the value in PL_sortstash which, as far as I can tell, isn't
used or documented anywhere at all. (It could possibly be deleted.)

The code to lookup the $a and $b uses:
PL_firstgv = gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV);
PL_secondgv = gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV);
and it's Perl_gv_fetchpvn_flags that ends up calling CopSTASH(PL_curcop).

If there was a way to get the stash pointer (not name) that was in
effect at the time the code was compiled we could use that to lookup $a
and $b.

There are stash pointers, er, stashed in lots of places.
One approach might be CvSTASH(find_runcv(...))

Tim.


badalex at gmail

Nov 8, 2009, 4:56 PM

Post #28 of 30 (46 views)
Permalink
Re: [perl #60374] Safe.pm sort {} bug with -Dusethreads [In reply to]

On Sun, Nov 8, 2009 at 16:36, Tim Bunce <Tim.Bunce[at]pobox.com> wrote:
> I don't think the "detect if we are returning an anon sub" approach will
> work because the reval() may have compiled some named subs that will be
> invoked later. That's the case with PostgrSQL's embedded plperl, for example.

BTW I just tested and it does fix PostgreSQL

create or replace function trustedsort()
returns int
as $$
my @arr = (5, 4, 3, 2, 1);
my @sorted = sort { elog(NOTICE, "$a $b"); $a <=> $b } @arr;
return 1;
$$
language 'plperl';


unpatched Safe.pm:
select trustedsort();
NOTICE:
CONTEXT: PL/Perl function "trustedsort"
NOTICE:
CONTEXT: PL/Perl function "trustedsort"
NOTICE:
CONTEXT: PL/Perl function "trustedsort"
NOTICE:
CONTEXT: PL/Perl function "trustedsort"
NOTICE:
CONTEXT: PL/Perl function "trustedsort"
NOTICE:
CONTEXT: PL/Perl function "trustedsort"
NOTICE:
CONTEXT: PL/Perl function "trustedsort"
NOTICE:
CONTEXT: PL/Perl function "trustedsort"

trustedsort
-------------
1
(1 row)


w patched:
select trustedsort();
NOTICE: 5 4
CONTEXT: PL/Perl function "trustedsort"
NOTICE: 3 2
CONTEXT: PL/Perl function "trustedsort"
NOTICE: 4 2
CONTEXT: PL/Perl function "trustedsort"
NOTICE: 4 3
CONTEXT: PL/Perl function "trustedsort"
NOTICE: 2 1
CONTEXT: PL/Perl function "trustedsort"
trustedsort
-------------
1


nick at ccl4

Nov 10, 2009, 6:56 AM

Post #29 of 30 (39 views)
Permalink
Re: [perl #60374] Safe.pm sort {} bug with -Dusethreads [In reply to]

On Sun, Nov 08, 2009 at 11:36:46PM +0000, Tim Bunce wrote:
> On Fri, Nov 06, 2009 at 02:30:47PM -0700, Alex Hunsaker wrote:
> >
> > Um the last patch I posted should...
> > http://rt.perl.org/rt3/Ticket/Display.html?id=60374#txn-612980. And
> > while I found it quite ugly and im sure there are better ways to fix
> > this... (namely we could fix Opcode::_safe_call_sv to do something
> > similar, or fix it as diagnosed in
> > http://rt.perl.org/rt3/Ticket/Display.html?id=60374#txn-491794)
> > I was more or less looking for some kind of validation as to the
> > approach :).
>
> I don't think the "detect if we are returning an anon sub" approach will
> work because the reval() may have compiled some named subs that will be
> invoked later. That's the case with PostgrSQL's embedded plperl, for example.
>
> http://rt.perl.org/rt3/Public/Bug/Display.html?id=60374#txn-491794 says
> "pp_sort uses CopSTASH(PL_curcop) to get the package stash (symbol
> table) in order to locate the $a and $b variables in it."
>
> While pp_sort does call CopSTASH(PL_curcop) directly, all it does with
> it is store the value in PL_sortstash which, as far as I can tell, isn't
> used or documented anywhere at all. (It could possibly be deleted.)
>
> The code to lookup the $a and $b uses:
> PL_firstgv = gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV);
> PL_secondgv = gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV);
> and it's Perl_gv_fetchpvn_flags that ends up calling CopSTASH(PL_curcop).
>
> If there was a way to get the stash pointer (not name) that was in
> effect at the time the code was compiled we could use that to lookup $a
> and $b.

The logical way to do this would be to indirect via an entry in the
subroutine's pad, as the reference would be correctly translated by the
ithreads clone code. This probably isn't *trivial* to implement, as a
subroutine can contain code compiled in more than one package, but I think*
it would be viable at compile time to loop up/store if not there yet, the
stash pointer, under the stash's name.

> There are stash pointers, er, stashed in lots of places.
> One approach might be CvSTASH(find_runcv(...))

I think that that doesn't cope with

package foo;
sub bar {
# here package is foo
package baz;
# here package is baz
}

Nicholas Clark

* I think. I don't know this stuff well.


Tim.Bunce at pobox

Nov 10, 2009, 8:16 AM

Post #30 of 30 (39 views)
Permalink
Re: [perl #60374] Safe.pm sort {} bug with -Dusethreads [In reply to]

On Tue, Nov 10, 2009 at 02:56:36PM +0000, Nicholas Clark wrote:
> >
> > http://rt.perl.org/rt3/Public/Bug/Display.html?id=60374#txn-491794 says
> > "pp_sort uses CopSTASH(PL_curcop) to get the package stash (symbol
> > table) in order to locate the $a and $b variables in it."
> >
> > While pp_sort does call CopSTASH(PL_curcop) directly, all it does with
> > it is store the value in PL_sortstash which, as far as I can tell, isn't
> > used or documented anywhere at all. (It could possibly be deleted.)
> >
> > The code to lookup the $a and $b uses:
> > PL_firstgv = gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV);
> > PL_secondgv = gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV);
> > and it's Perl_gv_fetchpvn_flags that ends up calling CopSTASH(PL_curcop).
> >
> > If there was a way to get the stash pointer (not name) that was in
> > effect at the time the code was compiled we could use that to lookup $a
> > and $b.
>
> The logical way to do this would be to indirect via an entry in the
> subroutine's pad, as the reference would be correctly translated by the
> ithreads clone code. This probably isn't *trivial* to implement, as a
> subroutine can contain code compiled in more than one package, but I think*
> it would be viable at compile time to loop up/store if not there yet, the
> stash pointer, under the stash's name.
>
> > There are stash pointers, er, stashed in lots of places.
> > One approach might be CvSTASH(find_runcv(...))
>
> I think that that doesn't cope with
>
> package foo;
> sub bar {
> # here package is foo
> package baz;
> # here package is baz
> }

I couldn't get it to work even without that (but trying to follow the
inside-safe vs outside-safe and compile-time vs run-time intricacies
made my rusty old head spin, so I could have done something silly).

Alex's approach, of arranging to execute the closure 'inside' the
compartment, seems like a good idea from a 'safety' point of view
anyway. The fact it works around the bug is a bonus.

On the other hand, the fact it costs two extra sub calls is unfortunate.
I tried to look for a way to the PL_defstash switch into pp_entersub but
couldn't see a viable approach.

> * I think. I don't know this stuff well.

Me neither. It's been many years since I helped develop Opcode and Safe.
(I recall refering to Safe as a "failed experiment" more than once.)

Tim.

First page Previous page 1 2 Next page Last page  View All Perl porters RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.