Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.88k stars 530 forks source link

unclear version error message #8661

Open p5pRT opened 17 years ago

p5pRT commented 17 years ago

Migrated from rt.perl.org#40652 (status was 'open')

Searchable as RT40652$

p5pRT commented 17 years ago

From perl@nevcal.com

This is a bug report for perl from perl@​nevcal.com\, generated with the help of perlbug 1.35 running under perl v5.8.8.

So in attempting to build PAR on Windows\, an inappropriate installation of perl58.dll into Windows\system32 by WordPerfect Mail (Corel has been notified about the WordPerfect Mail installation bug/issue) resulted in the following error message. Removing the perl58.dll from Windows\system32 resolved the problem\, but it took 6 months to figure out that that was what was needed\, because I am not a Perl internals guru (I just lurk and occasionally comment here in an attempt to learn more\, being a heavy user of Perl)\, and the following message is confusing.

Perl lib version (v5.8.8) doesn't match executable version (v5.8.3) at C​:/Perl/lib/Config.pm line 46.

Having finally figured out the cause of the problem\, with help from folks on the PAR list\, I'd like to see the message improved so that it would be more clear to non-gurus\, and lead to more rapid analysis of the problem. Here is what I have learned​:

So "Perl lib version" in the above message is the hard coded string in Config.pm. Which is fine\, but it is easily confused with the concept of the perl58.dll library file to people that don't know better. So a better explanation of what this version really is would be helpful.

And\, it seems that "executable version" might really mean that for static builds of perl for which there is no perl58.dll. But it appears that in the case of build of perl that do produce dynamic libraries\, that the "executable version" really is the "library version"... I cannot even find that there is a separate version for those two entities\, or any consistency checks to ensure that they are compatible.

On Windows\, where dynamic libraries are searched for according to the following rules (from Advanced Windows\, Third Edition\, Jeffrey Richter)\, it seems important to keep the executable and the dynamic library in the same directory\, both for the efficiency of finding the dynamic library on the first look\, and also to make it easier to keep consistent versions together\, so that this problem doesn't show up as often. The PAR build process assumes (erroneously in my opinion) that because the perl installation being used to build it is on the path\, that the dynamic link library found will be the one from that perl installation.
In the presence of the following rules\, and the stray perl58.dll placed in my C​:\Windows\system32 directory\, this was not so.

1. Directory containing the executable program 2. process's current directory 3. Windows system directory 4. Windows directory 5. directories listed in the PATH

So the real problem was that I was looking for a perl.exe with the wrong version\, in particular with version 5.8.3\, and I couldn't find one anywhere on my system. I should have been looking for a perl dynamic library (perl58.dll) with version 5.8.3\, but the error message didn't clue me in to the fact that that was the problem. Hence\, I think the error message needs to be improved.

It would be extremely helpful to use descriptive text in the message that doesn't have misleading connotations (lib\, executable) in some of the standard perl build environments.

It would be extremely helpful if the complete file name of the perl file producing $^V (in this case\, C​:\Windows\system32\perl58.dll) were included in the message -- doing this could completely eliminate the need for the erroneous descriptive words "executable version".

It would be great if the error message said something like​:

"Config.pm version (v5.8.8) doesn't match C​:\Windows\system32\perl58.dll version (v5.8.3)"

And it would be great if there were some explanation in Config.pod that explained what is going wrong and why Config.pm should have a version that gets checked against the version in perl58.dll\, etc. Although the likelihood is\, that when this sort of thing happens\, it will be because the wrong file got picked up according to the rules for finding dynamic links libraries\, and the display of the fully qualified file name will give away why the problem is occurring.

Following Andy's suggestion that this should be reported as a bug\, perhaps with a patch\, and a hint about what might be wrong\, I'll point out that I only have Windows perl to test with\, so the patch at least needs to be tested on other platforms to avoid breakage\, and perhaps modified for compatibility.

Andy suggested​:

Yes\, that would have been more useful in this case. The 'Config.pm' part is easy. Unfortunately\, I don't know offhand how to get the shared library location. Perl's $^X variable would likely just be C​:/Perl/bin/perl.exe or something like that.

Does Windows perl have $Config{useshrplib} set? If so\, we could change configpm (the tool that generates lib/Config.pm) to conditionally say something like

  Perl Config.pm version (v5.8.8) doesn't match shared library version   used by C​:/Perl/bin/perl.exe (v5.8.3) at C​:/Perl/lib/Config.pm line 46.

I don't know if that would be more or less confusing\, however.

