in reply to Re: Multiple perl interpreters and Module::Runtime (-d)
in thread Multiple perl interpreters and Module::Runtime

Thanks for the hint. I've tried the Perl debugger and found the following:

It is crashing in the module Exporter, line 64:

[31499->31499] DB<1> Exporter::import(/export/packages/perl-5.12.3/li +b/5.12.3/Exporter.pm:64): 64: *{"$callpkg\::$_"} = \&{"$pkg\::$_"} foreach @_;
where the variables are:
$callpkg = "Module::Runtime" @_ = ("is_string") $_ = "is_string" $pkg = "Params::Classify"
When I tried to feed the debugger with this:
&{"$pkg\::$_"}
the debugger crashed. So there is probably something bad going on in Params::Classify. The generated core dump shows, that it crashed in lib/params/Classify.xs:635. The backtrace is very high and starts like this:
... #87243 0x00007fd820981b7a in myck_entersub (my_perl=0x2143000, op=0x26 +0b250) at lib/Params/Classify.xs:635 #87244 0x00007fd820981b7a in myck_entersub (my_perl=0x2143000, op=0x26 +0b250) at lib/Params/Classify.xs:635 #87245 0x00007fd820981b7a in myck_entersub (my_perl=0x2143000, op=0x26 +0b250) at lib/Params/Classify.xs:635 #87246 0x00007fd820981b7a in myck_entersub (my_perl=0x2143000, op=0x26 +0b250) at lib/Params/Classify.xs:635 #87247 0x00007fd826cae142 in Perl_convert (my_perl=0x2143000, type=173 +, flags=192, o=0x260b250) at op.c:2652 #87248 0x00007fd826cb351c in Perl_utilize (my_perl=0x2143000, aver=1, +floor=147, version=0x0, idop=0x2617d20, arg=0x264e210) at op.c:3979 #87249 0x00007fd826d4d17c in Perl_yyparse (my_perl=0x2143000) at perly +.y:674 #87250 0x00007fd826ef2d6d in S_doeval (my_perl=0x2143000, gimme=2, sta +rtop=0x0, outside=0x0, seq=2054) at pp_ctl.c:3112 #87251 0x00007fd826efa35e in Perl_pp_require (my_perl=0x2143000) at pp +_ctl.c:3690 #87252 0x00007fd826da5fc8 in Perl_runops_debug (my_perl=0x2143000) at +dump.c:2049 #87253 0x00007fd826cdadb6 in Perl_eval_sv (my_perl=0x2143000, sv=0x216 +0e28, flags=4) at perl.c:2705 #87254 0x0000000000401a47 in perl_load_module_1 () #87255 0x00000000004040f9 in main ()
The function "myck_entersub" is calling itself ad infinitum, which is not good. My guess is there's something wrong with Classify.xs. Unfortunately, I don't know how to fix it. Do you have any ideas?

Replies are listed 'Best First'.
Re^3: Multiple perl interpreters and Module::Runtime (&)
by tye (Sage) on Feb 07, 2011 at 14:20 UTC
    *{"$callpkg\::$_"} = \&{"$pkg\::$_"} foreach @_;
    ... When I tried to feed the debugger with this:
    &{"$pkg\::$_"}

    \&... would never do what &... does. \&... takes a reference to a subroutine while &... invokes a subroutine. So what &{"$pkg\::$_"} does is rather irrelevant. It is indeed unfortunate that Params::Classify::is_string() stupidly produces an endless recursive loop when not given any parameters. But that likely has nothing to do with your original problem.

    The author of that module even included:

    sub is_string($);

    Which makes it fatal to call is_string() with no arguments... unless you use the prefix & to disable sub prototype checking, as you did. So even a bug report against the module might not yield anything.

    It is crashing in the module Exporter, line 64:

    How does it crash?

    - tye        

      How does it crash?
      Sorry, I should have been more specific.

      The program crashes with SEGFAULT after executing this line (Exporter.pm, line 64):

      64: *{"$callpkg\::$_"} = \&{"$pkg\::$_"} foreach @_;

      \&... would never do what &... does. \&... takes a reference to a subroutine while &... invokes a subroutine. So what &{"$pkg\::$_"} does is rather irrelevant. It is indeed unfortunate that Params::Classify::is_string() stupidly produces an endless recursive loop when not given any parameters. But that likely has nothing to do with your original problem.

      Indeed, you are right. However the expression \&{"$pkg\::$_"} entered into the perl debugger yields the same result - SEGFAULT crash.

      I've been trying to find the part of the line 64 that causes problems - and it shows that the bad part is the expression \&{"$pkg\::$_"}. Perl somehow cannot correctly resolve the function Params::Classify::is_string.

      My previous post followed with a GDB backtrace generated from the core dump of the crashed program. It shows where exactly the segfaulted.

      Btw. have you tried that program? Does it work on your computer?

        I'm not surprised that Params::Classify fails when used more than once in the same process.

        Here it declares a single data structure per process:

        static struct rtype_metadata { char const *desc_noun, *keyword_pv; SV *keyword_sv; } rtype_metadata[RTYPE_COUNT] = { { "scalar", "SCALAR", NULL }, { "array", "ARRAY", NULL }, { "hash", "HASH", NULL }, { "code", "CODE", NULL }, { "format", "FORMAT", NULL }, { "io", "IO", NULL }, };

        That data structure will eventually contain pointers to Perl variables, as set here:

        rtypemeta->keyword_sv = newSVpvn_share(rtypemeta->keyword_pv, strlen(rtypemeta->keyword_pv), 0);

        I don't believe that you can safely use Perl variables from one interpreter instance in a different instance of the interpreter.

        You could try loading Params::Classify in multiple Perl "threads" (using threads.pm) and see if that also dies and file a bug against the module.

        Or you could just get similar functionality in a way that doesn't require such a large chunk of XS code (since XS code is, by far, the single biggest source of core dumps in Perl -- because it is extremely hard to write robust XS code), especially XS code that entwines itself into everything by hooking 'entersub' and doing manipulations of the Perl opcodes.

        When searching the module documentation for some hint of why it hooked 'entersub' and manipulated opcodes, I found none, but I did find:

        This module is implemented in XS, with a pure Perl backup version for systems that can't handle XS.

        So, if you really want Params::Classify features, you could use the non-XS implementation (you'll have to figure out how that is done).

        Btw. have you tried that program?

        No. I have no intention of even downloading Param::Classify, much less trying to reproduce your problem locally.

        - tye