On l�rdag, mar 1, 2003, at 10:08 Europe/Stockholm, Stas Bekman wrote:
while debugging the modperl problem with threads.pm and not realizing that the problem lies not in the perl_clone(), but in the fact that the app itself is threaded, I was trying to reproduce the problem with one perl interpreter and its clone as you can see in the program at the end.
In the test below I'm using a blead version of the threaded perl, perl -V is at the end.
What I've noticed is that if I don't preload 'threads.pm' before cloning:
% gcc -o clone test.c `perl -MExtUtils::Embed -e ccopts -e ldopts` -Wall -g -DPRELOAD=0
% ./clone
0
1
Attempt to free temp prematurely: SV 0x810b4e4 during global destruction.
Scalars leaked: 1
I get the perl_clone report that threads->self->tid is actually 1. But I
haven't spawned any threads. Shouldn't it report 0 as its tid()?
if I compile with -DPRELOAD=1 (so the cloned perl doesn't load threads.pm), both perls report 0 as their tid.
Also I get these destruction problems/leakage report, which go away if I clone with CLONEf_KEEP_PTR_TABLE|CLONEf_COPY_STACKS contrary to what perlapi.pod's perl_clone entry suggesting to use only CLONEf_KEEP_PTR_TABLE. Is this a problem in my test program or in threads.pm?
Here is the test program:
#include <EXTERN.h> #include <perl.h>
EXTERN_C void xs_init (pTHX);
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
EXTERN_C void xs_init(pTHX) { char *file = __FILE__; dXSUB_SYS; /* DynaLoader is a special case */ newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); }
#if PRELOAD == 0 #define LOAD "" #define TEST "require threads; print threads->self->tid;" #elif PRELOAD == 1 #define LOAD "require threads;" #define TEST "print threads->self->tid;" #endif
int main(int argc, char **argv, char **env) { char *embedding[] = { "", "-le", "0" }; dTHX; PerlInterpreter *one_perl = perl_alloc(); PerlInterpreter *two_perl;
aTHX = one_perl; PERL_SET_CONTEXT(aTHX); perl_construct(one_perl);
perl_parse(one_perl, xs_init, 3, embedding, (char **)NULL); /* DynaLoader must be preloaded before perl_clone, if DynaLoader * is to be required later */ eval_pv("require DynaLoader;", TRUE); eval_pv(LOAD, TRUE); /* loaded only by the first perl */
two_perl = perl_clone(one_perl, CLONEf_KEEP_PTR_TABLE);
eval_pv(TEST, TRUE);
aTHX = two_perl; PERL_SET_CONTEXT(aTHX); eval_pv(TEST, TRUE);
perl_destruct(two_perl); perl_free(two_perl);
perl_destruct(one_perl); perl_free(one_perl);
exit(0);
}
Weha, this is an interesting problem :-)
First of all, using "require threads;" is nearly always wrong, but what happens here is still strange, I am wondering what is actually upping the TID count.... hmmm...
What happens here is that it SEEMS like the Boot: section in threads.xs is being executed twice, which is very odd, and kind of wrong. .... I thought BOOT sections were only run once?
Need more investigation.
Arthur
