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

I am trying to use Devel::NYTProf and have the following shell script:

#!/bin/tcsh -f setenv PERL5LIB "/home/user/perl_modules/lib/perl5/x86_64-linux" /usr/bin/perl -d:NYTProf factorial_recurse.pl 12

factorial_recurse.pl contains the following:

#!/usr/bin/perl use strict; sub factorial { return unless int($_[0]) == $_[0]; return 1 if $_[0] == 1; return $_[0] * factorial($_[0] - 1); } print factorial($ARGV[0]), "\n";

If I run the above, I receive the following error message:

Can't load '/home/user/perl_modules/lib/perl5/x86_64-linux/Devel/auto/ +Devel/NYTProf/NYTProf.so' for module Devel::NYTProf: /home/user/perl_ +modules/lib/perl5/x86_64-linux/Devel/auto/Devel/NYTProf/NYTProf.so: u +ndefined symbol: PL_stack_sp at /usr/share/perl5/XSLoader.pm line 68. at /home/user/perl_modules/lib/perl5/x86_64-linux/Devel/NYTProf/Core. +pm line 17. Compilation failed in require at /home/user/perl_modules/lib/perl5/x86 +_64-linux/Devel/NYTProf.pm line 26. Compilation failed in require. BEGIN failed--compilation aborted.

If I instead change /usr/bin/perl in the shell script to /tool/bin/perl, the script runs without errors. I found this fix when I searched for "undefined symbol: PL_stack_sp", but what exactly is going wrong here and why does using a different perl installation fix it? If anything I would expect the error case to be when the version of perl called in the shell script doesn't match the version specified in factorial_recurse.pl.
For reference, "/usr/bin/perl -v" is v5.16.3 and "/tool/bin/perl -v" is v5.12.2.

Replies are listed 'Best First'.
Re: Devel::NYTProf: "undefined symbol: PL_stack_sp" error
by Corion (Patriarch) on Aug 26, 2021 at 05:37 UTC

    The module loading path, most likely $ENV{PERL5LIB}, shows the path to one Perl version while you are running a different Perl version. Set up $ENV{PERL5LIB} to only contain paths for the Perl version you're actually running.

      If I include the following in factorial_recurse.pl:

      printf("perl5lib = $ENV{PERL5LIB}");

      It prints:

      perl5lib = /home/user/perl_modules/lib/perl5/x86_64-linux/

      and nothing else. I don't see a path to either perl version referenced in my previous post (/tool/bin/perl

      or

      /usr/bin/perl

      ). Is that a problem?

        The issue is that the libraries under that path are compiled for one of your perls, but not the other.

        You need to have a separate directory for each perl version, each of which has a version of the libraries you are using. This is what Corion was recommending in 11136089.

        A slightly more involved, but well tested and used, way to achieve this is to use local::lib to handle the different directories.