Re: plperl & sort - Mailing list pgsql-bugs
From | Andrew Gierth |
---|---|
Subject | Re: plperl & sort |
Date | |
Msg-id | 8763n0hmk1.fsf@news-spur.riddles.org.uk Whole thread Raw |
In response to | Re: plperl & sort ("Alex Hunsaker" <badalex@gmail.com>) |
Responses |
Re: plperl & sort
("Alex Hunsaker" <badalex@gmail.com>)
|
List | 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 by date: