Perl / perl5

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

Caret X does not use readlink() when coreutils are compiled with multicall support #15922

Open p5pRT opened 7 years ago

p5pRT commented 7 years ago

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

Searchable as RT130997$

p5pRT commented 7 years ago

From kabel@blackhole.sk

Created by kabel@blackhole.sk

When coreutils are compiled with multicall support\, the command ls -l /proc/self/exe outputs something like​:

  lrwxrwxrwx 1 user group 0 Jan 1 00​:00 /proc/self/exe -> /usr/bin/coreutils

But when determining the HAS_PROCSELFEXE macro\, perl's Configure script checks if the result of the ls command contains string '/ls'. It this case this fails\, because there is no /bin/ls\, rather /usr/bin/coreutils.

Thus when perl is compiled on systems with multicall coreutils\, it cannot check the path to its own executable\, and thus the $^X variable return argv[0].

I encountered this issue when compiling OpenWRT/LEDE on my Gentoo system with multicall coreutils​: when perl is cross compiled\, miniperl is just a symlink to host's perl\, which\, in this case\, is built to be relocatable. But the code which searches for modules could not find the XXX/usr/lib/perl5 directory\, because instead of "XXX/usr/bin/perl"\, it had just "./miniperl" in $^X.

I think the best way to check for /proc/self/exe and similar symlinks in Configure would be to compile a small test.c which check for this\, ie. something like

  #include \<unistd.h>   int main(int argc\, char ** argv) {   char r[1024];   size_t l = readlink(argv[1]\, r\, 1024);   return l \< 1024 && !strcmp(r\, argv[2]));   }

Then Configure could just call /PATH/test /proc/self/exe /PATH/test to check if /proc/self/exe works as intended.