On a related note\, would adding useful comments to Config.pm near line 46 have been any help? Perhaps we could add a paragraph there discussing the problem in more detail?

My attempt to analyze Andy's suggestion​:

I temporarily added a line in Config.pm just before the error message is produced to print out $Config{useshrplib}\, $^X\, and $0. For the problematic case\, $Config{useshrplib} was empty\, $^X was "perl.exe"\, and $0 was ".\par.exe".

None of that seems particularly useful. It is possible\, on Windows\, for a shared DLL file to obtain its fully-qualified path name\, but I have no clue if there is already a hook in the library to obtain it -- I certainly don't see a Perl variable dedicated to that purpose in the documentation. The API is GetModuleFileName\, but it must be called from C code\, not Perl code. Such would be a handy addition\, for systems that can report their library module names.

So my patch (below) adds a paragraph of explanation\, avoids using "lib" for the first version\, and alters "executable" to say "executable (or possibly shared library)". I have no personal attachment to the comment text or even the error message text; there may be better explanations or better wording for the error messaeg\, I didn't (but could) include the list of special places that Windows looks for DLLs\, etc.

It would be very nice if the message could include the path to the library or executable that is mismatched (different from the version in Config.pm) but that looks like it would take more work than I could do\, not ever having worked on Perl internals.

Dunno how to attach to perlbug reports\, so the patch is in-line\, sorry.
Well\, since I had to send it manually\, I'll try attaching the patch too.

Inline Patch ```diff --- Config.pm~ Thu Sep 21 18:48:43 2006 +++ Config.pm Thu Nov 2 10:11:43 2006 @@ -40,11 +40,22 @@ return; } -die "Perl lib version (v5.8.8) doesn't match executable version ($])" +# this error is generated when the compiled perl binary, either the ```

executable +# perl program for static builds\, or the dynamic shared library for dynamic +# builds\, is not consistent with the version found in the CORE distributed +# Config.pm file. This indicates some inconsistency in the Perl components +# found at execution time\, and such inconsistency is serious enough to be +# considered fatal immediately\, rather than attempting to execute with +# mismatched components\, which would likely lead to other\, more mysterious +# and difficult to diagnose issues. Check versions and paths to figure out +# how the inconsistency was generated; be aware that on Windows\, there are +# 4 places searched for shared libraries before the PATH is searched! + +die "Perl Config.pm version (v5.8.8) doesn't match executable (or possibly shared library) version ($])"   unless $^V;

$^V eq v5.8.8 - or die "Perl lib version (v5.8.8) doesn't match executable version (" . + or die "Perl Config.pm version (v5.8.8) doesn't match executable (or possibly shared library) version (" .   sprintf("v%vd"\,$^V) . ")";


Flags​:   category=core   severity=medium


Site configuration information for perl v5.8.8​:

Configured by SYSTEM at Tue Aug 29 12​:39​:43 2006.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration​:   Platform​:   osname=MSWin32\, osvers=5.0\, archname=MSWin32-x86-multi-thread   uname=''   config_args='undef'   hint=recommended\, useposix=true\, d_sigaction=undef   usethreads=define use5005threads=undef useithreads=define usemultiplicity=define   useperlio=define d_sfio=undef uselargefiles=define usesocks=undef   use64bitint=undef use64bitall=undef uselongdouble=undef   usemymalloc=n\, bincompat5005=undef   Compiler​:   cc='cl'\, ccflags ='-nologo -GF -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DNO_HASH_SEED -DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX'\,   optimize='-MD -Zi -DNDEBUG -O1'\,   cppflags='-DWIN32'   ccversion='12.00.8804'\, gccversion=''\, gccosandvers=''   intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234   d_longlong=undef\, longlongsize=8\, d_longdbl=define\, longdblsize=10   ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='__int64'\, lseeksize=8   alignbytes=8\, prototype=define   Linker and Libraries​:   ld='link'\, ldflags ='-nologo -nodefaultlib -debug -opt​:ref\,icf
-libpath​:"C​:\Perl\lib\CORE" -machine​:x86'   libpth=\lib   libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib
netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib   perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib
version.lib odbc32.lib odbccp32.lib msvcrt.lib   libc=msvcrt.lib\, so=dll\, useshrplib=yes\, libperl=perl58.lib   gnulibc_version=''   Dynamic Linking​:   dlsrc=dl_win32.xs\, dlext=dll\, d_dlsymun=undef\, ccdlflags=' '   cccdlflags=' '\, lddlflags='-dll -nologo -nodefaultlib -debug -opt​:ref\,icf -libpath​:"C​:\Perl\lib\CORE" -machine​:x86'

Locally applied patches​:   ACTIVEPERL_LOCAL_PATCHES_ENTRY   Iin_load_module moved for compatibility with build 806   Avoid signal flag SA_RESTART for older versions of HP-UX   PerlEx support in CGI​::Carp   Less verbose ExtUtils​::Install and Pod​::Find   Patch for CAN-2005-0448 from Debian with modifications   Rearrange @​INC so that 'site' is searched before 'perl'   Partly reverted 24733 to preserve binary compatibility   28671 Define PERL_NO_DEV_RANDOM on Windows   28376 Add error checks after execing PL_cshname or PL_sh_path   28305 Pod​::Html should not convert \"foo\" into ``foo''   27736 Make perl_fini() run with Sun WorkShop compiler   27619 Bug in Term​::ReadKey being triggered by a bug in Term​::ReadLine   27549 Move DynaLoader.o into libperl.so   27528 win32_pclose() error exit doesn't unlock mutex   27527 win32_async_check() can loop indefinitely   27515 ignore directories when searching @​INC   27359 Fix -d​:Foo=bar syntax   27210 Fix quote typo in c2ph   27203 Allow compiling swigged C++ code   27200 Make stat() on Windows handle trailing slashes correctly   27194 Get perl_fini() running on HP-UX again   27133 Initialise lastparen in the regexp structure   27034 Avoid \"Prototype mismatch\" warnings with autouse   26970 Make Passive mode the default for Net​::FTP   26921 Avoid getprotobyname/number calls in IO​::Socket​::INET   26897\,26903 Make common IPPROTO_* constants always available   26670 Make '-s' on the shebang line parse -foo=bar switches   26536 INSTALLSCRIPT versus INSTALLDIRS   26379 Fix alarm() for Windows 2003   26087 Storable 0.1 compatibility   25861 IO​::File performace issue   25084 long groups entry could cause memory exhaustion   24699 ICMP_UNREACHABLE handling in Net​::Ping


@​INC for perl v5.8.8​:   C​:/Perl/site/lib   C​:/Perl/lib   .


Environment for perl v5.8.8​:   HOME (unset)   LANG (unset)   LANGUAGE (unset)   LD_LIBRARY_PATH (unset)   LOGDIR (unset)  
PATH=d​:\my\ntpgms;d​:\my\perl;d​:\emacs\bin;C​:\Perl\bin;C​:\WINDOWS\system32;C​:\WINDOWS;C​:\WINDOWS\System32\Wbem;C​:\Program Files\ATI Technologies\ATI Control Panel;C​:\Program Files\ATI Technologies\ATI.ACE;d​:\my\pgms;C​:\Program Files\Common Files\Adobe\AGL   PERL_BADLANG (unset)   SHELL (unset)

-- Glenn -- http​://nevcal.com/

A protocol is complete when there is nothing left to remove. -- Stuart Cheshire\, Apple Computer\, regarding Zero Configuration Networking

p5pRT commented 17 years ago

From perl@nevcal.com

config_pm.diff ```diff --- Config.pm~ Thu Sep 21 18:48:43 2006 +++ Config.pm Thu Nov 2 10:11:43 2006 @@ -40,11 +40,22 @@ return; } -die "Perl lib version (v5.8.8) doesn't match executable version ($])" +# this error is generated when the compiled perl binary, either the executable +# perl program for static builds, or the dynamic shared library for dynamic +# builds, is not consistent with the version found in the CORE distributed +# Config.pm file. This indicates some inconsistency in the Perl components +# found at execution time, and such inconsistency is serious enough to be +# considered fatal immediately, rather than attempting to execute with +# mismatched components, which would likely lead to other, more mysterious +# and difficult to diagnose issues. Check versions and paths to figure out +# how the inconsistency was generated; be aware that on Windows, there are +# 4 places searched for shared libraries before the PATH is searched! + +die "Perl Config.pm version (v5.8.8) doesn't match executable (or possibly shared library) version ($])" unless $^V; $^V eq v5.8.8 - or die "Perl lib version (v5.8.8) doesn't match executable version (" . + or die "Perl Config.pm version (v5.8.8) doesn't match executable (or possibly shared library) version (" . sprintf("v%vd",$^V) . ")"; ```
p5pRT commented 12 years ago

From @jkeenan

On Thu Nov 02 11​:53​:38 2006\, perl@​nevcal.com wrote​:

This is a bug report for perl from perl@​nevcal.com\, generated with the help of perlbug 1.35 running under perl v5.8.8.

