somekindafreak has asked for the wisdom of the Perl Monks concerning the following question:

I have created a simple threading module that runs queued subroutines simultaneously. It works great standalone, but I am now integrating it with a larger system. This system has dozens of objects, each which may need to reference data from other objects. Therefore I create one context object that stores indexed references to each object. Each object created also has a reference back to the context object.

I then run the thread module, integrated with the larger system, and everything works great. The threads are created and run the queued subroutines simultaneously. However when I join the threads, I get this error:

panic: regfree data code 'ð' during global destruction.

The data code is different every time. I suspected it had to do with perl's object cleanup being messy due to my references so I wrote a cleanup routine to walk through the context, deleting all references and undeffing all objects. However even after this routine is run, one or two objects are still not destroyed (as indicated using print statements in a DESTROY routine appearing at the time of the join and not the undef executed during the cleanup) and the error above still occurs.

I have googled this to no avail. I can't be the only one hitting this problem. Any advice on the true cause of the problem, or another solution for cleaning up all my objects/references so that the threads can join without this error?

  • Comment on panic: regfree data code 'ð' during global destruction. error when joining threads

Replies are listed 'Best First'.
Re: panic: regfree data code 'ð' during global destruction. error when joining threads
by grinder (Bishop) on Jun 11, 2008 at 12:38 UTC

    What version of perl are you using? 5.8 or 5.10? There's been a lot of hard work put into the threads subsystem, and you also should make sure you're using the latest versions of threads.pm. That *may* solve your problem.

    Otherwise you will have to start cutting bits out until you can reproduce the problem reliably in a more-or-less self-contained manner.

    Are these objects of which you speak shared, or per thread? Can you not encapsulate their acces via an API rather than slinging the objects around indiscriminantly? Are you using threads::shared?

    • another intruder with the mooring in the heart of the Perl

      There's been a lot of hard work put into the threads subsystem, and you also should make sure you're using the latest versions of threads.pm.

      Unfortunately, the later versions of threads seem less reliable than that which shipped with 5.8.6.

      Specifically, leaked scalars seem to abound during global destruction, and traps when joining or detaching threads are more prevalent. This seems to be true of the CPAN version in conjunction with 5.8.6, 5.8.8 and 5.10.

      I don't have a clean example to demonstrate this yet. but threading definitely seems less stable since the version that shipped with 5.8.6 was superceded.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
      The perl version I am running is
      Summary of my perl5 (revision 5 version 8 subversion 8) configuration: Platform: osname=solaris, osvers=2.8, archname=sun4-solaris-thread-multi-64i +nt uname='sunos thor1 5.8 generic_117350-26 sun4u sparc sunw,sun-fire +-v210 ' config_args='-de -Dcc=gcc -Dmake=make -D prefix=/opt/VRTSperl -D u +sethreads -D useithreads -D useperlio -D use64bitint' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef useithreads=define usemulti +plicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=define use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -fno-strict-aliasing -pipe -Wdecl +aration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_F +ILE_OFFSET_BITS=64', optimize='-O', cppflags='-D_REENTRANT -fno-strict-aliasing -pipe -Wdeclaration-af +ter-statement -I/usr/local/include' ccversion='', gccversion='3.4.2', gccosandvers='solaris2.8' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=87654321 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=1 +6 ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='of +f_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='gcc', ldflags =' -L/usr/local/lib ' libpth=/usr/local/lib /usr/lib /usr/ccs/lib libs=-lsocket -lnsl -ldl -lm -lpthread -lc perllibs=-lsocket -lnsl -ldl -lm -lpthread -lc libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' ' cccdlflags='-fPIC', lddlflags='-G -L/usr/local/lib' Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API Built under solaris Compiled at May 1 2007 14:18:14 @INC: /opt/VRTSperl/lib/5.8.8/sun4-solaris-thread-multi-64int /opt/VRTSperl/lib/5.8.8 /opt/VRTSperl/lib/site_perl/5.8.8/sun4-solaris-thread-multi-64int /opt/VRTSperl/lib/site_perl/5.8.8 /opt/VRTSperl/lib/site_perl .
      I am using threads::shared, but at the moment the only things that are shared are the subroutine, args passed onto the queue that the thread is waiting on to execute.

      I made my Object pool global and simplified it so it surely can be cleaned up. Even after cleaning everything up myself, I get:

      DESTROY AIX=HASH(0x86df04) DESTROY Cfg=HASH(0x8bea54) DESTROY HPUX1123=HASH(0x8851e8) DESTROY HPUX1131=HASH(0x89ec3c) DESTROY RHEL4x8664=HASH(0x8686ac) DESTROY RHEL5x8664=HASH(0x86d4a8) DESTROY SLES10x8664=HASH(0x86d9d0) DESTROY SLES9x8664=HASH(0x891110) DESTROY SolSparc=HASH(0x89f164) DESTROY Solx64=HASH(0x890d98) DESTROY Sys=HASH(0x8850d4) 1 17:12:31 thread 1 returning sq_run_subs 0 17:12:32 Joining thread 1 DESTROY Thr=HASH(0x91994c) DESTROY EDR=HASH(0x885014) panic: regfree data code 'À' during global destruction.
      I presume the last two do not get cleaned up because I am running a subroutine from the Thr class, called from one in the EDR class. I can't imagine these objects being thread-unsafe, they're as simple as can be. Any further insight on to what is going on would be a blessing.

        You didn't identify which version of threads you are using?

        perl -Mthreads -le"print $threads::VERSION"

        Debugging any code is nigh impossible without seeing the code. Debugging threaded code without seeing it is impossible. If you're worried about proprietary code, then simply remove everything you can whilst still exhibiting the same problem.

        If you take something out and the problem goes away, put it back. When you have the minimum code left that still panics, post it. If nothng else, you will have a suitable testcase for raising a bug report.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: panic: regfree data code 'ð' during global destruction. error when joining threads
by zentara (Cardinal) on Jun 11, 2008 at 13:10 UTC
    or another solution for cleaning up all my objects/references so that the threads can join without this error?

    Without seeing your code, when you get into refcount problems with threads, it's best to reuse your threads. If you try to create threads, with create/join cycles, and an object isn't threadsafe, the object may hang around in memory and bite you later. The best approach, is to reuse threads by cleaning out the temp data from it's objects, and filling them with fresh data for the objects. You only need to join the threads when you exit the program.

    I know this sounds like a hassle, but it works reliably.... reuse your threads.


    I'm not really a human, but I play one on earth CandyGram for Mongo
      I can reuse the threads, but eventually they have to join, dont they? how would I get the main thread to exit without the

      A thread exited while 3 threads were running, <STDIN> line 1.

      message?

        they? how would I get the main thread to exit without the A thread exited while 3 threads were running warning?

        You can't exit the main thread without exiting all threads. If you need the behavior where the children continue on after the parent dies, you need "fork and exec", not threads.

        If you just want to make sure all threads finish , at the end of your main program put something like

        while (threads->list()) { $_->join() foreach threads->list(threads::joinable); sleep(1); }
        that should wait for all threads to finish. Remeber, a thread cannot be joined unless it returns or hits the end of it's code block. In an emergency, you can use the fact that calling "exit" from any thread, will kill all threads.

        I'm not really a human, but I play one on earth CandyGram for Mongo