Re: plperl & sort

Поиск
Список
Период
Сортировка
От Andrew Gierth
Тема Re: plperl & sort
Дата
Msg-id 8763n0hmk1.fsf@news-spur.riddles.org.uk
обсуждение исходный текст
Ответ на Re: plperl & sort  ("Alex Hunsaker" <badalex@gmail.com>)
Ответы Re: plperl & sort  ("Alex Hunsaker" <badalex@gmail.com>)
Список pgsql-bugs
>>>>> "Alex" == Alex Hunsaker <badalex@gmail.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.

В списке pgsql-bugs по дате отправления:

Предыдущее
От: "Alex Hunsaker"
Дата:
Сообщение: Re: plperl & sort
Следующее
От: Andrew Gierth
Дата:
Сообщение: Re: plperl & sort