I reviewed this older ticket tonight. Because it is lengthy\, I urge readers of the list to refer to the original ticket. But I believe the salient points were​:

* A complaint about the lack of helpfulness of this error message​:

Perl lib version (v5.8.8) doesn't match executable version (v5.8.3) at C​:/Perl/lib/Config.pm line 46.

-- a message which I have also found confusing.

* The original poster's analysis\, with particular focus on how this gets more confusing on Windows.

* The poster's suggestion for an improved error message​:

It would be great if the error message said something like​:

"Config.pm version (v5.8.8) doesn't match C​:\Windows\system32\perl58.dll version (v5.8.3)"

And it would be great if there were some explanation in Config.pod that explained what is going wrong and why Config.pm should have a version that gets checked against the version in perl58.dll\, etc.

* The author's citation from feedback on a mailing list from Andy -- presumably Andy Dougherty​:

Yes\, that would have been more useful in this case. The 'Config.pm' part is easy. Unfortunately\, I don't know offhand how to get the shared library location. Perl's $^X variable would likely just be C​:/Perl/bin/perl.exe or something like that. [snip] On a related note\, would adding useful comments to Config.pm near line 46 have been any help? Perhaps we could add a paragraph there discussing the problem in more detail?

* The original poster's response to Andy's feedback and an inline patch​:

--- Config.pm~ Thu Sep 21 18​:48​:43 2006 +++ Config.pm Thu Nov 2 10​:11​:43 2006 @​@​ -40\,11 +40\,22 @​@​ return; }

-die "Perl lib version (v5.8.8) doesn't match executable version ($])" +# this error is generated when the compiled perl binary\, either the executable +# perl program for static builds\, or the dynamic shared library for dynamic +# builds\, is not consistent with the version found in the CORE distributed +# Config.pm file. This indicates some inconsistency in the Perl components +# found at execution time\, and such inconsistency is serious enough to be +# considered fatal immediately\, rather than attempting to execute with +# mismatched components\, which would likely lead to other\, more mysterious +# and difficult to diagnose issues. Check versions and paths to figure out +# how the inconsistency was generated; be aware that on Windows\, there are +# 4 places searched for shared libraries before the PATH is searched! + +die "Perl Config.pm version (v5.8.8) doesn't match executable (or possibly shared library) version ($])" unless $^V;

$^V eq v5.8.8 - or die "Perl lib version (v5.8.8) doesn't match executable version (" . + or die "Perl Config.pm version (v5.8.8) doesn't match executable (or possibly shared library) version (" . sprintf("v%vd"\,$^V) . ")";

Now\, since Config.pm is a generated file\, I believe the patch should have been made against 'configpm'. And\, inspecting that program in blead\, I see that the wording of the error message has changed somewhat from the time this ticket was originally filed​:

#####   281 die "Perl lib version (%s) doesn't match executable '$0' version ($])"   282 unless $^V;   283   284 $^V eq %s   285 or die "Perl lib version (%s) doesn't match executable '$0' version (" .   286 sprintf("v%%vd"\,$^V) . ")"; #####

So\, do people feel these error messages are sufficiently helpful?

Thank you very much. Jim Keenan

p5pRT commented 12 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 12 years ago

From @rjbs

I think "Config.pm" would be clearer than "lib" -- I wonder if that string is used in more than one place\, and that's why it is so vague? I will follow up.

p5pRT commented 12 years ago

From @jkeenan

On Sun Jan 22 15​:13​:15 2012\, rjbs wrote​:

I think "Config.pm" would be clearer than "lib" -- I wonder if that string is used in more than one place\, and that's why it is so vague? I will follow up.

Have you been able to follow up on this?

Thank you very much. Jim Keenan

p5pRT commented 12 years ago

From @nwc10

On Thu\, Nov 02\, 2006 at 11​:53​:39AM -0800\, Glenn Linderman wrote​:

It would be great if the error message said something like​:

"Config.pm version (v5.8.8) doesn't match C​:\Windows\system32\perl58.dll version (v5.8.3)"

Agree that it would be useful.

Does Windows perl have $Config{useshrplib} set? If so\, we could change configpm (the tool that generates lib/Config.pm) to conditionally say something like

Perl Config\.pm version \(v5\.8\.8\) doesn't match shared library version

used by C​:/Perl/bin/perl.exe (v5.8.3) at C​:/Perl/lib/Config.pm line 46.

I don't know if that would be more or less confusing\, however.

