Skip site navigation (1) Skip section navigation (2)

Re: plperl & sort

From: Andrew Gierth <andrew(at)tao11(dot)riddles(dot)org(dot)uk>
To: "Alex Hunsaker" <badalex(at)gmail(dot)com>
Cc: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: plperl & sort
Date: 2008-11-06 16:00:14
Message-ID: 8763n0hmk1.fsf@news-spur.riddles.org.uk (view raw or flat)
Thread:
Lists: pgsql-bugs
>>>>> "Alex" == Alex Hunsaker <badalex(at)gmail(dot)com> writes:

 >> Then explain why the problem goes away when you build perl with
 >> threading turned off.

 Alex> Hrm yep i built one without threads problem disappears... Guess
 Alex> Ive just been out to lunch :)

If it helps any, I've tracked down in the perl guts exactly why this
happens:

cop.h:

struct cop {
    BASEOP
    char *	cop_label;	/* label for this construct */
#ifdef USE_ITHREADS
    char *	cop_stashpv;	/* package line was compiled in */
    char *	cop_file;	/* file name the following line # is from */
#else
    HV *	cop_stash;	/* package line was compiled in */
    GV *	cop_filegv;	/* file the following line # is from */
#endif
    U32		cop_seq;	/* parse sequence number */
    I32		cop_arybase;	/* array base this line was compiled with */
    line_t      cop_line;       /* line # of this command */
    SV *	cop_warnings;	/* lexical warnings bitmask */
    SV *	cop_io;		/* lexical IO defaults */
};

A COP in perl is a control operation, basically a compiled statement,
and the pointer to the current COP is used to determine all the
lexical state, including the current package. pp_sort uses
CopSTASH(PL_curcop) to get the package stash (symbol table) in order
to locate the $a and $b variables in it.

Notice, though, that without ithreads, the COP points directly to the
stash, but with ithreads, it points instead to the _name_ of the stash
(e.g. "main"). The problem arises because with Safe in use, the
package created by Safe to use as a container _thinks_ that its name
is "main" even though it's not, so the COPs compiled inside it point
to the name "main" rather than to the real name of the container.

So with ithreads enabled, pp_sort looks up the package stash by name,
gets the "main" package rather than the safe container, and creates
$main::a and $main::b to store the comparison values in. But the
compiled comparison block has its own references to the variables
which refers to the correct stash, so it all goes Horribly Wrong at
that point.

So there are three factors involved:

1) the change in layout of COP with ithreads enabled
2) the fact that Safe changes the internally-seen name of a package
3) any operation that relies on CopSTASH(PL_curcop) (I can only find a
   few: sort, reset, and bless) will then behave incorrectly

However, I have no idea why Perl has this difference between threaded
and non-threaded code.

-- 
Andrew.

In response to

Responses

pgsql-bugs by date

Next:From: Andrew GierthDate: 2008-11-06 16:03:20
Subject: Re: plperl & sort
Previous:From: Alex HunsakerDate: 2008-11-06 15:37:58
Subject: Re: plperl & sort

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group