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

Reply via email to