Perl Info ``` Flags: category=core severity=low Site configuration information for perl 5.24.1: Configured by Gentoo at Fri Mar 10 18:00:40 CET 2017. Summary of my perl5 (revision 5 version 24 subversion 1) configuration: Platform: osname=linux, osvers=4.9.13-gentoo, archname=x86_64-linux uname='linux thinkpad 4.9.13-gentoo #1 smp thu mar 9 11:43:35 cet 2017 x86_64 intel(r) core(tm) i7-3520m cpu @ 2.90ghz genuineintel gnulinux ' config_args='-des -Dinstallprefix=/usr -Dinstallusrbinperl=n -Di_ndbm -Di_gdbm -Di_db -DDEBUGGING=none -Dinc_version_list=5.24.0/x86_64-linux 5.24.0 -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Dnoextensions=ODBM_File -Duseshrplib -Darchname=x86_64-linux -Dcc=x86_64-pc-linux-gnu-gcc -Doptimize=-march=native -O3 -pipe -fPIC -flto=4 -fuse-linker-plugin -Wl,-fuse-ld=gold -Dldflags=-Wl,-O1 -Wl,--as-needed -Dprefix=/usr -Dsiteprefix=/usr/local -Dvendorprefix=/usr -Dscriptdir=/usr/bin -Dprivlib=/usr/lib64/perl5/5.24.1 -Darchlib=/usr/lib64/perl5/5.24.1/x86_64-linux -Dsitelib=/usr/local/lib64/perl5/5.24.1 -Dsitearch=/usr/local/lib64/perl5/5.24.1/x86_64-linux -Dvendorlib=/usr/lib64/perl5/vendor_perl/5.24.1 -Dvendorarch=/usr/lib64/perl5/vendor_perl/5.24.1/x86_64-linux -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dvendorman1dir=/usr/share/man/man1 -Dvendorman3dir=/usr/share/man/man3 -Dman1ext=1 -Dman3ext=3pm -Dlibperl=libperl.so.5.24.1 -Dlocincpth=/usr/include -Dglibpth=/lib64 /usr/lib64 -Duselargefiles -Dd_semctl_semun -Dcf_by=Gentoo -Dmyhostname=localhost -Dperladmin=root@localhost -Ud_csh -Dsh=/bin/sh -Dtargetsh=/bin/sh -Uusenm -Di_ndbm -Di_gdbm -Di_db -DDEBUGGING=none -Dinc_version_list=5.24.0/x86_64-linux 5.24.0 -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Dnoextensions=ODBM_File' hint=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='x86_64-pc-linux-gnu-gcc', ccflags ='-fwrapv -fno-strict-aliasing -pipe -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-march=native -O3 -pipe -fPIC -flto=4 -fuse-linker-plugin -Wl,-fuse-ld=gold', cppflags='-fwrapv -fno-strict-aliasing -pipe' ccversion='', gccversion='5.4.0', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='x86_64-pc-linux-gnu-gcc', ldflags ='-Wl,-O1 -Wl,--as-needed' libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include-fixed /usr/lib /lib/../lib64 /usr/lib/../lib64 /lib libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc libc=libc-2.23.so, so=so, useshrplib=true, libperl=libperl.so.5.24.1 gnulibc_version='2.23' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -march=native -O3 -pipe -fPIC -flto=4 -fuse-linker-plugin -Wl,-fuse-ld=gold -Wl,-O1 -Wl,--as-needed' Locally applied patches: gentoo/hints_hpux - Fix hpux hints gentoo/aix_soname - aix gcc detection and shared library soname support gentoo/EUMM-RUNPATH - https://bugs.gentoo.org/105054 cpan/ExtUtils-MakeMaker: drop $PORTAGE_TMPDIR from LD_RUN_PATH gentoo/config_over - Remove -rpath and append LDFLAGS to lddlflags gentoo/opensolaris_headers - Add headers for opensolaris gentoo/patchlevel - List packaged patches for perl-5.24.1-r1(#3) in patchlevel.h gentoo/cleanup-paths - Cleanup PATH and shrpenv gentoo/enc2xs - Tweak enc2xs to follow symlinks and ignore missing @INC directories. gentoo/darwin-cc-ld - https://bugs.gentoo.org/297751 darwin: Use $CC to link gentoo/cpan_definstalldirs - Provide a sensible INSTALLDIRS default for modules installed from CPAN. gentoo/interix - Fix interix hints gentoo/create_libperl_soname - https://bugs.gentoo.org/286840 Set libperl soname gentoo/mod_paths - Add /etc/perl to @INC gentoo/EUMM_perllocalpod - cpan/ExtUtils-MakeMaker: remove targets that generate perllocal.pod gentoo/drop_fstack_protector - https://bugs.gentoo.org/348557 Don't force -fstack-protector on everyone gentoo/usr_local - Configure: Don't include sources in /usr/local/ for compiling perl gentoo/D-SHA-CFLAGS - https://bugs.gentoo.org/506818 Do not set custom CFLAGS in cpan/Digest-SHA gentoo/io_socket_ip_tests - cpan/IO-Socket-IP: Disable network tests gentoo/cygwin-libperl - Cygwin: avoid libperl.dll.dll.a gentoo/tests - Fixup EUMM perlocal.pod tests and customised SHA1s gentoo/basepm-dot-inc - base.pm: Protect against . in @INC gentoo/zlib-1.2.9-backported-fixes - [rt#119762] Compress-Raw-Zlib: backport zlib 1.2.9+ fixes from upstream 2.073 gentoo/gcc6-lto-configure - [RT#128131] fix symbol detection with gcc 6 link-time optimization debian/cpan-missing-site-dirs - Fix CPAN::FirstTime defaults with nonexisting site dirs if a parent is writable debian/makemaker-pasthru - Pass LD settings through to subdirectories fixes/memoize_storable_nstore - [rt.cpan.org #77790] Memoize::Storable: respect 'nstore' option not respected fixes/podman-pipe - Better errors for man pages from standard input fixes/respect_umask - Respect umask during installation fixes/net_smtp_docs - [rt.cpan.org #36038] Document the Net::SMTP 'Port' option fixes/document_makemaker_ccflags - [rt.cpan.org #68613] Document that CCFLAGS should include $Config{ccflags} fixes/parallel-manisort.patch - Fix parallel building @INC for perl 5.24.1: /etc/perl /usr/local/lib64/perl5/5.24.1/x86_64-linux /usr/local/lib64/perl5/5.24.1 /usr/lib64/perl5/vendor_perl/5.24.1/x86_64-linux /usr/lib64/perl5/vendor_perl/5.24.1 /usr/local/lib64/perl5 /usr/lib64/perl5/vendor_perl/5.24.0/x86_64-linux /usr/lib64/perl5/vendor_perl/5.24.0 /usr/lib64/perl5/vendor_perl /usr/lib64/perl5/5.24.1/x86_64-linux /usr/lib64/perl5/5.24.1 Environment for perl 5.24.1: HOME=/home/kabel LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=.:/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/x86_64-pc-linux-gnu/gcc-bin/5.4.0:/usr/x86_64-pc-linux-gnu/aarch64-unknown-linux-gnu/gcc-bin/5.4.0:/usr/x86_64-pc-linux-gnu/armv7a-hardfloat-linux-gnueabi/gcc-bin/4.9.4:/usr/x86_64-pc-linux-gnu/mipsel-softfloat-linux-gnu/gcc-bin/5.4.0:/usr/x86_64-pc-linux-gnu/mipsel-softfloat-linux-musl/gcc-bin/4.9.4:/sbin:/usr/sbin:/home/kabel/bin PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 7 years ago

From @jkeenan

Are there any 'Configure' experts who could evaluate this bug report?

Thank you very much.

-- James E Keenan (jkeenan@​cpan.org)

p5pRT commented 7 years ago

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

zwizwa commented 2 months ago

I ran into the same problem compiling perl-5.40.0 as part of OpenWRT on my NixOS system.

jkeenan commented 2 months ago

OpenWRT

Some references:

jkeenan commented 2 months ago

From kabel@blackhole.sk

Created by kabel@blackhole.sk

When coreutils are compiled with multicall support, the command ls -l /proc/self/exe outputs something like​:

lrwxrwxrwx 1 user group 0 Jan 1 00​:00 /proc/self/exe -> /usr/bin/coreutils

But when determining the HAS_PROCSELFEXE macro, perl's Configure script checks if the result of the ls command contains string '/ls'. It this case this fails, because there is no /bin/ls, rather /usr/bin/coreutils.

Thus when perl is compiled on systems with multicall coreutils, it cannot check the path to its own executable, and thus the $^X variable return argv[0].

I encountered this issue when compiling OpenWRT/LEDE on my Gentoo system with multicall coreutils​: when perl is cross compiled, miniperl is just a symlink to host's perl, which, in this case, is built to be relocatable. But the code which searches for modules could not find the XXX/usr/lib/perl5 directory, because instead of "XXX/usr/bin/perl", it had just "./miniperl" in $^X.

I think the best way to check for /proc/self/exe and similar symlinks in Configure would be to compile a small test.c which check for this, ie. something like

include int main(int argc, char ** argv) { char r[1024]; size_t l = readlink(argv[1], r, 1024); return l < 1024 && !strcmp(r, argv[2])); }

Then Configure could just call /PATH/test /proc/self/exe /PATH/test to check if /proc/self/exe works as intended. Perl Info

I got warnings and errors when I attempted to compile the C program submitted by the OP back in 2017. With my limited C skills, I modified the probe program as follows:

$ cat gh-15922-readlink.c 
#include <unistd.h>
#include <string.h>
int main(int argc, char ** argv) {
    char r[1024];
    size_t l = readlink(argv[1], r, 1024);
    return l < 1024 && !strcmp(r, argv[2]);
}

Can someone compile and run this program on a system with /usr/bin/coreutils or otherwise similar to the OP's platform? Thanks.