I think that's going to be more confusing\, as it's going to be 100% wrong.

The desire is to have the path of the (loaded) perl DLL in the error message. The value of $Config{useshrplib} in Config.pm is going to be the location of the *correct* perl DLL. The error message is triggered by the (stub) perl.exe loading the wrong DLL. The wrong DLL might have any path\, and it's that (unknown to %Config​::Config) path for the loaded DLL that is desired for the error message.

Nicholas Clark

p5pRT commented 12 years ago

From @nwc10

On Tue\, Mar 27\, 2012 at 02​:06​:28PM +0100\, Nicholas Clark wrote​:

On Thu\, Nov 02\, 2006 at 11​:53​:39AM -0800\, Glenn Linderman wrote​:

It would be great if the error message said something like​:

"Config.pm version (v5.8.8) doesn't match C​:\Windows\system32\perl58.dll version (v5.8.3)"

Agree that it would be useful.

Does Windows perl have $Config{useshrplib} set? If so\, we could change configpm (the tool that generates lib/Config.pm) to conditionally say something like

Perl Config\.pm version \(v5\.8\.8\) doesn't match shared library version

used by C​:/Perl/bin/perl.exe (v5.8.3) at C​:/Perl/lib/Config.pm line 46.

I don't know if that would be more or less confusing\, however.

I think that's going to be more confusing\, as it's going to be 100% wrong.

The desire is to have the path of the (loaded) perl DLL in the error message. The value of $Config{useshrplib} in Config.pm is going to be the location of the *correct* perl DLL. The error message is triggered by the (stub) perl.exe loading the wrong DLL. The wrong DLL might have any path\, and it's that (unknown to %Config​::Config) path for the loaded DLL that is desired for the error message.

I *think* that it may be possible to get about an 80% solution to this.

My impression was that Win32 already can (easily) report the path of the shared library\, as perl is already using this to find paths for @​INC [Please correct me if I'm wrong]

It looks like *most* dl_open() based platforms provide a dl_addr() function with this interface​:

DESCRIPTION   The dladdr() function queries dyld (the dynamic linker) for information   about the image containing the address addr. The information is returned   in the structure specified by info. The structure contains at least the   following members​:

  const char* dli_fname The pathname of the shared object containing   the address.

  void* dli_fbase The base address (mach_header) at which the   image is mapped into the address space of the   calling process.

  const char* dli_sname The name of the nearest run-time symbol with a   value less than or equal to addr.

  void* dli_saddr The value of the symbol returned in dli_sname.

  The dladdr() function is available only in dynamically linked programs.

(at least Linux\, FreeBSD\, OpenBSD\, OS X and Solaris and\, gosh\, HP-UX. Which confuses me\, as I thought that HP-UX had its own way of doing things\, and didn't use dlopen() etc. However\, it does look like shl_findsym() can be used to do it on the "native"/"classic"/"special biologist word" HP-UX API)

which should be good enough to find the filename for a symbol we know came from a dynamic libperl. Which means that it should be possible to expose this answer through a built-in private function.

I have enough more pressing itches to scratch that I can't promise to even look at this again in the foreseeable future (ie >12 months)

Nicholas Clark

p5pRT commented 12 years ago

From @nwc10

On Wed\, Apr 18\, 2012 at 01​:48​:30PM +0100\, Nicholas Clark wrote​:

I have enough more pressing itches to scratch that I can't promise to even look at this again in the foreseeable future (ie >12 months)

To add - if anyone wants to take this up\, I think the most useful way to start is to write suitable C code that can report the path to its library\, compile that into a shared object\, invoke the code from a main program\, and show that it works. On either Win32 or any *nix with dl_addr. And find someone else to do the other kind of OS.*

Nicholas Clark

* We support both kinds of OS\, ...   (Although someone able to test blead on QNX 4 and QNX Neutrino would be   useful. Not heard anything about either for a while)

p5pRT commented 11 years ago

From @tonycoz

On Wed Apr 18 05​:49​:13 2012\, nicholas wrote​:

My impression was that Win32 already can (easily) report the path of the shared library\, as perl is already using this to find paths for @​INC [Please correct me if I'm wrong]

Perl on Win32 includes code to initialize w32_module_name when the DLL is loaded.

(at least Linux\, FreeBSD\, OpenBSD\, OS X and Solaris and\, gosh\, HP-UX.

I can add Haiku-OS to that list (well\, it's in the headers.)

This ticket included a patch to Config.pm\, which is a generated file\, so I've rejected the patch.

The ticket itself remains open if anyone is interested.

Tony