Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

5.24.1 'make test' failures on linux-x86_64 (Linux: 4.10 glibc: 2.25 gcc: 5,4.0) #15946

Open
p5pRT opened this issue Apr 9, 2017 · 50 comments
Open

Comments

@p5pRT
Copy link

p5pRT commented Apr 9, 2017

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

Searchable as RT131126$

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @JVD66

Created by @JVD66

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee make.test.log
...
  t/run/switches ................................................ #
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
  # got 'Can\'t open perl script \"tmp17019C\"​: (null)\n'
  # expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
  FAILED at test 9
...
  t/op/taint .................................................... #
Failed test 732 - tainted $! at op/taint.t line 2060
  # got '2'
  # expected !~ /(?^​:^\d+$)/
  FAILED at test 732
...
  t/op/time ..................................................... #
Failed test 2 - very basic times test at op/time.t line 33
  FAILED at test 2
...
  cpan/ExtUtils-Install/t/Installed ............................. #
Failed test '... should find doc file under given dir'
  # at t/Installed.t line 267.
  # got​: '2'
  # expected​: '1'
  # Failed test '... should find all files files() would'
  # at t/Installed.t line 292.
  # got​: '1'
  # expected​: '2'
  # Failed test '... should find all files files() would, again'
  # at t/Installed.t line 295.
  # got​: '3'
  # expected​: '4'
  # Failed test '... should sort output'
  # at t/Installed.t line 297.
  # got​: '. /usr /usr/share/man/man3 /usr/share/man/man3'
  # expected​: '. /usr /usr/share/man/man3'
  # Failed test 'directory_tree() should report intermediate
dirs to those requested'
  # at t/Installed.t line 309.
  # got​: '2'
  # expected​: '3'
  # Looks like you failed 5 tests of 73.
  FAILED at test 56
...
  dist/autouse/t/autouse ........................................ #
Failed test 'Function imported via 'autouse' performs as expected'
  # at t/autouse.t line 32.
  # Looks like you failed 1 test of 15.
  FAILED at test 3
...
  dist/constant/t/constant ...................................... #
Failed test at t/constant.t line 99.
  # '1'
  # >
  # '6'
  # Looks like you failed 1 test of 109.
  FAILED at test 31
...
  dist/Time-HiRes/t/itimer ......................................
  t/itimer.t​: overall time allowed for tests (360s) exceeded!
  FAILED--expected 2 tests, saw 1

  The process was stuck doing (shown by strace of it) :

  getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0, 490041}}) = 0
  getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0, 490041}}) = 0
  getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
  getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
  lib/Benchmark .................................................
  ^- I didn't wait for this test to complete - it was also hanging,
  doing, as disclosed by strace :

  times({tms_utime=4, tms_stime=46582, tms_cutime=0, tms_cstime=0}) = 430811075
  times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
  times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
  times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

  The only major difference in configuration between 5.22.1, which
passed its test suite,
  and 5.24.1, which did not, was that I answered 'Yes' to using PerlIO
/ 'Fast stdio' .

  I will be investigating each problem above further unless someone
can tell me where
  I went wrong configuring . Thanks in advance for any replies!

Perl Info

Flags:
    category=core
    severity=high

Site configuration information for perl 5.24.1:

Configured by root at Sun Apr  9 14:51:14 GMT 2017.

Summary of my perl5 (revision 5 version 24 subversion 1) configuration:

  Platform:
    osname=linux, osvers=4.10.0, archname=x86_64-linux-thread-multi
    uname='linux jvdlux 4.10.0 #7 smp preempt wed feb 22 21:25:04 gmt
2017 x86_64 x86_64 gnulinux '
    config_args=''
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-g -fPIC -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2',
    optimize='-O2',
    cppflags='-g -fPIC'
    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='gcc', ldflags =''
    libpth=/usr/lib64 /usr/lib64/gcc/x86_64-pc-linux-gnu/5.4.0
    libs=-lpthread -lnsl -lgdbm -ldbm -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/usr/lib64/libc-2.25.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.25'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E
-Wl,-rpath,/usr/lib/perl5/5.24.1/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -O2'



@INC for perl 5.24.1:
    /usr/build/linux/perl-5.24.1
    /usr/build/linux/perl-5.24.1/lib
    /usr/build/linux/perl-5.24.1/ext
    /usr/lib/perl5/site_perl/5.24.1/x86_64-linux-thread-multi
    /usr/lib/perl5/site_perl/5.24.1
    /usr/lib/perl5/5.24.1/x86_64-linux-thread-multi
    /usr/lib/perl5/5.24.1
    /usr/lib/perl5/site_perl/5.22.1
    /usr/lib/perl5/site_perl/5.20.1
    /usr/lib/perl5/site_perl


Environment for perl 5.24.1:
    HOME=/root
    LANG=en_GB.UTF-8
    LANGUAGE (unset)
    LC_ALL=POSIX
    LD_LIBRARY_PATH=/usr/build/linux/perl-5.24.1
    LOGDIR (unset)
    PATH=/usr/bin:/usr/sbin
    PERL5LIB=/usr/build/linux/perl-5.24.1:/usr/build/linux/perl-5.24.1/lib:/usr/build/linux/perl-5.24.1/ext
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @JVD66

config.sh

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @JVD66

Re-Configuring and answering 'n' (No) to using fast stdio (PerlIO)
made no difference
- the same tests failed in same way .

It could be that something is buggy with Linux 4.10.0's timing subsystem - I've
raised a few bugs on this recently . Maybe PERL 5.24.1 will perform better
under latest Linux 4.10.9 ?
trying this now & will report back.

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @JVD66

Re-Configuring and answering 'n' (No) to using fast stdio (PerlIO)
made no difference
- the same tests failed in same way .

It could be that something is buggy with Linux 4.10.0's timing subsystem -
I've raised a few Linux kernel bugs on this recently.
Maybe PERL 5.24.1 will perform better under latest Linux 4.10.9 ?
I am trying this now & will report back.

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From [Unknown Contact. See original ticket]

Re-Configuring and answering 'n' (No) to using fast stdio (PerlIO)
made no difference
- the same tests failed in same way .

It could be that something is buggy with Linux 4.10.0's timing subsystem -
I've raised a few Linux kernel bugs on this recently.
Maybe PERL 5.24.1 will perform better under latest Linux 4.10.9 ?
I am trying this now & will report back.

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @jkeenan

On Sun, 09 Apr 2017 16​:03​:35 GMT, jvdias wrote​:

This is a bug report for perl from jason.vas.dias@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.24.1.

-----------------------------------------------------------------
[Please describe your issue here]

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful
Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee make.test.log
...
t/run/switches ................................................
#
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp17019C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
FAILED at test 9
...
t/op/taint ....................................................
#
Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732
...
t/op/time .....................................................
#
Failed test 2 - very basic times test at op/time.t line 33
FAILED at test 2
...
cpan/ExtUtils-Install/t/Installed .............................
#
Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files() would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files() would,
again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3
/usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report intermediate
dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56
...
dist/autouse/t/autouse ........................................
#
Failed test 'Function imported via 'autouse' performs as expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3
...
dist/constant/t/constant ......................................
#
Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31
...
dist/Time-HiRes/t/itimer ......................................
t/itimer.t​: overall time allowed for tests (360s) exceeded!
FAILED--expected 2 tests, saw 1

The process was stuck doing (shown by strace of it) :

getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
lib/Benchmark .................................................
^- I didn't wait for this test to complete - it was also
hanging,
doing, as disclosed by strace :

times({tms_utime=4, tms_stime=46582, tms_cutime=0, tms_cstime=0}) =
430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

The only major difference in configuration between 5.22.1, which
passed its test suite,
and 5.24.1, which did not, was that I answered 'Yes' to using PerlIO
/ 'Fast stdio' .

This is going to be difficult for us to diagnose without more information. You indicate that when configuring perl-5.24.1, you answered 'Yes' to one question to which, in perl-5.22.1, you answered 'No'. But that doesn't tell us how you answered all the *other* questions during manual configuration.

For example, the output of 'perl -V' you attached shows no 'config_args' but does show 'useithreads=define', suggesting you answered Yes to "Build a threading Perl? [n]". If I download a tarball of perl-5.24.1 and start to configure manually, I have to know how to answer each of the questions as a prerequisite to further diagnose.

If you know how you want to configure Perl, can you give us that description in regular words? We could then translate that into the particular set of arguments to Configure that meet your objective and get all tests to PASS.

Thank you very much.
Jim Keenan

I will be investigating each problem above further unless someone
can tell me where
I went wrong configuring . Thanks in advance for any replies!

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags​:
category=core
severity=high
---
Site configuration information for perl 5.24.1​:

Configured by root at Sun Apr 9 14​:51​:14 GMT 2017.

Summary of my perl5 (revision 5 version 24 subversion 1)
configuration​:

Platform​:
osname=linux, osvers=4.10.0, archname=x86_64-linux-thread-multi
uname='linux jvdlux 4.10.0 #7 smp preempt wed feb 22 21​:25​:04 gmt
2017 x86_64 x86_64 gnulinux '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
useithreads=define, usemultiplicity=define
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler​:
cc='gcc', ccflags ='-g -fPIC -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2',
optimize='-O2',
cppflags='-g -fPIC'
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='gcc', ldflags =''
libpth=/usr/lib64 /usr/lib64/gcc/x86_64-pc-linux-gnu/5.4.0
libs=-lpthread -lnsl -lgdbm -ldbm -ldb -ldl -lm -lcrypt -lutil -lc
perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
libc=/usr/lib64/libc-2.25.so, so=so, useshrplib=true,
libperl=libperl.so
gnulibc_version='2.25'
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E
-Wl,-rpath,/usr/lib/perl5/5.24.1/x86_64-linux-thread-multi/CORE'
cccdlflags='-fPIC', lddlflags='-shared -O2'

---
@​INC for perl 5.24.1​:
/usr/build/linux/perl-5.24.1
/usr/build/linux/perl-5.24.1/lib
/usr/build/linux/perl-5.24.1/ext
/usr/lib/perl5/site_perl/5.24.1/x86_64-linux-thread-multi
/usr/lib/perl5/site_perl/5.24.1
/usr/lib/perl5/5.24.1/x86_64-linux-thread-multi
/usr/lib/perl5/5.24.1
/usr/lib/perl5/site_perl/5.22.1
/usr/lib/perl5/site_perl/5.20.1
/usr/lib/perl5/site_perl

---
Environment for perl 5.24.1​:
HOME=/root
LANG=en_GB.UTF-8
LANGUAGE (unset)
LC_ALL=POSIX
LD_LIBRARY_PATH=/usr/build/linux/perl-5.24.1
LOGDIR (unset)
PATH=/usr/bin​:/usr/sbin
PERL5LIB=/usr/build/linux/perl-5.24.1​:/usr/build/linux/perl-
5.24.1/lib​:/usr/build/linux/perl-5.24.1/ext
PERL_BADLANG (unset)
SHELL=/bin/bash

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

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @jkeenan

On Sun, 09 Apr 2017 16​:54​:53 GMT, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:03​:35 GMT, jvdias wrote​:

This is a bug report for perl from jason.vas.dias@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.24.1.

-----------------------------------------------------------------
[Please describe your issue here]

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful
Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee make.test.log
...
t/run/switches
................................................
#
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp17019C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
FAILED at test 9
...
t/op/taint
....................................................
#
Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732
...
t/op/time
.....................................................
#
Failed test 2 - very basic times test at op/time.t line 33
FAILED at test 2
...
cpan/ExtUtils-Install/t/Installed
.............................
#
Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files() would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files() would,
again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3
/usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report intermediate
dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56
...
dist/autouse/t/autouse
........................................
#
Failed test 'Function imported via 'autouse' performs as expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3
...
dist/constant/t/constant
......................................
#
Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31
...
dist/Time-HiRes/t/itimer
......................................
t/itimer.t​: overall time allowed for tests (360s) exceeded!
FAILED--expected 2 tests, saw 1

The process was stuck doing (shown by strace of it) :

getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
lib/Benchmark
.................................................
^- I didn't wait for this test to complete - it was also
hanging,
doing, as disclosed by strace :

times({tms_utime=4, tms_stime=46582, tms_cutime=0, tms_cstime=0}) =
430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

The only major difference in configuration between 5.22.1, which
passed its test suite,
and 5.24.1, which did not, was that I answered 'Yes' to using PerlIO
/ 'Fast stdio' .

This is going to be difficult for us to diagnose without more
information. You indicate that when configuring perl-5.24.1, you
answered 'Yes' to one question to which, in perl-5.22.1, you answered
'No'. But that doesn't tell us how you answered all the *other*
questions during manual configuration.

For example, the output of 'perl -V' you attached shows no
'config_args' but does show 'useithreads=define', suggesting you
answered Yes to "Build a threading Perl? [n]". If I download a
tarball of perl-5.24.1 and start to configure manually, I have to know
how to answer each of the questions as a prerequisite to further
diagnose.

If you know how you want to configure Perl, can you give us that
description in regular words? We could then translate that into the
particular set of arguments to Configure that meet your objective and
get all tests to PASS.

Thank you very much.
Jim Keenan

After unwrapping a perl-5.24.1 tarball, I configured with this command​:

#####
sh ./Configure -des -Dusethreads -Accflags='-g -fPIC -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' \
-Dusefaststdio
#####

This was my guess at what your configuration would have looked like if done non-interactively -- with two exceptions​:

1. I was running as myself, not as root. (And I confess I don't know why you would do this as root.)

2. I did not include '-Duseshrplib'. (When I did include '-Duseshrplib' I got errors in 4 of the test files you cited.)

All tests PASSed. Content of './perl -Ilib -V' attached.

So my hunch is that those two differences just mentioned are the source of your test failures.

Thank you very much.
Jim Keenan
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @jkeenan

Summary of my perl5 (revision 5 version 24 subversion 1) configuration​:
 
  Platform​:
  osname=linux, osvers=4.4.0-72-generic, archname=x86_64-linux-thread-multi
  uname='linux zareason 4.4.0-72-generic #93-ubuntu smp fri mar 31 14​:07​:41 utc 2017 x86_64 x86_64 x86_64 gnulinux '
  config_args='-des -Dusethreads -Accflags=-g -fPIC -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -Dusefaststdio'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=define, usemultiplicity=define
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -g -fPIC -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -g -fPIC -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
  ccversion='', gccversion='5.4.0 20160609', 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='cc', ldflags =' -fstack-protector-strong -L/usr/local/lib'
  libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /lib64 /usr/lib64
  libs=-lpthread -lnsl -ldb -ldl -lm -lcrypt -lutil -lc
  perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
  libc=libc-2.23.so, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.23'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'

Characteristics of this binary (from libperl)​:
  Compile-time options​: HAS_TIMES MULTIPLICITY PERLIO_LAYERS
  PERL_COPY_ON_WRITE PERL_DONT_CREATE_GVSV
  PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
  PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
  PERL_PRESERVE_IVUV USE_64_BIT_ALL USE_64_BIT_INT
  USE_FAST_STDIO USE_ITHREADS USE_LARGE_FILES
  USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE
  USE_LOCALE_NUMERIC USE_LOCALE_TIME USE_PERLIO
  USE_PERL_ATOF USE_REENTRANT_API
  Built under linux
  Compiled at Apr 9 2017 14​:03​:52
  %ENV​:
  PERLBREW_BASHRC_VERSION="0.78"
  PERLBREW_HOME="/home/jkeenan/.perlbrew"
  PERLBREW_MANPATH="/home/jkeenan/perl5/perlbrew/perls/perl-5.24.1/man"
  PERLBREW_PATH="/home/jkeenan/perl5/perlbrew/bin​:/home/jkeenan/perl5/perlbrew/perls/perl-5.24.1/bin"
  PERLBREW_PERL="perl-5.24.1"
  PERLBREW_ROOT="/home/jkeenan/perl5/perlbrew"
  PERLBREW_VERSION="0.78"
  PERL_WORKDIR="/home/jkeenan/gitwork/perl"
  @​INC​:
  lib
  /usr/local/lib/perl5/site_perl/5.24.1/x86_64-linux-thread-multi
  /usr/local/lib/perl5/site_perl/5.24.1
  /usr/local/lib/perl5/5.24.1/x86_64-linux-thread-multi
  /usr/local/lib/perl5/5.24.1
  .

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @JVD66

On Sun, 09 Apr 2017 11​:15​:37 -0700, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:54​:53 GMT, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:03​:35 GMT, jvdias wrote​:

This is a bug report for perl from jason.vas.dias@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.24.1.

-----------------------------------------------------------------
[Please describe your issue here]

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful
Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee
make.test.log
...
t/run/switches
................................................
#
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp17019C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
FAILED at test 9
...
t/op/taint
....................................................
#
Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732
...
t/op/time
.....................................................
#
Failed test 2 - very basic times test at op/time.t line 33
FAILED at test 2
...
cpan/ExtUtils-Install/t/Installed
.............................
#
Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files() would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files() would,
again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3
/usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report intermediate
dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56
...
dist/autouse/t/autouse
........................................
#
Failed test 'Function imported via 'autouse' performs as expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3
...
dist/constant/t/constant
......................................
#
Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31
...
dist/Time-HiRes/t/itimer
......................................
t/itimer.t​: overall time allowed for tests (360s) exceeded!
FAILED--expected 2 tests, saw 1

The process was stuck doing (shown by strace of it) :

getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
lib/Benchmark
.................................................
^- I didn't wait for this test to complete - it was also
hanging,
doing, as disclosed by strace :

times({tms_utime=4, tms_stime=46582, tms_cutime=0, tms_cstime=0}) =
430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

The only major difference in configuration between 5.22.1, which
passed its test suite,
and 5.24.1, which did not, was that I answered 'Yes' to using
PerlIO
/ 'Fast stdio' .

This is going to be difficult for us to diagnose without more
information. You indicate that when configuring perl-5.24.1, you
answered 'Yes' to one question to which, in perl-5.22.1, you answered
'No'. But that doesn't tell us how you answered all the *other*
questions during manual configuration.

For example, the output of 'perl -V' you attached shows no
'config_args' but does show 'useithreads=define', suggesting you
answered Yes to "Build a threading Perl? [n]". If I download a
tarball of perl-5.24.1 and start to configure manually, I have to
know
how to answer each of the questions as a prerequisite to further
diagnose.

If you know how you want to configure Perl, can you give us that
description in regular words? We could then translate that into the
particular set of arguments to Configure that meet your objective and
get all tests to PASS.

Thank you very much.
Jim Keenan

After unwrapping a perl-5.24.1 tarball, I configured with this
command​:

#####
sh ./Configure -des -Dusethreads -Accflags='-g -fPIC
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' \
-Dusefaststdio
#####

This was my guess at what your configuration would have looked like if
done non-interactively -- with two exceptions​:

1. I was running as myself, not as root. (And I confess I don't know
why you would do this as root.)

2. I did not include '-Duseshrplib'. (When I did include '-
Duseshrplib' I got errors in 4 of the test files you cited.)

All tests PASSed. Content of './perl -Ilib -V' attached.

So my hunch is that those two differences just mentioned are the
source of your test failures.

Thank you very much.
Jim Keenan

Thanks very much for your response, James -

I did attach a copy of my config.sh to the mail, which didn't get attached to this bug - attaching now .

I built linux 4.10.9, and rebuilt perl with the -Dusefaststdio option - building
without it made no difference - tests still fail in same places.
Maybe suspect glibc-2.25 ?

I need the -Duseshrplib option. Could it be, after all this time, that
the test suite STILL needs the LD_PRELINK=${PWD}/libperl.so environment
variable setting ?

I am re-running tests as non-root user, with :
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} make test 2>&1 |
  tee make.test.dev.2.log

and the config.sh as attached. Same tests are still failing .
I think there is something about Linux 4.10+ / glibc-2.25+
that perl does not like. Previous perl 5.22.1 was built with
linux 4.8 (I think) & glibc-2.23? - over a year ago .
Have you tested on Linux 4.10+ under glibc 2.25+ ?
I am using binutils-2.28 .

I will investigate further and find out exactly why all the
timer / times() + constants tests fail tomorrow.

Thanks & Regards,
Jason

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @JVD66

config.sh

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2017

From @JVD66

make.test.dev.2.log

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @JVD66

On Sun, 09 Apr 2017 16​:35​:34 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 11​:15​:37 -0700, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:54​:53 GMT, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:03​:35 GMT, jvdias wrote​:

This is a bug report for perl from jason.vas.dias@​gmail.com,
generated with the help of perlbug 1.40 running under perl
5.24.1.

-----------------------------------------------------------------
[Please describe your issue here]

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful
Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee
make.test.log
...
t/run/switches
................................................
#
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp17019C\"​:
(null)\n'
# expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
FAILED at test 9
...
t/op/taint
....................................................
#
Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732
...
t/op/time
.....................................................
#
Failed test 2 - very basic times test at op/time.t line 33
FAILED at test 2
...
cpan/ExtUtils-Install/t/Installed
.............................
#
Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files() would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files() would,
again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3
/usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report
intermediate
dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56
...
dist/autouse/t/autouse
........................................
#
Failed test 'Function imported via 'autouse' performs as
expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3
...
dist/constant/t/constant
......................................
#
Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31
...
dist/Time-HiRes/t/itimer
......................................
t/itimer.t​: overall time allowed for tests (360s)
exceeded!
FAILED--expected 2 tests, saw 1

The process was stuck doing (shown by strace of it) :

getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
lib/Benchmark
.................................................
^- I didn't wait for this test to complete - it was also
hanging,
doing, as disclosed by strace :

times({tms_utime=4, tms_stime=46582, tms_cutime=0, tms_cstime=0})

430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

The only major difference in configuration between 5.22.1, which
passed its test suite,
and 5.24.1, which did not, was that I answered 'Yes' to using
PerlIO
/ 'Fast stdio' .

This is going to be difficult for us to diagnose without more
information. You indicate that when configuring perl-5.24.1, you
answered 'Yes' to one question to which, in perl-5.22.1, you
answered
'No'. But that doesn't tell us how you answered all the *other*
questions during manual configuration.

For example, the output of 'perl -V' you attached shows no
'config_args' but does show 'useithreads=define', suggesting you
answered Yes to "Build a threading Perl? [n]". If I download a
tarball of perl-5.24.1 and start to configure manually, I have to
know
how to answer each of the questions as a prerequisite to further
diagnose.

If you know how you want to configure Perl, can you give us that
description in regular words? We could then translate that into
the
particular set of arguments to Configure that meet your objective
and
get all tests to PASS.

Thank you very much.
Jim Keenan

After unwrapping a perl-5.24.1 tarball, I configured with this
command​:

#####
sh ./Configure -des -Dusethreads -Accflags='-g -fPIC
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' \
-Dusefaststdio
#####

This was my guess at what your configuration would have looked like
if
done non-interactively -- with two exceptions​:

1. I was running as myself, not as root. (And I confess I don't know
why you would do this as root.)

2. I did not include '-Duseshrplib'. (When I did include '-
Duseshrplib' I got errors in 4 of the test files you cited.)

All tests PASSed. Content of './perl -Ilib -V' attached.

So my hunch is that those two differences just mentioned are the
source of your test failures.

Thank you very much.
Jim Keenan

Thanks very much for your response, James -

I did attach a copy of my config.sh to the mail, which didn't get
attached to this bug - attaching now .

I built linux 4.10.9, and rebuilt perl with the -Dusefaststdio option
- building
without it made no difference - tests still fail in same places.
Maybe suspect glibc-2.25 ?

I need the -Duseshrplib option. Could it be, after all this time, that
the test suite STILL needs the LD_PRELINK=${PWD}/libperl.so
environment
variable setting ?

I am re-running tests as non-root user, with :
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} make test 2>&1
|
tee make.test.dev.2.log

and the config.sh as attached. Same tests are still failing .
I think there is something about Linux 4.10+ / glibc-2.25+
that perl does not like. Previous perl 5.22.1 was built with
linux 4.8 (I think) & glibc-2.23? - over a year ago .
Have you tested on Linux 4.10+ under glibc 2.25+ ?
I am using binutils-2.28 .

I will investigate further and find out exactly why all the
timer / times() + constants tests fail tomorrow.

Thanks & Regards,
Jason

Aha ! there is a problem on my system with times() -

RE​: t/op/time.t -

The test that fails is :

$ LD_LIBRARY_PATH=${PWD} \
  LD_PRELINK=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD} /ext​:${PWD}/t ./perl -e '$beg = time;
($beguser, $begsys) = times;
while (($now = time) == $beg) { sleep 1 }

# ok($now > $beg && $now - $beg < 10, 'very basic time test');
print time, " ", $now, " ", $beg, "\n";

my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
  for my $j (1..1000) { ++$x; }; # burn some user cycles
  ($nowuser, $nowsys) = times;
  $i = 2_000_000 if $nowuser > $beguser &&
  ( $nowsys >= $begsys ||
  (!$nowsys && !$begsys));
  last if time - $beg > 20;
}

print $beguser, " ", $begsys, " ", join(" ",times),"\n";
'
1491785650 1491785650 1491785649
0 0 0 19.5 0 0
$

ie. Linux / glibc is returning FOUR elements for times() -
see :
  http​://man7.org/linux/man-pages/man2/times.2.html :
"
  The struct tms is as defined in <sys/times.h>​:

  struct tms {
  clock_t tms_utime; /* user time */
  clock_t tms_stime; /* system time */
  clock_t tms_cutime; /* user time of children */
  clock_t tms_cstime; /* system time of children */
  };
"
 
So the expression​:
  $(beguser, $begsys) = times;

would set $begsys to the remainder of the list ?

Confirmed by doing :
$ LD_LIBRARY_PATH=${PWD} LD_PRELINK=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext​:${PWD}/t ./perl -e '$beg = time;
($beguser, $begsys, $begcuser, $begcsys) = times;
while (($now = time) == $beg) { sleep 1 }

print time, " ", $now, " ", $beg, "\n";
my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
  for my $j (1..1000) { ++$x; }; # burn some user cycles
  ($nowuser, $nowsys, $nowcuser, $nowcsys ) = times;
  $i = 2_000_000 if (($nowuser+$nowcuser) > ($beguser+$begcuser)) && ( ($nowsys+$nowcsys) >= ($begsys+$begcsys) ||
  (!($nowsys+$nowcsys) && !($begsys+$nowcsys)));
  last if time - $beg > 20;
}

print $i," ", $beguser+$begcuser, " ", $begsys + $begcsys, " ",$nowuser+$nowcuser, " ", $nowsys+$nowcsys, " [", join(" ",times),"]\n";'

1491786835 1491786835 1491786834
559601 0 0 0 19.04 [0 19.04 0 0]

$

Note the test would still fail :

ok($i >= 2_000_000, 'very basic times test');

since $i is 559601 .

I guess under Linux 4.10.9 , it is no longer
possible to measure any CPU user-time with :
  for my $j (1..1000) { ++$x; }; # burn some user cycles
could it be that something is noticing this loop
has no effect ($x is not used) and so is not entering it ?

Anyway, on my system, NO user CPU cycles are measured ,
so the expression :

$i = 2_000_000 if $nowuser > $beguser && ( $nowsys >= $begsys ||
  (!$nowsys && !$begsys));

is never true.

Perhaps this should be something like​:

$i = 2_000_000 if (($nowuser + $nowcuser + $beguser + $begcuser) > 0) ||
  ($nowsys + $nowcsys + $begsys + $begcsys) > 0 )
  ) ;

??

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From [Unknown Contact. See original ticket]

On Sun, 09 Apr 2017 16​:35​:34 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 11​:15​:37 -0700, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:54​:53 GMT, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:03​:35 GMT, jvdias wrote​:

This is a bug report for perl from jason.vas.dias@​gmail.com,
generated with the help of perlbug 1.40 running under perl
5.24.1.

-----------------------------------------------------------------
[Please describe your issue here]

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful
Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee
make.test.log
...
t/run/switches
................................................
#
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp17019C\"​:
(null)\n'
# expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
FAILED at test 9
...
t/op/taint
....................................................
#
Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732
...
t/op/time
.....................................................
#
Failed test 2 - very basic times test at op/time.t line 33
FAILED at test 2
...
cpan/ExtUtils-Install/t/Installed
.............................
#
Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files() would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files() would,
again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3
/usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report
intermediate
dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56
...
dist/autouse/t/autouse
........................................
#
Failed test 'Function imported via 'autouse' performs as
expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3
...
dist/constant/t/constant
......................................
#
Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31
...
dist/Time-HiRes/t/itimer
......................................
t/itimer.t​: overall time allowed for tests (360s)
exceeded!
FAILED--expected 2 tests, saw 1

The process was stuck doing (shown by strace of it) :

getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000}, it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
lib/Benchmark
.................................................
^- I didn't wait for this test to complete - it was also
hanging,
doing, as disclosed by strace :

times({tms_utime=4, tms_stime=46582, tms_cutime=0, tms_cstime=0})

430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

The only major difference in configuration between 5.22.1, which
passed its test suite,
and 5.24.1, which did not, was that I answered 'Yes' to using
PerlIO
/ 'Fast stdio' .

This is going to be difficult for us to diagnose without more
information. You indicate that when configuring perl-5.24.1, you
answered 'Yes' to one question to which, in perl-5.22.1, you
answered
'No'. But that doesn't tell us how you answered all the *other*
questions during manual configuration.

For example, the output of 'perl -V' you attached shows no
'config_args' but does show 'useithreads=define', suggesting you
answered Yes to "Build a threading Perl? [n]". If I download a
tarball of perl-5.24.1 and start to configure manually, I have to
know
how to answer each of the questions as a prerequisite to further
diagnose.

If you know how you want to configure Perl, can you give us that
description in regular words? We could then translate that into
the
particular set of arguments to Configure that meet your objective
and
get all tests to PASS.

Thank you very much.
Jim Keenan

After unwrapping a perl-5.24.1 tarball, I configured with this
command​:

#####
sh ./Configure -des -Dusethreads -Accflags='-g -fPIC
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' \
-Dusefaststdio
#####

This was my guess at what your configuration would have looked like
if
done non-interactively -- with two exceptions​:

1. I was running as myself, not as root. (And I confess I don't know
why you would do this as root.)

2. I did not include '-Duseshrplib'. (When I did include '-
Duseshrplib' I got errors in 4 of the test files you cited.)

All tests PASSed. Content of './perl -Ilib -V' attached.

So my hunch is that those two differences just mentioned are the
source of your test failures.

Thank you very much.
Jim Keenan

Thanks very much for your response, James -

I did attach a copy of my config.sh to the mail, which didn't get
attached to this bug - attaching now .

I built linux 4.10.9, and rebuilt perl with the -Dusefaststdio option
- building
without it made no difference - tests still fail in same places.
Maybe suspect glibc-2.25 ?

I need the -Duseshrplib option. Could it be, after all this time, that
the test suite STILL needs the LD_PRELINK=${PWD}/libperl.so
environment
variable setting ?

I am re-running tests as non-root user, with :
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} make test 2>&1
|
tee make.test.dev.2.log

and the config.sh as attached. Same tests are still failing .
I think there is something about Linux 4.10+ / glibc-2.25+
that perl does not like. Previous perl 5.22.1 was built with
linux 4.8 (I think) & glibc-2.23? - over a year ago .
Have you tested on Linux 4.10+ under glibc 2.25+ ?
I am using binutils-2.28 .

I will investigate further and find out exactly why all the
timer / times() + constants tests fail tomorrow.

Thanks & Regards,
Jason

Aha ! there is a problem on my system with times() -

RE​: t/op/time.t -

The test that fails is :

$ LD_LIBRARY_PATH=${PWD} \
  LD_PRELINK=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD} /ext​:${PWD}/t ./perl -e '$beg = time;
($beguser, $begsys) = times;
while (($now = time) == $beg) { sleep 1 }

# ok($now > $beg && $now - $beg < 10, 'very basic time test');
print time, " ", $now, " ", $beg, "\n";

my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
  for my $j (1..1000) { ++$x; }; # burn some user cycles
  ($nowuser, $nowsys) = times;
  $i = 2_000_000 if $nowuser > $beguser &&
  ( $nowsys >= $begsys ||
  (!$nowsys && !$begsys));
  last if time - $beg > 20;
}

print $beguser, " ", $begsys, " ", join(" ",times),"\n";
'
1491785650 1491785650 1491785649
0 0 0 19.5 0 0
$

ie. Linux / glibc is returning FOUR elements for times() -
see :
  http​://man7.org/linux/man-pages/man2/times.2.html :
"
  The struct tms is as defined in <sys/times.h>​:

  struct tms {
  clock_t tms_utime; /* user time */
  clock_t tms_stime; /* system time */
  clock_t tms_cutime; /* user time of children */
  clock_t tms_cstime; /* system time of children */
  };
"
 
So the expression​:
  $(beguser, $begsys) = times;

would set $begsys to the remainder of the list ?

Confirmed by doing :
$ LD_LIBRARY_PATH=${PWD} LD_PRELINK=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext​:${PWD}/t ./perl -e '$beg = time;
($beguser, $begsys, $begcuser, $begcsys) = times;
while (($now = time) == $beg) { sleep 1 }

print time, " ", $now, " ", $beg, "\n";
my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
  for my $j (1..1000) { ++$x; }; # burn some user cycles
  ($nowuser, $nowsys, $nowcuser, $nowcsys ) = times;
  $i = 2_000_000 if (($nowuser+$nowcuser) > ($beguser+$begcuser)) && ( ($nowsys+$nowcsys) >= ($begsys+$begcsys) ||
  (!($nowsys+$nowcsys) && !($begsys+$nowcsys)));
  last if time - $beg > 20;
}

print $i," ", $beguser+$begcuser, " ", $begsys + $begcsys, " ",$nowuser+$nowcuser, " ", $nowsys+$nowcsys, " [", join(" ",times),"]\n";'

1491786835 1491786835 1491786834
559601 0 0 0 19.04 [0 19.04 0 0]

$

Note the test would still fail :

ok($i >= 2_000_000, 'very basic times test');

since $i is 559601 .

I guess under Linux 4.10.9 , it is no longer
possible to measure any CPU user-time with :
  for my $j (1..1000) { ++$x; }; # burn some user cycles
could it be that something is noticing this loop
has no effect ($x is not used) and so is not entering it ?

Anyway, on my system, NO user CPU cycles are measured ,
so the expression :

$i = 2_000_000 if $nowuser > $beguser && ( $nowsys >= $begsys ||
  (!$nowsys && !$begsys));

is never true.

Perhaps this should be something like​:

$i = 2_000_000 if (($nowuser + $nowcuser + $beguser + $begcuser) > 0) ||
  ($nowsys + $nowcsys + $begsys + $begcsys) > 0 )
  ) ;

??

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @JVD66

On Sun, 09 Apr 2017 18​:23​:18 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 16​:35​:34 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 11​:15​:37 -0700, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:54​:53 GMT, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:03​:35 GMT, jvdias wrote​:

This is a bug report for perl from jason.vas.dias@​gmail.com,
generated with the help of perlbug 1.40 running under perl
5.24.1.

-----------------------------------------------------------------
[Please describe your issue here]

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful
Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee
make.test.log
...
t/run/switches
................................................
#
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp17019C\"​:
(null)\n'
# expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
FAILED at test 9
...
t/op/taint
....................................................
#
Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732
...
t/op/time
.....................................................
#
Failed test 2 - very basic times test at op/time.t line 33
FAILED at test 2
...
cpan/ExtUtils-Install/t/Installed
.............................
#
Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files()
would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files()
would,
again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3
/usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report
intermediate
dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56
...
dist/autouse/t/autouse
........................................
#
Failed test 'Function imported via 'autouse' performs as
expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3
...
dist/constant/t/constant
......................................
#
Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31
...
dist/Time-HiRes/t/itimer
......................................
t/itimer.t​: overall time allowed for tests (360s)
exceeded!
FAILED--expected 2 tests, saw 1

The process was stuck doing (shown by strace of it) :

getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
lib/Benchmark
.................................................
^- I didn't wait for this test to complete - it was also
hanging,
doing, as disclosed by strace :

times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0})

430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

The only major difference in configuration between 5.22.1,
which
passed its test suite,
and 5.24.1, which did not, was that I answered 'Yes' to using
PerlIO
/ 'Fast stdio' .

This is going to be difficult for us to diagnose without more
information. You indicate that when configuring perl-5.24.1, you
answered 'Yes' to one question to which, in perl-5.22.1, you
answered
'No'. But that doesn't tell us how you answered all the *other*
questions during manual configuration.

For example, the output of 'perl -V' you attached shows no
'config_args' but does show 'useithreads=define', suggesting you
answered Yes to "Build a threading Perl? [n]". If I download a
tarball of perl-5.24.1 and start to configure manually, I have to
know
how to answer each of the questions as a prerequisite to further
diagnose.

If you know how you want to configure Perl, can you give us that
description in regular words? We could then translate that into
the
particular set of arguments to Configure that meet your objective
and
get all tests to PASS.

Thank you very much.
Jim Keenan

After unwrapping a perl-5.24.1 tarball, I configured with this
command​:

#####
sh ./Configure -des -Dusethreads -Accflags='-g -fPIC
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' \
-Dusefaststdio
#####

This was my guess at what your configuration would have looked like
if
done non-interactively -- with two exceptions​:

1. I was running as myself, not as root. (And I confess I don't
know
why you would do this as root.)

2. I did not include '-Duseshrplib'. (When I did include '-
Duseshrplib' I got errors in 4 of the test files you cited.)

All tests PASSed. Content of './perl -Ilib -V' attached.

So my hunch is that those two differences just mentioned are the
source of your test failures.

Thank you very much.
Jim Keenan

Thanks very much for your response, James -

I did attach a copy of my config.sh to the mail, which didn't get
attached to this bug - attaching now .

I built linux 4.10.9, and rebuilt perl with the -Dusefaststdio option
- building
without it made no difference - tests still fail in same places.
Maybe suspect glibc-2.25 ?

I need the -Duseshrplib option. Could it be, after all this time,
that
the test suite STILL needs the LD_PRELINK=${PWD}/libperl.so
environment
variable setting ?

I am re-running tests as non-root user, with :
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} make test
2>&1
|
tee make.test.dev.2.log

and the config.sh as attached. Same tests are still failing .
I think there is something about Linux 4.10+ / glibc-2.25+
that perl does not like. Previous perl 5.22.1 was built with
linux 4.8 (I think) & glibc-2.23? - over a year ago .
Have you tested on Linux 4.10+ under glibc 2.25+ ?
I am using binutils-2.28 .

I will investigate further and find out exactly why all the
timer / times() + constants tests fail tomorrow.

Thanks & Regards,
Jason

Aha ! there is a problem on my system with times() -

RE​: t/op/time.t -

The test that fails is :

$ LD_LIBRARY_PATH=${PWD} \
LD_PRELINK=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD} /ext​:${PWD}/t
./perl -e '$beg = time;
($beguser, $begsys) = times;
while (($now = time) == $beg) { sleep 1 }

# ok($now > $beg && $now - $beg < 10, 'very basic time
test');
print time, " ", $now, " ", $beg, "\n";

my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
for my $j (1..1000) { ++$x; }; # burn some user cycles
($nowuser, $nowsys) = times;
$i = 2_000_000 if $nowuser > $beguser &&
( $nowsys >= $begsys ||
(!$nowsys && !$begsys));
last if time - $beg > 20;
}

print $beguser, " ", $begsys, " ", join(" ",times),"\n";
'
1491785650 1491785650 1491785649
0 0 0 19.5 0 0
$

ie. Linux / glibc is returning FOUR elements for times() -
see :
http​://man7.org/linux/man-pages/man2/times.2.html :
"
The struct tms is as defined in <sys/times.h>​:

struct tms {
clock_t tms_utime; /* user time */
clock_t tms_stime; /* system time */
clock_t tms_cutime; /* user time of children */
clock_t tms_cstime; /* system time of children */
};
"

So the expression​:
$(beguser, $begsys) = times;

would set $begsys to the remainder of the list ?

Confirmed by doing :
$ LD_LIBRARY_PATH=${PWD} LD_PRELINK=${PWD}
PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext​:${PWD}/t ./perl -e '$beg = time;
($beguser, $begsys, $begcuser, $begcsys) = times;
while (($now = time) == $beg) { sleep 1 }

print time, " ", $now, " ", $beg, "\n";
my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
for my $j (1..1000) { ++$x; }; # burn some user cycles
($nowuser, $nowsys, $nowcuser, $nowcsys ) = times;
$i = 2_000_000 if (($nowuser+$nowcuser) > ($beguser+$begcuser)) &&
( ($nowsys+$nowcsys) >= ($begsys+$begcsys) ||
(!($nowsys+$nowcsys) &&
!($begsys+$nowcsys)));
last if time - $beg > 20;
}

print $i," ", $beguser+$begcuser, " ", $begsys + $begcsys, "
",$nowuser+$nowcuser, " ", $nowsys+$nowcsys, " [", join("
",times),"]\n";'

1491786835 1491786835 1491786834
559601 0 0 0 19.04 [0 19.04 0 0]

$

Note the test would still fail :

ok($i >= 2_000_000, 'very basic times test');

since $i is 559601 .

I guess under Linux 4.10.9 , it is no longer
possible to measure any CPU user-time with :
for my $j (1..1000) { ++$x; }; # burn some user cycles
could it be that something is noticing this loop
has no effect ($x is not used) and so is not entering it ?

Anyway, on my system, NO user CPU cycles are measured ,
so the expression :

$i = 2_000_000 if $nowuser > $beguser && ( $nowsys >= $begsys ||
(!$nowsys && !$begsys));

is never true.

Perhaps this should be something like​:

$i = 2_000_000 if (($nowuser + $nowcuser + $beguser + $begcuser) > 0)
||
($nowsys + $nowcsys + $begsys + $begcsys) > 0 )
) ;

??

I think on modern Linux, times() is becoming less and less accurate.
The modern (supported?) way of reading the process CPU clock cycle usage is​:
 
 
  int cid=0;
  struct timespec ts;
  if( (0 == clock_getcpuclockid(getpid(), &cid))
  &&(0 == clock_gettime(cid, &ts)
  )
  return // number of CPU nanoseconds used by all threads in process​:
  ( (((unsigned long long)ts.tv_sec) * 1000000000ULL)
  + ts.tv_nsec
  ) ;
  }

Linux is becoming less and less real time capable as time progresses -
languages such as PERL need to remove support for real-time features on
Linux to keep up with it .

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From [Unknown Contact. See original ticket]

On Sun, 09 Apr 2017 18​:23​:18 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 16​:35​:34 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 11​:15​:37 -0700, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:54​:53 GMT, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:03​:35 GMT, jvdias wrote​:

This is a bug report for perl from jason.vas.dias@​gmail.com,
generated with the help of perlbug 1.40 running under perl
5.24.1.

-----------------------------------------------------------------
[Please describe your issue here]

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful
Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee
make.test.log
...
t/run/switches
................................................
#
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp17019C\"​:
(null)\n'
# expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
FAILED at test 9
...
t/op/taint
....................................................
#
Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732
...
t/op/time
.....................................................
#
Failed test 2 - very basic times test at op/time.t line 33
FAILED at test 2
...
cpan/ExtUtils-Install/t/Installed
.............................
#
Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files()
would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files()
would,
again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3
/usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report
intermediate
dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56
...
dist/autouse/t/autouse
........................................
#
Failed test 'Function imported via 'autouse' performs as
expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3
...
dist/constant/t/constant
......................................
#
Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31
...
dist/Time-HiRes/t/itimer
......................................
t/itimer.t​: overall time allowed for tests (360s)
exceeded!
FAILED--expected 2 tests, saw 1

The process was stuck doing (shown by strace of it) :

getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
lib/Benchmark
.................................................
^- I didn't wait for this test to complete - it was also
hanging,
doing, as disclosed by strace :

times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0})

430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

The only major difference in configuration between 5.22.1,
which
passed its test suite,
and 5.24.1, which did not, was that I answered 'Yes' to using
PerlIO
/ 'Fast stdio' .

This is going to be difficult for us to diagnose without more
information. You indicate that when configuring perl-5.24.1, you
answered 'Yes' to one question to which, in perl-5.22.1, you
answered
'No'. But that doesn't tell us how you answered all the *other*
questions during manual configuration.

For example, the output of 'perl -V' you attached shows no
'config_args' but does show 'useithreads=define', suggesting you
answered Yes to "Build a threading Perl? [n]". If I download a
tarball of perl-5.24.1 and start to configure manually, I have to
know
how to answer each of the questions as a prerequisite to further
diagnose.

If you know how you want to configure Perl, can you give us that
description in regular words? We could then translate that into
the
particular set of arguments to Configure that meet your objective
and
get all tests to PASS.

Thank you very much.
Jim Keenan

After unwrapping a perl-5.24.1 tarball, I configured with this
command​:

#####
sh ./Configure -des -Dusethreads -Accflags='-g -fPIC
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' \
-Dusefaststdio
#####

This was my guess at what your configuration would have looked like
if
done non-interactively -- with two exceptions​:

1. I was running as myself, not as root. (And I confess I don't
know
why you would do this as root.)

2. I did not include '-Duseshrplib'. (When I did include '-
Duseshrplib' I got errors in 4 of the test files you cited.)

All tests PASSed. Content of './perl -Ilib -V' attached.

So my hunch is that those two differences just mentioned are the
source of your test failures.

Thank you very much.
Jim Keenan

Thanks very much for your response, James -

I did attach a copy of my config.sh to the mail, which didn't get
attached to this bug - attaching now .

I built linux 4.10.9, and rebuilt perl with the -Dusefaststdio option
- building
without it made no difference - tests still fail in same places.
Maybe suspect glibc-2.25 ?

I need the -Duseshrplib option. Could it be, after all this time,
that
the test suite STILL needs the LD_PRELINK=${PWD}/libperl.so
environment
variable setting ?

I am re-running tests as non-root user, with :
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} make test
2>&1
|
tee make.test.dev.2.log

and the config.sh as attached. Same tests are still failing .
I think there is something about Linux 4.10+ / glibc-2.25+
that perl does not like. Previous perl 5.22.1 was built with
linux 4.8 (I think) & glibc-2.23? - over a year ago .
Have you tested on Linux 4.10+ under glibc 2.25+ ?
I am using binutils-2.28 .

I will investigate further and find out exactly why all the
timer / times() + constants tests fail tomorrow.

Thanks & Regards,
Jason

Aha ! there is a problem on my system with times() -

RE​: t/op/time.t -

The test that fails is :

$ LD_LIBRARY_PATH=${PWD} \
LD_PRELINK=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD} /ext​:${PWD}/t
./perl -e '$beg = time;
($beguser, $begsys) = times;
while (($now = time) == $beg) { sleep 1 }

# ok($now > $beg && $now - $beg < 10, 'very basic time
test');
print time, " ", $now, " ", $beg, "\n";

my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
for my $j (1..1000) { ++$x; }; # burn some user cycles
($nowuser, $nowsys) = times;
$i = 2_000_000 if $nowuser > $beguser &&
( $nowsys >= $begsys ||
(!$nowsys && !$begsys));
last if time - $beg > 20;
}

print $beguser, " ", $begsys, " ", join(" ",times),"\n";
'
1491785650 1491785650 1491785649
0 0 0 19.5 0 0
$

ie. Linux / glibc is returning FOUR elements for times() -
see :
http​://man7.org/linux/man-pages/man2/times.2.html :
"
The struct tms is as defined in <sys/times.h>​:

struct tms {
clock_t tms_utime; /* user time */
clock_t tms_stime; /* system time */
clock_t tms_cutime; /* user time of children */
clock_t tms_cstime; /* system time of children */
};
"

So the expression​:
$(beguser, $begsys) = times;

would set $begsys to the remainder of the list ?

Confirmed by doing :
$ LD_LIBRARY_PATH=${PWD} LD_PRELINK=${PWD}
PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext​:${PWD}/t ./perl -e '$beg = time;
($beguser, $begsys, $begcuser, $begcsys) = times;
while (($now = time) == $beg) { sleep 1 }

print time, " ", $now, " ", $beg, "\n";
my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
for my $j (1..1000) { ++$x; }; # burn some user cycles
($nowuser, $nowsys, $nowcuser, $nowcsys ) = times;
$i = 2_000_000 if (($nowuser+$nowcuser) > ($beguser+$begcuser)) &&
( ($nowsys+$nowcsys) >= ($begsys+$begcsys) ||
(!($nowsys+$nowcsys) &&
!($begsys+$nowcsys)));
last if time - $beg > 20;
}

print $i," ", $beguser+$begcuser, " ", $begsys + $begcsys, "
",$nowuser+$nowcuser, " ", $nowsys+$nowcsys, " [", join("
",times),"]\n";'

1491786835 1491786835 1491786834
559601 0 0 0 19.04 [0 19.04 0 0]

$

Note the test would still fail :

ok($i >= 2_000_000, 'very basic times test');

since $i is 559601 .

I guess under Linux 4.10.9 , it is no longer
possible to measure any CPU user-time with :
for my $j (1..1000) { ++$x; }; # burn some user cycles
could it be that something is noticing this loop
has no effect ($x is not used) and so is not entering it ?

Anyway, on my system, NO user CPU cycles are measured ,
so the expression :

$i = 2_000_000 if $nowuser > $beguser && ( $nowsys >= $begsys ||
(!$nowsys && !$begsys));

is never true.

Perhaps this should be something like​:

$i = 2_000_000 if (($nowuser + $nowcuser + $beguser + $begcuser) > 0)
||
($nowsys + $nowcsys + $begsys + $begcsys) > 0 )
) ;

??

I think on modern Linux, times() is becoming less and less accurate.
The modern (supported?) way of reading the process CPU clock cycle usage is​:
 
 
  int cid=0;
  struct timespec ts;
  if( (0 == clock_getcpuclockid(getpid(), &cid))
  &&(0 == clock_gettime(cid, &ts)
  )
  return // number of CPU nanoseconds used by all threads in process​:
  ( (((unsigned long long)ts.tv_sec) * 1000000000ULL)
  + ts.tv_nsec
  ) ;
  }

Linux is becoming less and less real time capable as time progresses -
languages such as PERL need to remove support for real-time features on
Linux to keep up with it .

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @jkeenan

On Mon, 10 Apr 2017 01​:43​:51 GMT, jvdias wrote​:

On Sun, 09 Apr 2017 18​:23​:18 -0700, jvdias wrote​:
[snip]

I guess under Linux 4.10.9 , it is no longer
possible to measure any CPU user-time with :
for my $j (1..1000) { ++$x; }; # burn some user cycles
could it be that something is noticing this loop
has no effect ($x is not used) and so is not entering it ?

Anyway, on my system, NO user CPU cycles are measured ,
so the expression :

$i = 2_000_000 if $nowuser > $beguser && ( $nowsys >= $begsys ||
(!$nowsys && !$begsys));

is never true.

Perhaps this should be something like​:

$i = 2_000_000 if (($nowuser + $nowcuser + $beguser + $begcuser) > 0)
||
($nowsys + $nowcsys + $begsys + $begcsys) > 0 )
) ;

??

I think on modern Linux, times() is becoming less and less accurate.
The modern (supported?) way of reading the process CPU clock cycle usage is​:

int cid=0;
struct timespec ts;
if\( \(0 == clock\_getcpuclockid\(getpid\(\)\, &cid\)\)
  &&\(0 == clock\_gettime\(cid\, &ts\)
  \) 
  return // number of CPU nanoseconds used by all threads in process&#8203;: 
  \( \(\(\(unsigned long long\)ts\.tv\_sec\) \* 1000000000ULL\)
    \+ ts\.tv\_nsec
  \) ;   
\}

Linux is becoming less and less real time capable as time progresses -
languages such as PERL need to remove support for real-time features on
Linux to keep up with it .

P5P List​: Is there anyone who could start providing smoke tests for Linux 4.10.9?

Linux 4.9.11 is the highest version I could find at http​://perl5.test-smoke.org/search.

Thank you very much.

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

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @jkeenan

On Sun, 09 Apr 2017 23​:35​:34 GMT, jvdias wrote​:

I built linux 4.10.9, and rebuilt perl with the -Dusefaststdio option
- building
without it made no difference - tests still fail in same places.
Maybe suspect glibc-2.25 ?

I need the -Duseshrplib option. Could it be, after all this time, that
the test suite STILL needs the LD_PRELINK=${PWD}/libperl.so
environment
variable setting ?

I know little about -Duseshrplib, so other readers will have to help you out on that.

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

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @JVD66

On Sun, 09 Apr 2017 18​:43​:51 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 18​:23​:18 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 16​:35​:34 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 11​:15​:37 -0700, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:54​:53 GMT, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:03​:35 GMT, jvdias wrote​:

This is a bug report for perl from jason.vas.dias@​gmail.com,
generated with the help of perlbug 1.40 running under perl
5.24.1.

-----------------------------------------------------------------
[Please describe your issue here]

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful
Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee
make.test.log
...
t/run/switches
................................................
#
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp17019C\"​:
(null)\n'
# expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
FAILED at test 9
...
t/op/taint
....................................................
#
Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732
...
t/op/time
.....................................................
#
Failed test 2 - very basic times test at op/time.t line 33
FAILED at test 2
...
cpan/ExtUtils-Install/t/Installed
.............................
#
Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files()
would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files()
would,
again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3
/usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report
intermediate
dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56
...
dist/autouse/t/autouse
........................................
#
Failed test 'Function imported via 'autouse' performs as
expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3
...
dist/constant/t/constant
......................................
#
Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31
...
dist/Time-HiRes/t/itimer
......................................
t/itimer.t​: overall time allowed for tests (360s)
exceeded!
FAILED--expected 2 tests, saw 1

The process was stuck doing (shown by strace of it) :

getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
lib/Benchmark
.................................................
^- I didn't wait for this test to complete - it was also
hanging,
doing, as disclosed by strace :

times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0})

430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

The only major difference in configuration between 5.22.1,
which
passed its test suite,
and 5.24.1, which did not, was that I answered 'Yes' to using
PerlIO
/ 'Fast stdio' .

This is going to be difficult for us to diagnose without more
information. You indicate that when configuring perl-5.24.1, you
answered 'Yes' to one question to which, in perl-5.22.1, you
answered
'No'. But that doesn't tell us how you answered all the *other*
questions during manual configuration.

For example, the output of 'perl -V' you attached shows no
'config_args' but does show 'useithreads=define', suggesting you
answered Yes to "Build a threading Perl? [n]". If I download a
tarball of perl-5.24.1 and start to configure manually, I have to
know
how to answer each of the questions as a prerequisite to further
diagnose.

If you know how you want to configure Perl, can you give us that
description in regular words? We could then translate that into
the
particular set of arguments to Configure that meet your objective
and
get all tests to PASS.

Thank you very much.
Jim Keenan

After unwrapping a perl-5.24.1 tarball, I configured with this
command​:

#####
sh ./Configure -des -Dusethreads -Accflags='-g -fPIC
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' \
-Dusefaststdio
#####

This was my guess at what your configuration would have looked like
if
done non-interactively -- with two exceptions​:

1. I was running as myself, not as root. (And I confess I don't
know
why you would do this as root.)

2. I did not include '-Duseshrplib'. (When I did include '-
Duseshrplib' I got errors in 4 of the test files you cited.)

All tests PASSed. Content of './perl -Ilib -V' attached.

So my hunch is that those two differences just mentioned are the
source of your test failures.

Thank you very much.
Jim Keenan

Thanks very much for your response, James -

I did attach a copy of my config.sh to the mail, which didn't get
attached to this bug - attaching now .

I built linux 4.10.9, and rebuilt perl with the -Dusefaststdio option
- building
without it made no difference - tests still fail in same places.
Maybe suspect glibc-2.25 ?

I need the -Duseshrplib option. Could it be, after all this time,
that
the test suite STILL needs the LD_PRELINK=${PWD}/libperl.so
environment
variable setting ?

I am re-running tests as non-root user, with :
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} make test
2>&1
|
tee make.test.dev.2.log

and the config.sh as attached. Same tests are still failing .
I think there is something about Linux 4.10+ / glibc-2.25+
that perl does not like. Previous perl 5.22.1 was built with
linux 4.8 (I think) & glibc-2.23? - over a year ago .
Have you tested on Linux 4.10+ under glibc 2.25+ ?
I am using binutils-2.28 .

I will investigate further and find out exactly why all the
timer / times() + constants tests fail tomorrow.

Thanks & Regards,
Jason

Aha ! there is a problem on my system with times() -

RE​: t/op/time.t -

The test that fails is :

$ LD_LIBRARY_PATH=${PWD} \
LD_PRELINK=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD} /ext​:${PWD}/t
./perl -e '$beg = time;
($beguser, $begsys) = times;
while (($now = time) == $beg) { sleep 1 }

# ok($now > $beg && $now - $beg < 10, 'very basic time
test');
print time, " ", $now, " ", $beg, "\n";

my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
for my $j (1..1000) { ++$x; }; # burn some user cycles
($nowuser, $nowsys) = times;
$i = 2_000_000 if $nowuser > $beguser &&
( $nowsys >= $begsys ||
(!$nowsys && !$begsys));
last if time - $beg > 20;
}

print $beguser, " ", $begsys, " ", join(" ",times),"\n";
'
1491785650 1491785650 1491785649
0 0 0 19.5 0 0
$

ie. Linux / glibc is returning FOUR elements for times() -
see :
http​://man7.org/linux/man-pages/man2/times.2.html :
"
The struct tms is as defined in <sys/times.h>​:

struct tms {
clock_t tms_utime; /* user time */
clock_t tms_stime; /* system time */
clock_t tms_cutime; /* user time of children */
clock_t tms_cstime; /* system time of children */
};
"

So the expression​:
$(beguser, $begsys) = times;

would set $begsys to the remainder of the list ?

Confirmed by doing :
$ LD_LIBRARY_PATH=${PWD} LD_PRELINK=${PWD}
PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext​:${PWD}/t ./perl -e '$beg = time;
($beguser, $begsys, $begcuser, $begcsys) = times;
while (($now = time) == $beg) { sleep 1 }

print time, " ", $now, " ", $beg, "\n";
my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
for my $j (1..1000) { ++$x; }; # burn some user cycles
($nowuser, $nowsys, $nowcuser, $nowcsys ) = times;
$i = 2_000_000 if (($nowuser+$nowcuser) > ($beguser+$begcuser)) &&
( ($nowsys+$nowcsys) >= ($begsys+$begcsys) ||
(!($nowsys+$nowcsys) &&
!($begsys+$nowcsys)));
last if time - $beg > 20;
}

print $i," ", $beguser+$begcuser, " ", $begsys + $begcsys, "
",$nowuser+$nowcuser, " ", $nowsys+$nowcsys, " [", join("
",times),"]\n";'

1491786835 1491786835 1491786834
559601 0 0 0 19.04 [0 19.04 0 0]

$

Note the test would still fail :

ok($i >= 2_000_000, 'very basic times test');

since $i is 559601 .

I guess under Linux 4.10.9 , it is no longer
possible to measure any CPU user-time with :
for my $j (1..1000) { ++$x; }; # burn some user cycles
could it be that something is noticing this loop
has no effect ($x is not used) and so is not entering it ?

Anyway, on my system, NO user CPU cycles are measured ,
so the expression :

$i = 2_000_000 if $nowuser > $beguser && ( $nowsys >= $begsys ||
(!$nowsys && !$begsys));

is never true.

Perhaps this should be something like​:

$i = 2_000_000 if (($nowuser + $nowcuser + $beguser + $begcuser) > 0)
||
($nowsys + $nowcsys + $begsys + $begcsys) > 0 )
) ;

??

I think on modern Linux, times() is becoming less and less accurate.
The modern (supported?) way of reading the process CPU clock cycle usage is​:

int cid=0;
struct timespec ts;
if\( \(0 == clock\_getcpuclockid\(getpid\(\)\, &cid\)\)
  &&\(0 == clock\_gettime\(cid\, &ts\)
  \) 
  return // number of CPU nanoseconds used by all threads in process&#8203;: 
  \( \(\(\(unsigned long long\)ts\.tv\_sec\) \* 1000000000ULL\)
    \+ ts\.tv\_nsec
  \) ;   
\}

Linux is becoming less and less real time capable as time progresses -
languages such as PERL need to remove support for real-time features on
Linux to keep up with it .

Fix for times issues is this patch :

Inline Patch
--- pp_sys.c~	2016-07-14 19:08:08.000000000 +0000
+++ pp_sys.c	2017-04-10 02:42:37.169810362 +0000
@@ -4651,0 +4652,4 @@
+#if defined(__linux__)
+#include <linux/version.h>
+#endif
+
@@ -4657 +4661,3 @@
-
+#if (defined(__linux__) && ( (LINUX_VERSION_CODE >> 16) >= 4 ))    
+    struct timespec ts;
+#endif    
@@ -4660 +4666,8 @@
-
+    
+#if (defined(__linux__) && ( (LINUX_VERSION_CODE >> 16) >= 4 ))
+    /* Linux's times() no longer measures accurate user CPU time */
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts );
+    timesbuf.tms_utime = (ts.tv_sec * PL_clocktick) +
+        (ts.tv_nsec / ( 1000000000 / PL_clocktick) );
+#endif
+    

All other tests that failed above (except time.t or Benchmark.t)
are still failing.

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @JVD66

pp_sys.patch
--- pp_sys.c~	2016-07-14 19:08:08.000000000 +0000
+++ pp_sys.c	2017-04-10 02:42:37.169810362 +0000
@@ -4651,0 +4652,4 @@
+#if defined(__linux__)
+#include <linux/version.h>
+#endif
+
@@ -4657 +4661,3 @@
-
+#if (defined(__linux__) && ( (LINUX_VERSION_CODE >> 16) >= 4 ))    
+    struct timespec ts;
+#endif    
@@ -4660 +4666,8 @@
-
+    
+#if (defined(__linux__) && ( (LINUX_VERSION_CODE >> 16) >= 4 ))
+    /* Linux's times() no longer measures accurate user CPU time */
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts );
+    timesbuf.tms_utime = (ts.tv_sec * PL_clocktick) +
+        (ts.tv_nsec / ( 1000000000 / PL_clocktick) );
+#endif
+    

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From [Unknown Contact. See original ticket]

On Sun, 09 Apr 2017 18​:43​:51 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 18​:23​:18 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 16​:35​:34 -0700, jvdias wrote​:

On Sun, 09 Apr 2017 11​:15​:37 -0700, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:54​:53 GMT, jkeenan wrote​:

On Sun, 09 Apr 2017 16​:03​:35 GMT, jvdias wrote​:

This is a bug report for perl from jason.vas.dias@​gmail.com,
generated with the help of perlbug 1.40 running under perl
5.24.1.

-----------------------------------------------------------------
[Please describe your issue here]

The PERL 5.24.1 I am using for this bug report failed its test
suite, and will not be used to replace my existing PERL 5.22.1
until I can explain why .

If these test failures have been seen before / are expected /
known not to indicate problems, please let me know -

excerpts from the make.test.log file produced after successful
Configure and
build, showing each failed test, with​:

$ make -j4 2>&1 | tee make.log && make test 2>&1 | tee
make.test.log
...
t/run/switches
................................................
#
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp17019C\"​:
(null)\n'
# expected /(?^s​:Can't open perl script.*tmp17019C.*21)/
FAILED at test 9
...
t/op/taint
....................................................
#
Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732
...
t/op/time
.....................................................
#
Failed test 2 - very basic times test at op/time.t line 33
FAILED at test 2
...
cpan/ExtUtils-Install/t/Installed
.............................
#
Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files()
would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files()
would,
again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3
/usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report
intermediate
dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56
...
dist/autouse/t/autouse
........................................
#
Failed test 'Function imported via 'autouse' performs as
expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3
...
dist/constant/t/constant
......................................
#
Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31
...
dist/Time-HiRes/t/itimer
......................................
t/itimer.t​: overall time allowed for tests (360s)
exceeded!
FAILED--expected 2 tests, saw 1

The process was stuck doing (shown by strace of it) :

getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0,
490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0
getitimer(ITIMER_VIRTUAL, {it_interval={0, 400000},
it_value={0, 490041}}) = 0

...
lib/Benchmark
.................................................
^- I didn't wait for this test to complete - it was also
hanging,
doing, as disclosed by strace :

times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0})

430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075
times({tms_utime=4, tms_stime=46582, tms_cutime=0,
tms_cstime=0}) = 430811075

The only major difference in configuration between 5.22.1,
which
passed its test suite,
and 5.24.1, which did not, was that I answered 'Yes' to using
PerlIO
/ 'Fast stdio' .

This is going to be difficult for us to diagnose without more
information. You indicate that when configuring perl-5.24.1, you
answered 'Yes' to one question to which, in perl-5.22.1, you
answered
'No'. But that doesn't tell us how you answered all the *other*
questions during manual configuration.

For example, the output of 'perl -V' you attached shows no
'config_args' but does show 'useithreads=define', suggesting you
answered Yes to "Build a threading Perl? [n]". If I download a
tarball of perl-5.24.1 and start to configure manually, I have to
know
how to answer each of the questions as a prerequisite to further
diagnose.

If you know how you want to configure Perl, can you give us that
description in regular words? We could then translate that into
the
particular set of arguments to Configure that meet your objective
and
get all tests to PASS.

Thank you very much.
Jim Keenan

After unwrapping a perl-5.24.1 tarball, I configured with this
command​:

#####
sh ./Configure -des -Dusethreads -Accflags='-g -fPIC
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' \
-Dusefaststdio
#####

This was my guess at what your configuration would have looked like
if
done non-interactively -- with two exceptions​:

1. I was running as myself, not as root. (And I confess I don't
know
why you would do this as root.)

2. I did not include '-Duseshrplib'. (When I did include '-
Duseshrplib' I got errors in 4 of the test files you cited.)

All tests PASSed. Content of './perl -Ilib -V' attached.

So my hunch is that those two differences just mentioned are the
source of your test failures.

Thank you very much.
Jim Keenan

Thanks very much for your response, James -

I did attach a copy of my config.sh to the mail, which didn't get
attached to this bug - attaching now .

I built linux 4.10.9, and rebuilt perl with the -Dusefaststdio option
- building
without it made no difference - tests still fail in same places.
Maybe suspect glibc-2.25 ?

I need the -Duseshrplib option. Could it be, after all this time,
that
the test suite STILL needs the LD_PRELINK=${PWD}/libperl.so
environment
variable setting ?

I am re-running tests as non-root user, with :
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} make test
2>&1
|
tee make.test.dev.2.log

and the config.sh as attached. Same tests are still failing .
I think there is something about Linux 4.10+ / glibc-2.25+
that perl does not like. Previous perl 5.22.1 was built with
linux 4.8 (I think) & glibc-2.23? - over a year ago .
Have you tested on Linux 4.10+ under glibc 2.25+ ?
I am using binutils-2.28 .

I will investigate further and find out exactly why all the
timer / times() + constants tests fail tomorrow.

Thanks & Regards,
Jason

Aha ! there is a problem on my system with times() -

RE​: t/op/time.t -

The test that fails is :

$ LD_LIBRARY_PATH=${PWD} \
LD_PRELINK=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD} /ext​:${PWD}/t
./perl -e '$beg = time;
($beguser, $begsys) = times;
while (($now = time) == $beg) { sleep 1 }

# ok($now > $beg && $now - $beg < 10, 'very basic time
test');
print time, " ", $now, " ", $beg, "\n";

my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
for my $j (1..1000) { ++$x; }; # burn some user cycles
($nowuser, $nowsys) = times;
$i = 2_000_000 if $nowuser > $beguser &&
( $nowsys >= $begsys ||
(!$nowsys && !$begsys));
last if time - $beg > 20;
}

print $beguser, " ", $begsys, " ", join(" ",times),"\n";
'
1491785650 1491785650 1491785649
0 0 0 19.5 0 0
$

ie. Linux / glibc is returning FOUR elements for times() -
see :
http​://man7.org/linux/man-pages/man2/times.2.html :
"
The struct tms is as defined in <sys/times.h>​:

struct tms {
clock_t tms_utime; /* user time */
clock_t tms_stime; /* system time */
clock_t tms_cutime; /* user time of children */
clock_t tms_cstime; /* system time of children */
};
"

So the expression​:
$(beguser, $begsys) = times;

would set $begsys to the remainder of the list ?

Confirmed by doing :
$ LD_LIBRARY_PATH=${PWD} LD_PRELINK=${PWD}
PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext​:${PWD}/t ./perl -e '$beg = time;
($beguser, $begsys, $begcuser, $begcsys) = times;
while (($now = time) == $beg) { sleep 1 }

print time, " ", $now, " ", $beg, "\n";
my $x = "aaaa";
for ($i = 0; $i < 1_000_000; $i++) {
for my $j (1..1000) { ++$x; }; # burn some user cycles
($nowuser, $nowsys, $nowcuser, $nowcsys ) = times;
$i = 2_000_000 if (($nowuser+$nowcuser) > ($beguser+$begcuser)) &&
( ($nowsys+$nowcsys) >= ($begsys+$begcsys) ||
(!($nowsys+$nowcsys) &&
!($begsys+$nowcsys)));
last if time - $beg > 20;
}

print $i," ", $beguser+$begcuser, " ", $begsys + $begcsys, "
",$nowuser+$nowcuser, " ", $nowsys+$nowcsys, " [", join("
",times),"]\n";'

1491786835 1491786835 1491786834
559601 0 0 0 19.04 [0 19.04 0 0]

$

Note the test would still fail :

ok($i >= 2_000_000, 'very basic times test');

since $i is 559601 .

I guess under Linux 4.10.9 , it is no longer
possible to measure any CPU user-time with :
for my $j (1..1000) { ++$x; }; # burn some user cycles
could it be that something is noticing this loop
has no effect ($x is not used) and so is not entering it ?

Anyway, on my system, NO user CPU cycles are measured ,
so the expression :

$i = 2_000_000 if $nowuser > $beguser && ( $nowsys >= $begsys ||
(!$nowsys && !$begsys));

is never true.

Perhaps this should be something like​:

$i = 2_000_000 if (($nowuser + $nowcuser + $beguser + $begcuser) > 0)
||
($nowsys + $nowcsys + $begsys + $begcsys) > 0 )
) ;

??

I think on modern Linux, times() is becoming less and less accurate.
The modern (supported?) way of reading the process CPU clock cycle usage is​:

int cid=0;
struct timespec ts;
if\( \(0 == clock\_getcpuclockid\(getpid\(\)\, &cid\)\)
  &&\(0 == clock\_gettime\(cid\, &ts\)
  \) 
  return // number of CPU nanoseconds used by all threads in process&#8203;: 
  \( \(\(\(unsigned long long\)ts\.tv\_sec\) \* 1000000000ULL\)
    \+ ts\.tv\_nsec
  \) ;   
\}

Linux is becoming less and less real time capable as time progresses -
languages such as PERL need to remove support for real-time features on
Linux to keep up with it .

Fix for times issues is this patch :

Inline Patch
--- pp_sys.c~	2016-07-14 19:08:08.000000000 +0000
+++ pp_sys.c	2017-04-10 02:42:37.169810362 +0000
@@ -4651,0 +4652,4 @@
+#if defined(__linux__)
+#include <linux/version.h>
+#endif
+
@@ -4657 +4661,3 @@
-
+#if (defined(__linux__) && ( (LINUX_VERSION_CODE >> 16) >= 4 ))    
+    struct timespec ts;
+#endif    
@@ -4660 +4666,8 @@
-
+    
+#if (defined(__linux__) && ( (LINUX_VERSION_CODE >> 16) >= 4 ))
+    /* Linux's times() no longer measures accurate user CPU time */
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts );
+    timesbuf.tms_utime = (ts.tv_sec * PL_clocktick) +
+        (ts.tv_nsec / ( 1000000000 / PL_clocktick) );
+#endif
+    

All other tests that failed above (except time.t or Benchmark.t)
are still failing.

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @iabyn

On Sun, Apr 09, 2017 at 06​:43​:52PM -0700, Jason Vas Dias via RT wrote​:

I think on modern Linux, times() is becoming less and less accurate.
The modern (supported?) way of reading the process CPU clock cycle usage is​:

int cid=0;
struct timespec ts;
if\( \(0 == clock\_getcpuclockid\(getpid\(\)\, &cid\)\)
  &&\(0 == clock\_gettime\(cid\, &ts\)
  \) 
  return // number of CPU nanoseconds used by all threads in process&#8203;: 
  \( \(\(\(unsigned long long\)ts\.tv\_sec\) \* 1000000000ULL\)
    \+ ts\.tv\_nsec
  \) ;   
\}

Linux is becoming less and less real time capable as time progresses -
languages such as PERL need to remove support for real-time features on
Linux to keep up with it .

Do you have any indications that times() returning garbage is new intended
behaviour for newer kernels? Perhaps it is an unintended bug somewhere?

I would be *extremely* reluctant to include code in perl that is
dependent on the linux kernel version. For one thing its extra code to
maintain, and secondly, a perl binary may be compiled on one platform
then run on another platform with a different kernel version.

Can you compile and run the following little program to confirm whether
the times() system call is doing something strange on your platform.
(If necessary adjust the i or j top-level values to make the process run
for several seconds.)

  #include <stdio.h>
  #include <sys/times.h>

  int main(int argc, char**argv)
  {
  struct tms t0, t1;
  int i, j;
  times(&t0);
  for (i=0; i<1; i++) {
  for (j=0; j<0x7fffffff; j++) {
  }
  }
  times(&t1);
  printf("user=%ld, sys=%ld\n",
  t1.tms_utime - t0.tms_utime,
  t1.tms_stime - t0.tms_stime
  );
  }

On my platform I see​:

$ make c
cc c.c -o c
$ time ./c
user=416, sys=0

real 0m4.168s
user 0m4.166s
sys 0m0.001s

--
Please note that ash-trays are provided for the use of smokers,
whereas the floor is provided for the use of all patrons.
  -- Bill Royston

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @JVD66

On Mon, 10 Apr 2017 01​:41​:59 -0700, davem wrote​:

On Sun, Apr 09, 2017 at 06​:43​:52PM -0700, Jason Vas Dias via RT wrote​:

I think on modern Linux, times() is becoming less and less accurate.
The modern (supported?) way of reading the process CPU clock cycle
usage is​:

int cid=0;
struct timespec ts;
if( (0 == clock_getcpuclockid(getpid(), &cid))
&&(0 == clock_gettime(cid, &ts)
)
return // number of CPU nanoseconds used by all threads in
process​:
( (((unsigned long long)ts.tv_sec) * 1000000000ULL)
+ ts.tv_nsec
) ;
}

Linux is becoming less and less real time capable as time progresses
-
languages such as PERL need to remove support for real-time features
on
Linux to keep up with it .

Do you have any indications that times() returning garbage is new
intended
behaviour for newer kernels? Perhaps it is an unintended bug
somewhere?

I would be *extremely* reluctant to include code in perl that is
dependent on the linux kernel version. For one thing its extra code to
maintain, and secondly, a perl binary may be compiled on one platform
then run on another platform with a different kernel version.

Can you compile and run the following little program to confirm
whether
the times() system call is doing something strange on your platform.
(If necessary adjust the i or j top-level values to make the process
run
for several seconds.)

#include <stdio.h>
#include <sys/times.h>

int main(int argc, char**argv)
{
struct tms t0, t1;
int i, j;
times(&t0);
for (i=0; i<1; i++) {
for (j=0; j<0x7fffffff; j++) {
}
}
times(&t1);
printf("user=%ld, sys=%ld\n",
t1.tms_utime - t0.tms_utime,
t1.tms_stime - t0.tms_stime
);
}

On my platform I see​:

$ make c
cc c.c -o c
$ time ./c
user=416, sys=0

real 0m4.168s
user 0m4.166s
sys 0m0.001s

Thanks for responding, Dave!

Yes, something is very strange about Linux 4.10+ 's
recording of user CPU time. I built & ran your test
program with the following results​:

$ gcc -o times1 times1.c
$ ./times1
user=0, sys=352

This took a noticeable time to complete - @​ 3.52 seconds -
352 centiseconds ( sysconf(_SC_CLK_TCK) is hardwired to 100 ) ,
yet NO user CPU time is recorded.

Getting out my trusty bash built-in high-res timer which
does a getrusage(2) :

$ . /lib64/bash-4.3.42\(9\)-release_loadables/load.sh
$ time_hi_res ./times1
user=0, sys=348
[./times1
[elapsed]=3.500779 [cpu%]=99.51 [sys]=3.483663 [user]=0.000000 [rss]=4648 [csw]=1 [vcsw]=29 [fltmaj]=0 [fltmin]=63 [inblk]=0 [outblk]=0 [exit]=0
]

So even getrusage does not record ANY user CPU time .

One explanation might be that improved branch prediction in Linux kernel
realizes that the loop​:

  for (i=0; i<1; i++)
  { for (j=0; j<0x7fffffff; j++);
  }

has no effect because 'j' is never used; indeed the compiler might realize that
the loop can be replaced with the expression 'j = 0x7fffffff;' .

But it does look like a linux bug ; NO 'user' CPU cycles are being recorded
anywhere, and all processes get the SAME system time (stime) value​:

$ ps -e -o 'pid=' -o 'ppid=' -o 'utime=' -o 'stime=' -o 'etimes=' -o 'psr=' -o 'state='
  1 0 - 14​:53 1855 5 S
  2 0 - 14​:53 1855 7 S
  4 2 - 14​:53 1855 0 S
  6 2 - 14​:53 1855 0 S
  7 2 - 14​:53 1855 0 S
  8 2 - 14​:53 1855 5 S
  9 2 - 14​:53 1855 0 S
  10 2 - 14​:53 1855 1 S
...

EVERY process in the system has '-' (0) utime and the SAME 'stime' ,
with linux 4.10.0 or linux 4.10.9 (unmodified). It is probably
some kernel mis-configuration issue .

I'll re-examine all process accounting kernel CONFIG_ items - but I
haven't changed any of them (intentionally) - they should be
at the same defaults I was using under Linux 4.8 .

Thanks to perl test suite for opening my eyes to this issue !

Will report back when kernel issue is resolved .

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @JVD66

The times() issue was due to me mistakenly enabling the kernel .config :

CONFIG_VIRT_CPU_ACCOUNTING=y
# CONFIG_TICK_CPU_ACCOUNTING is not set

CONFIG_VIRT_CPU_ACCOUNTING is not a complete feature yet.

Sorry !

But it still doesn't explain other test failures like :

t/run/switches ................................................ # Failed test 9 - RT \#61362​: Cannot syntax-check a directory at run/switches.t line 128
# got 'Can\'t open perl script \"tmp28769C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp28769C.*21)/
FAILED at test 9

t/op/taint .................................................... # Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732

This happens when running tests as non-root user now​:
cpan/autodie/t/chmod .......................................... # Failed test 'We can chmod ourselves just fine.'
# at t/chmod.t line 20.
# Failed test 'Confirm autodie on a 'true' chown failure.'
# at t/chmod.t line 24.
# got​: '0'
# expected​: '1'
# Looks like you failed 2 tests of 7.
FAILED at test 5
cpan/autodie/t/chown .......................................... # Failed test 'Can chown ourselves just fine.'
# at t/chown.t line 24.
# Failed test 'Confirm we're dying on a 'true' chown failure.'
# at t/chown.t line 28.
# got​: '0'
# expected​: '1'
# Looks like you failed 2 tests of 4.
FAILED at test 2

cpan/autodie/t/utime .......................................... Can't utime('1491789341', '1491779964', '/usr/build/linux/perl-5.24.1/cpan/autodie/t/touch_me')​: 1 at t/utime.t line 24
# Looks like your test exited with 1 just after 4.
FAILED--non-zero wait status​: 256

cpan/ExtUtils-Install/t/Installed ............................. # Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files() would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files() would, again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3 /usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report intermediate dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56

dist/autouse/t/autouse ........................................ # Failed test 'Function imported via 'autouse' performs as expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3

dist/constant/t/constant ...................................... # Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31

None of these tests fail when run under perl 5.22.1, which I am keeping till I can
get a newer release of PERL to pass its test suite.

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From [Unknown Contact. See original ticket]

The times() issue was due to me mistakenly enabling the kernel .config :

CONFIG_VIRT_CPU_ACCOUNTING=y
# CONFIG_TICK_CPU_ACCOUNTING is not set

CONFIG_VIRT_CPU_ACCOUNTING is not a complete feature yet.

Sorry !

But it still doesn't explain other test failures like :

t/run/switches ................................................ # Failed test 9 - RT \#61362​: Cannot syntax-check a directory at run/switches.t line 128
# got 'Can\'t open perl script \"tmp28769C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp28769C.*21)/
FAILED at test 9

t/op/taint .................................................... # Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732

This happens when running tests as non-root user now​:
cpan/autodie/t/chmod .......................................... # Failed test 'We can chmod ourselves just fine.'
# at t/chmod.t line 20.
# Failed test 'Confirm autodie on a 'true' chown failure.'
# at t/chmod.t line 24.
# got​: '0'
# expected​: '1'
# Looks like you failed 2 tests of 7.
FAILED at test 5
cpan/autodie/t/chown .......................................... # Failed test 'Can chown ourselves just fine.'
# at t/chown.t line 24.
# Failed test 'Confirm we're dying on a 'true' chown failure.'
# at t/chown.t line 28.
# got​: '0'
# expected​: '1'
# Looks like you failed 2 tests of 4.
FAILED at test 2

cpan/autodie/t/utime .......................................... Can't utime('1491789341', '1491779964', '/usr/build/linux/perl-5.24.1/cpan/autodie/t/touch_me')​: 1 at t/utime.t line 24
# Looks like your test exited with 1 just after 4.
FAILED--non-zero wait status​: 256

cpan/ExtUtils-Install/t/Installed ............................. # Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files() would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files() would, again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3 /usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report intermediate dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56

dist/autouse/t/autouse ........................................ # Failed test 'Function imported via 'autouse' performs as expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3

dist/constant/t/constant ...................................... # Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31

None of these tests fail when run under perl 5.22.1, which I am keeping till I can
get a newer release of PERL to pass its test suite.

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @JVD66

OK, I rebuilt the kernel with CONFIG_TICK_CPU_ACCOUNTING defined and
CONFIG_VIRT_CPU_ACCOUNTING_GEN NOT defined .

times() and itimers now work as expected.

But the remaining test failures still persist, when run either as root
or as non-root user (running as root permits more tests to succeed, since
I built perl as root)​:

t/run/switches ................................................ # Failed test 9 - RT \#61362​: Cannot syntax-check a directory at run/switches.t line 128
# got 'Can\'t open perl script \"tmp6139C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp6139C.*21)/
FAILED at test 9

t/op/taint .................................................... # Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732

cpan/ExtUtils-Install/t/Installed ............................. # Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files() would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files() would, again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3 /usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report intermediate dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56

dist/autouse/t/autouse ........................................ # Failed test 'Function imported via 'autouse' performs as expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3

dist/constant/t/constant ...................................... # Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From [Unknown Contact. See original ticket]

OK, I rebuilt the kernel with CONFIG_TICK_CPU_ACCOUNTING defined and
CONFIG_VIRT_CPU_ACCOUNTING_GEN NOT defined .

times() and itimers now work as expected.

But the remaining test failures still persist, when run either as root
or as non-root user (running as root permits more tests to succeed, since
I built perl as root)​:

t/run/switches ................................................ # Failed test 9 - RT \#61362​: Cannot syntax-check a directory at run/switches.t line 128
# got 'Can\'t open perl script \"tmp6139C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp6139C.*21)/
FAILED at test 9

t/op/taint .................................................... # Failed test 732 - tainted $! at op/taint.t line 2060
# got '2'
# expected !~ /(?^​:^\d+$)/
FAILED at test 732

cpan/ExtUtils-Install/t/Installed ............................. # Failed test '... should find doc file under given dir'
# at t/Installed.t line 267.
# got​: '2'
# expected​: '1'
# Failed test '... should find all files files() would'
# at t/Installed.t line 292.
# got​: '1'
# expected​: '2'
# Failed test '... should find all files files() would, again'
# at t/Installed.t line 295.
# got​: '3'
# expected​: '4'
# Failed test '... should sort output'
# at t/Installed.t line 297.
# got​: '. /usr /usr/share/man/man3 /usr/share/man/man3'
# expected​: '. /usr /usr/share/man/man3'
# Failed test 'directory_tree() should report intermediate dirs to those requested'
# at t/Installed.t line 309.
# got​: '2'
# expected​: '3'
# Looks like you failed 5 tests of 73.
FAILED at test 56

dist/autouse/t/autouse ........................................ # Failed test 'Function imported via 'autouse' performs as expected'
# at t/autouse.t line 32.
# Looks like you failed 1 test of 15.
FAILED at test 3

dist/constant/t/constant ...................................... # Failed test at t/constant.t line 99.
# '1'
# >
# '6'
# Looks like you failed 1 test of 109.
FAILED at test 31

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @JVD66

OK, here is my attempt to fix each issue​:

1. t/run/switches ................................................ # Failed test 9 - RT \#61362​: Cannot syntax-check a directory at run/switches.t line 128
# got 'Can\'t open perl script \"tmp6139C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp6139C.*21)/
FAILED at test 9

The code that fails is equivalent to this perl script, which I created in
the perl 5.24.1 build directory​:

<quote><pre>
BEGIN { require "./t/test.pl"; require "./t/loc_tools.pl"; }
use Config;
use Errno;
$ENV{'LC_ALL'} = 'C';
$ENV{LANGUAGE} = 'C';
setlocale(LC_ALL, "C");
my $tempdir=tempfile;
mkdir $tempdir, 0700 or die "Can't mkdir '$tempdir'​: $!";
my $rp = runperl( switches => [ '-c' ], args => [ $tempdir ], stderr => 1);
print STDERR "\nerror is​: $error rp is​: $rp !​:'$!' ?​:'$?'\n";
rmdir $tempdir;
</pre></quote>

$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} \
  PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext ./perl test_fail.pl

error is​: rp is​: Can't open perl script "tmp9540B"​: (null)
!​:'' ?​:'6400'

$ echo $((6400>>8))
25

$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} \
  PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext strace -f ./perl test_fail.pl
...
[pid 8860] ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
[pid 8860] lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 8860] ioctl(1, TCGETS, 0x7ffd922d1a20) = -1 ENOTTY (Inappropriate ioctl for device)
[pid 8860] lseek(1, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 8860] ioctl(2, TCGETS, 0x7ffd922d1a30) = -1 ENOTTY (Inappropriate ioctl for device)
[pid 8860] lseek(2, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 8860] open("tmp8858B", O_RDONLY) = 3
[pid 8860] ioctl(3, TCGETS, 0x7ffd922d1b30) = -1 ENOTTY (Inappropriate ioctl for device)
[pid 8860] lseek(3, 0, SEEK_CUR) = 0
[pid 8860] fcntl(3, F_SETFD, FD_CLOEXEC) = 0
[pid 8860] fstat(3, {st_mode=S_IFDIR|0700, st_size=0, ...}) = 0
[pid 8860] write(2, "Can't open perl script \"tmp8858B"..., 42 <unfinished ...>
...
[pid 8860] close(3) = 0
[pid 8860] exit_group(25) = ?
[pid 8860] +++ exited with 25 +++

So perl 5.24.1 , when given a directory to run, actually exits with status 25 : ENOTTY ,
since it is unable to ioctl FDs 1,2 or 3 in this case ; perl 5.22.1 does lookup
the right error message (EISDIR : 21), but still exits with code 25​:

this is 5.22.1​:
$ perl /tmp
Can't open perl script "/tmp"​: Is a directory
$ echo $?
25

the newly built 5.24.1​:
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext LANG=C LC_ALL=C \
./perl /tmp
Can't open perl script "/tmp"​: (null)
$ echo $?
25

I think the actual point of RT #61362 has not been fixed​:
when given an invalid script file, perl still is exiting
with the wrong code (25) from the errno set by ioctl({1,2,3},...) ,
not an error indicating the problem with the script file.

And it is a regression that perl 5.24.1 cannot print the
correct error message, while 5.22.1 can .

This does not appear to be a minor issue,
but is due to the expression :

utils.c​:
1795 die_unwind(ex);

being able to unpack the arguments, given to Perl_vcroak() .
which DO include the correct string, with this patch to perl.c​:

$ diff -U1 perl.c~ perl.c

Inline Patch
--- perl.c~	2017-01-02 17:27:54.000000000 +0000
+++ perl.c	2017-04-10 22:40:07.740195693 +0000
@@ -3861,3 +3861,3 @@
             CopFILE(PL_curcop),
-            Strerror(EISDIR));
+            Strerror(errno=EISDIR));

That patch makes perl exit with 21 (EISDIR) instead of 25 (ENOTTY) in the test case\, but\, having verified with GDB that the string is passed to Perl\_vcroak\, it appears the croak mechanism in 5\.24\.1 is fundamentally broken wrt 5\.22\.1 \- 5\.24\.1's die\_unwind\_ex\(\) is unable to retrieve the arguments\, while 5\.22\.1's die\_unwind\_ex\(\) can \.

My fix would be to back out any changes made to the die_unwind_ex
code to make it identical to that of 5.22.1 - I might as well keep
using 5.22.1 until this issue is fixed.

Nice that the test suite picked up this disastrous fault in the croak mechanism!
Not nice that perl's croak mechanism has regressed.

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From [Unknown Contact. See original ticket]

OK, here is my attempt to fix each issue​:

1. t/run/switches ................................................ # Failed test 9 - RT \#61362​: Cannot syntax-check a directory at run/switches.t line 128
# got 'Can\'t open perl script \"tmp6139C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp6139C.*21)/
FAILED at test 9

The code that fails is equivalent to this perl script, which I created in
the perl 5.24.1 build directory​:

<quote><pre>
BEGIN { require "./t/test.pl"; require "./t/loc_tools.pl"; }
use Config;
use Errno;
$ENV{'LC_ALL'} = 'C';
$ENV{LANGUAGE} = 'C';
setlocale(LC_ALL, "C");
my $tempdir=tempfile;
mkdir $tempdir, 0700 or die "Can't mkdir '$tempdir'​: $!";
my $rp = runperl( switches => [ '-c' ], args => [ $tempdir ], stderr => 1);
print STDERR "\nerror is​: $error rp is​: $rp !​:'$!' ?​:'$?'\n";
rmdir $tempdir;
</pre></quote>

$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} \
  PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext ./perl test_fail.pl

error is​: rp is​: Can't open perl script "tmp9540B"​: (null)
!​:'' ?​:'6400'

$ echo $((6400>>8))
25

$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} \
  PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext strace -f ./perl test_fail.pl
...
[pid 8860] ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
[pid 8860] lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 8860] ioctl(1, TCGETS, 0x7ffd922d1a20) = -1 ENOTTY (Inappropriate ioctl for device)
[pid 8860] lseek(1, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 8860] ioctl(2, TCGETS, 0x7ffd922d1a30) = -1 ENOTTY (Inappropriate ioctl for device)
[pid 8860] lseek(2, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 8860] open("tmp8858B", O_RDONLY) = 3
[pid 8860] ioctl(3, TCGETS, 0x7ffd922d1b30) = -1 ENOTTY (Inappropriate ioctl for device)
[pid 8860] lseek(3, 0, SEEK_CUR) = 0
[pid 8860] fcntl(3, F_SETFD, FD_CLOEXEC) = 0
[pid 8860] fstat(3, {st_mode=S_IFDIR|0700, st_size=0, ...}) = 0
[pid 8860] write(2, "Can't open perl script \"tmp8858B"..., 42 <unfinished ...>
...
[pid 8860] close(3) = 0
[pid 8860] exit_group(25) = ?
[pid 8860] +++ exited with 25 +++

So perl 5.24.1 , when given a directory to run, actually exits with status 25 : ENOTTY ,
since it is unable to ioctl FDs 1,2 or 3 in this case ; perl 5.22.1 does lookup
the right error message (EISDIR : 21), but still exits with code 25​:

this is 5.22.1​:
$ perl /tmp
Can't open perl script "/tmp"​: Is a directory
$ echo $?
25

the newly built 5.24.1​:
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext LANG=C LC_ALL=C \
./perl /tmp
Can't open perl script "/tmp"​: (null)
$ echo $?
25

I think the actual point of RT #61362 has not been fixed​:
when given an invalid script file, perl still is exiting
with the wrong code (25) from the errno set by ioctl({1,2,3},...) ,
not an error indicating the problem with the script file.

And it is a regression that perl 5.24.1 cannot print the
correct error message, while 5.22.1 can .

This does not appear to be a minor issue,
but is due to the expression :

utils.c​:
1795 die_unwind(ex);

being able to unpack the arguments, given to Perl_vcroak() .
which DO include the correct string, with this patch to perl.c​:

$ diff -U1 perl.c~ perl.c

Inline Patch
--- perl.c~	2017-01-02 17:27:54.000000000 +0000
+++ perl.c	2017-04-10 22:40:07.740195693 +0000
@@ -3861,3 +3861,3 @@
             CopFILE(PL_curcop),
-            Strerror(EISDIR));
+            Strerror(errno=EISDIR));

That patch makes perl exit with 21 (EISDIR) instead of 25 (ENOTTY) in the test case\, but\, having verified with GDB that the string is passed to Perl\_vcroak\, it appears the croak mechanism in 5\.24\.1 is fundamentally broken wrt 5\.22\.1 \- 5\.24\.1's die\_unwind\_ex\(\) is unable to retrieve the arguments\, while 5\.22\.1's die\_unwind\_ex\(\) can \.

My fix would be to back out any changes made to the die_unwind_ex
code to make it identical to that of 5.22.1 - I might as well keep
using 5.22.1 until this issue is fixed.

Nice that the test suite picked up this disastrous fault in the croak mechanism!
Not nice that perl's croak mechanism has regressed.

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2017

From @jkeenan

On Mon, 10 Apr 2017 23​:00​:51 GMT, jvdias wrote​:

OK, here is my attempt to fix each issue​:

1. t/run/switches ................................................ #
Failed test 9 - RT \#61362​: Cannot syntax-check a directory at
run/switches.t line 128
# got 'Can\'t open perl script \"tmp6139C\"​: (null)\n'
# expected /(?^s​:Can't open perl script.*tmp6139C.*21)/
FAILED at test 9

The code that fails is equivalent to this perl script, which I created
in
the perl 5.24.1 build directory​:

<quote><pre>
BEGIN { require "./t/test.pl"; require "./t/loc_tools.pl"; }
use Config;
use Errno;
$ENV{'LC_ALL'} = 'C';
$ENV{LANGUAGE} = 'C';
setlocale(LC_ALL, "C");
my $tempdir=tempfile;
mkdir $tempdir, 0700 or die "Can't mkdir '$tempdir'​: $!";
my $rp = runperl( switches => [ '-c' ], args => [ $tempdir ], stderr
=> 1);
print STDERR "\nerror is​: $error rp is​: $rp !​:'$!' ?​:'$?'\n";
rmdir $tempdir;
</pre></quote>

$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} \
PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext ./perl test_fail.pl

error is​: rp is​: Can't open perl script "tmp9540B"​: (null)
!​:'' ?​:'6400'

$ echo $((6400>>8))
25

$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} \
PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext strace -f ./perl test_fail.pl
...
[pid 8860] ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
[pid 8860] lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 8860] ioctl(1, TCGETS, 0x7ffd922d1a20) = -1 ENOTTY
(Inappropriate ioctl for device)
[pid 8860] lseek(1, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 8860] ioctl(2, TCGETS, 0x7ffd922d1a30) = -1 ENOTTY
(Inappropriate ioctl for device)
[pid 8860] lseek(2, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 8860] open("tmp8858B", O_RDONLY) = 3
[pid 8860] ioctl(3, TCGETS, 0x7ffd922d1b30) = -1 ENOTTY
(Inappropriate ioctl for device)
[pid 8860] lseek(3, 0, SEEK_CUR) = 0
[pid 8860] fcntl(3, F_SETFD, FD_CLOEXEC) = 0
[pid 8860] fstat(3, {st_mode=S_IFDIR|0700, st_size=0, ...}) = 0
[pid 8860] write(2, "Can't open perl script \"tmp8858B"..., 42
<unfinished ...>
...
[pid 8860] close(3) = 0
[pid 8860] exit_group(25) = ?
[pid 8860] +++ exited with 25 +++

So perl 5.24.1 , when given a directory to run, actually exits with
status 25 : ENOTTY ,
since it is unable to ioctl FDs 1,2 or 3 in this case ; perl 5.22.1
does lookup
the right error message (EISDIR : 21), but still exits with code 25​:

this is 5.22.1​:
$ perl /tmp
Can't open perl script "/tmp"​: Is a directory
$ echo $?
25

the newly built 5.24.1​:
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD}
PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext LANG=C LC_ALL=C \
./perl /tmp
Can't open perl script "/tmp"​: (null)
$ echo $?
25

I think the actual point of RT #61362 has not been fixed​:
when given an invalid script file, perl still is exiting
with the wrong code (25) from the errno set by ioctl({1,2,3},...) ,
not an error indicating the problem with the script file.

And it is a regression that perl 5.24.1 cannot print the
correct error message, while 5.22.1 can .

This does not appear to be a minor issue,
but is due to the expression :

utils.c​:
1795 die_unwind(ex);

being able to unpack the arguments, given to Perl_vcroak() .
which DO include the correct string, with this patch to perl.c​:

$ diff -U1 perl.c~ perl.c
--- perl.c~ 2017-01-02 17​:27​:54.000000000 +0000
+++ perl.c 2017-04-10 22​:40​:07.740195693 +0000
@​@​ -3861,3 +3861,3 @​@​
CopFILE(PL_curcop),
- Strerror(EISDIR));
+ Strerror(errno=EISDIR));

That patch makes perl exit with 21 (EISDIR) instead of 25 (ENOTTY) in
the test case, but, having verified with GDB that the string is passed
to Perl_vcroak, it appears the croak mechanism in 5.24.1 is
fundamentally
broken wrt 5.22.1 -
5.24.1's die_unwind_ex() is unable to retrieve the arguments, while
5.22.1's die_unwind_ex() can .

My fix would be to back out any changes made to the die_unwind_ex
code to make it identical to that of 5.22.1 - I might as well keep
using 5.22.1 until this issue is fixed.

Nice that the test suite picked up this disastrous fault in the croak
mechanism!
Not nice that perl's croak mechanism has regressed.

Can you supply the output of perl -V for these perl builds?

Also, did you configure interactively, or did you supply command-line options to ./Configure? The latter would be particularly helpful to us in attempting to reproduce your problems.

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From @iabyn

On Mon, Apr 10, 2017 at 04​:00​:51PM -0700, Jason Vas Dias via RT wrote​:

So perl 5.24.1 , when given a directory to run, actually exits with status 25 : ENOTTY ,
since it is unable to ioctl FDs 1,2 or 3 in this case ; perl 5.22.1 does lookup
the right error message (EISDIR : 21), but still exits with code 25​:

this is 5.22.1​:
$ perl /tmp
Can't open perl script "/tmp"​: Is a directory
$ echo $?
25

the newly built 5.24.1​:
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext LANG=C LC_ALL=C \
./perl /tmp
Can't open perl script "/tmp"​: (null)
$ echo $?
25

I think the actual point of RT #61362 has not been fixed​:
when given an invalid script file, perl still is exiting
with the wrong code (25) from the errno set by ioctl({1,2,3},...) ,
not an error indicating the problem with the script file.

And it is a regression that perl 5.24.1 cannot print the
correct error message, while 5.22.1 can .

If I understand you correctly, there are two separate issues here.

The first is that the fix for "perl /a_directory" is incomplete; although
it now croaks, the process's exit code is still wrong. This is present in
both 5.22.x and 5.24.x. It is fixed by your suggested patch​:

- Strerror(EISDIR));
+ Strerror(errno=EISDIR));

Is my understanding correct?

The second issue is that while perl5.22.x correctly gives an error message​:

  $ perl5220 /tmp
  Can't open perl script "/tmp"​: Is a directory

a regression in 5.24.x means that it now gives​:

  $ perl5241 /tmp
  Can't open perl script "/tmp"​: (null)

And, if I understand correctly, the Strerror(errno=EISDIR)) change doesn't
fix that.

A really important thing to point out is that this is only happening for
you. For me, I get​:

  $ perl5241 /tmp; echo $?
  Can't open perl script "/tmp"​: Is a directory

and indeed the test which has been failing you, has passed thousands of
times on many different smoking platforms with multiple configurations. We
don't generally release new versions of perl with known test fails. So

it appears the croak mechanism in 5.24.1 is fundamentally
broken wrt 5.22.1 -

seems a bit of an over-statement.

It seems far more likely that there is something up with the return value
of Strerr() in this function call​:

  Perl_croak(aTHX_ "Can't open perl script \"%s\"​: %s\n",
  CopFILE(PL_curcop),
  Strerror(EISDIR));

On my system, the last arg passed to croak() is a pointer the string
"Is a directory". On your system I'm guessing that Strerror(EISDIR)
is returning "(null)".

What Strerror is #defined to depends on what Configure finds in the way
of strerror() and sys_errlist[] on your system. On my system I get​:

  $ egrep 'strerror|syserrlst|strerrm' config.sh
  d_gai_strerror='define'
  d_strerrm='strerror(e)'
  d_strerror='define'
  d_strerror_l='define'
  d_strerror_r='define'
  d_syserrlst='define'
  strerror_r_proto='REENTRANT_PROTO_B_IBW'

Are you absolutely certain that on your platform, at the point that
Perl_croak is called, it's last argument is correct a string pointer, but
by the time Perl_sv_vcatpvfn_flags() is called to concatenate the args
using the format string, that pointer has become null?

The "Is a directory" pointer is retrieved on the second execution of this
line​: sv.c​:11889​:

  Perl_sv_vcatpvfn_flags(....)
  {
  ....
  case 's'​:
  if (vectorize)
  goto unknown;
  if (args) {
====> eptr = va_arg(*args, char*);

At this point all that has happened is that Perl_croak() has passed its
args on to to vcroak() which has passed its args to vmess() which creates
a new temp SV and passes its args to sv_vsetpvfn(), which sets the SV to
"" and then passes it and the args to Perl_sv_vcatpvfn_flags(). If the
pointer (or the text it points to) changes during that time, then
something very strange is going on.

Nice that the test suite picked up this disastrous fault in the croak mechanism!

Its not disastrous.

Not nice that perl's croak mechanism has regressed.

I doubt that it has regressed. I think its more likely that something
weird about your platform is triggering an obscure issue.

--
The crew of the Enterprise encounter an alien life form which is
surprisingly neither humanoid nor made from pure energy.
  -- Things That Never Happen in "Star Trek" #22

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From @jkeenan

On Tue, 11 Apr 2017 10​:24​:55 GMT, davem wrote​:

On Mon, Apr 10, 2017 at 04​:00​:51PM -0700, Jason Vas Dias via RT wrote​:

So perl 5.24.1 , when given a directory to run, actually exits with
status 25 : ENOTTY ,
since it is unable to ioctl FDs 1,2 or 3 in this case ; perl 5.22.1
does lookup
the right error message (EISDIR : 21), but still exits with code 25​:

this is 5.22.1​:
$ perl /tmp
Can't open perl script "/tmp"​: Is a directory
$ echo $?
25

the newly built 5.24.1​:
$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD}
PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext LANG=C LC_ALL=C \
./perl /tmp
Can't open perl script "/tmp"​: (null)
$ echo $?
25

I think the actual point of RT #61362 has not been fixed​:
when given an invalid script file, perl still is exiting
with the wrong code (25) from the errno set by ioctl({1,2,3},...) ,
not an error indicating the problem with the script file.

And it is a regression that perl 5.24.1 cannot print the
correct error message, while 5.22.1 can .

If I understand you correctly, there are two separate issues here.

The first is that the fix for "perl /a_directory" is incomplete;
although
it now croaks, the process's exit code is still wrong. This is present
in
both 5.22.x and 5.24.x. It is fixed by your suggested patch​:

- Strerror(EISDIR));
+ Strerror(errno=EISDIR));

Is my understanding correct?

The second issue is that while perl5.22.x correctly gives an error
message​:

$ perl5220 /tmp
Can't open perl script "/tmp"​: Is a directory

a regression in 5.24.x means that it now gives​:

$ perl5241 /tmp
Can't open perl script "/tmp"​: (null)

And, if I understand correctly, the Strerror(errno=EISDIR)) change
doesn't
fix that.

A really important thing to point out is that this is only happening
for
you. For me, I get​:

$ perl5241 /tmp; echo $?
Can't open perl script "/tmp"​: Is a directory

and indeed the test which has been failing you, has passed thousands
of
times on many different smoking platforms with multiple
configurations. We
don't generally release new versions of perl with known test fails. So

it appears the croak mechanism in 5.24.1 is fundamentally
broken wrt 5.22.1 -

seems a bit of an over-statement.

It seems far more likely that there is something up with the return
value
of Strerr() in this function call​:

Perl_croak(aTHX_ "Can't open perl script \"%s\"​: %s\n",
CopFILE(PL_curcop),
Strerror(EISDIR));

On my system, the last arg passed to croak() is a pointer the string
"Is a directory". On your system I'm guessing that Strerror(EISDIR)
is returning "(null)".

What Strerror is #defined to depends on what Configure finds in the
way
of strerror() and sys_errlist[] on your system. On my system I get​:

$ egrep 'strerror|syserrlst|strerrm' config.sh
d_gai_strerror='define'
d_strerrm='strerror(e)'
d_strerror='define'
d_strerror_l='define'
d_strerror_r='define'
d_syserrlst='define'
strerror_r_proto='REENTRANT_PROTO_B_IBW'

Are you absolutely certain that on your platform, at the point that
Perl_croak is called, it's last argument is correct a string pointer,
but
by the time Perl_sv_vcatpvfn_flags() is called to concatenate the args
using the format string, that pointer has become null?

The "Is a directory" pointer is retrieved on the second execution of
this
line​: sv.c​:11889​:

Perl_sv_vcatpvfn_flags(....)
{
....
case 's'​:
if (vectorize)
goto unknown;
if (args) {
====> eptr = va_arg(*args, char*);

At this point all that has happened is that Perl_croak() has passed
its
args on to to vcroak() which has passed its args to vmess() which
creates
a new temp SV and passes its args to sv_vsetpvfn(), which sets the SV
to
"" and then passes it and the args to Perl_sv_vcatpvfn_flags(). If the
pointer (or the text it points to) changes during that time, then
something very strange is going on.

Nice that the test suite picked up this disastrous fault in the croak
mechanism!

Its not disastrous.

Not nice that perl's croak mechanism has regressed.

I doubt that it has regressed. I think its more likely that something
weird about your platform is triggering an obscure issue.

I concur.

Yesterday I took the OP's sample program and simplified it to remove all the locale-related stuff, which seemed extraneous (attached). I then built perl in 6 different configurations (3 x 2 below) and ran the program in each.

Commit points​:

tag v5.22.3
tag v5.24.1
HEAD (b57dd50)

Configure​:

sh ./Configure -des -Dusedevel
sh ./Configure -des -Dusedevel -Duseshrplib

I got the same results in all 6 cases. Here's one example​:

#####
[perl] 646 $ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext ./perl -v |head -2 | tail -1
This is perl 5, version 22, subversion 3 (v5.22.3) built for x86_64-linux
[perl] 647 $ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext ./perl -I./lib /home/jkeenan/learn/perl/p5p/131126/131126-test_fail.pl
rp is​: <Can't open perl script "tmp15067B"​: Is a directory>
$! is​: <>
$? is​: <6400>
shifted​: <25>
ENOTTY
not EISDIR
#####

In each case, I got "Is a directory" in the error message. In each case, the errno was ENOTTY rather than EISDIR.

So I don't see any regression. EISDIR may, in principle, be a better errno for this situation than ENOTTY, but that's not a regression and not something we should change for 5.26.0.

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From @jkeenan

131126-test_fail.pl

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From @JVD66

Aha! I found & fixed the strerror problem.

My 'man strerror_r' manual page says :

SYNOPSIS
  #include <string.h>

  char *strerror(int errnum);

  int strerror_r(int errnum, char *buf, size_t buflen);
  /* XSI-compliant */

  char *strerror_r(int errnum, char *buf, size_t buflen);
  /* GNU-specific */

  char *strerror_l(int errnum, locale_t locale);

  Feature Test Macro Requirements for glibc (see feature_test_macros(7))​:

  strerror_r()​:
  The XSI-compliant version is provided if​:
  (_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE
  Otherwise, the GNU-specific version is provided.

In my config.h, STRERROR_R_PROTO is defined to be REENTRANT_PROTO_I_IBW ; in
reentr.h, it was INCORRECTLY passing the buffer instead of the buffer size as the
last parameter :

# define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)

This really makes no sense for any strerror_r version - all strerror_r prototypes
on my system expect a final 'size_t' argument.

Also, if the XSI version is being used, then strerror_r does not return a string
at all but an int status . If it returns a non-zero status & sets errno , I can see
a problem, but ...

So here is the patch to reentr.h that fixes the problem for me (also attached)​:

$ diff -U1 reentr.h~ reentr.h

Inline Patch
--- reentr.h~	2016-07-14 19:07:47.000000000 +0000
+++ reentr.h	2017-04-11 11:49:00.793988243 +0000
@@ -1397,3 +1397,7 @@
 #   if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_I_IBW
-#       define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)
+#     if ((_POSIX_C_SOURCE >= 200112L) && (!defined(_GNU_SOURCE)))
+#       define strerror(a) ({ register int _str = strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size); (_str == 0) ? PL_reentrant_buffer->_strerror_buffer : NULL; })
+#     else
+#       define strerror(a) strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size)
+#     endif
 #   endif


With the patch applied, the test now succeeeds:

$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} \ PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext LANG=C LC_ALL=C \
./perl /tmp
Can't open perl script "/tmp"​: Is a directory
$ echo $?
21

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From @JVD66

131126_reentr_h.patch
--- reentr.h~	2016-07-14 19:07:47.000000000 +0000
+++ reentr.h	2017-04-11 11:49:00.793988243 +0000
@@ -1397,3 +1397,7 @@
 #   if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_I_IBW
-#       define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)
+#     if ((_POSIX_C_SOURCE >= 200112L) && (!defined(_GNU_SOURCE)))
+#       define strerror(a) ({ register int _str = strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size); (_str == 0) ? PL_reentrant_buffer->_strerror_buffer : NULL; })
+#     else
+#       define strerror(a) strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size)
+#     endif
 #   endif

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From [Unknown Contact. See original ticket]

Aha! I found & fixed the strerror problem.

My 'man strerror_r' manual page says :

SYNOPSIS
  #include <string.h>

  char *strerror(int errnum);

  int strerror_r(int errnum, char *buf, size_t buflen);
  /* XSI-compliant */

  char *strerror_r(int errnum, char *buf, size_t buflen);
  /* GNU-specific */

  char *strerror_l(int errnum, locale_t locale);

  Feature Test Macro Requirements for glibc (see feature_test_macros(7))​:

  strerror_r()​:
  The XSI-compliant version is provided if​:
  (_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE
  Otherwise, the GNU-specific version is provided.

In my config.h, STRERROR_R_PROTO is defined to be REENTRANT_PROTO_I_IBW ; in
reentr.h, it was INCORRECTLY passing the buffer instead of the buffer size as the
last parameter :

# define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)

This really makes no sense for any strerror_r version - all strerror_r prototypes
on my system expect a final 'size_t' argument.

Also, if the XSI version is being used, then strerror_r does not return a string
at all but an int status . If it returns a non-zero status & sets errno , I can see
a problem, but ...

So here is the patch to reentr.h that fixes the problem for me (also attached)​:

$ diff -U1 reentr.h~ reentr.h

Inline Patch
--- reentr.h~	2016-07-14 19:07:47.000000000 +0000
+++ reentr.h	2017-04-11 11:49:00.793988243 +0000
@@ -1397,3 +1397,7 @@
 #   if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_I_IBW
-#       define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)
+#     if ((_POSIX_C_SOURCE >= 200112L) && (!defined(_GNU_SOURCE)))
+#       define strerror(a) ({ register int _str = strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size); (_str == 0) ? PL_reentrant_buffer->_strerror_buffer : NULL; })
+#     else
+#       define strerror(a) strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size)
+#     endif
 #   endif


With the patch applied, the test now succeeeds:

$ LD_PRELINK=${PWD}/libperl.so LD_LIBRARY_PATH=${PWD} \ PERL5LIB=${PWD}​:${PWD}/lib​:${PWD}/ext LANG=C LC_ALL=C \
./perl /tmp
Can't open perl script "/tmp"​: Is a directory
$ echo $?
21

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From @JVD66

Note that with the incorrect passing of the strerror buffer as the last argument
to strerror_r, the buffer pointer is converted to a size_t, and this will only
be a problem if an error string is > 256 bytes, which none are ; if one was,
then the bounds of the strerror buffer would be exceeded and strerror_r could
overwrite other memory - I suggest fixing the invocation of strerror_r.

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From [Unknown Contact. See original ticket]

Note that with the incorrect passing of the strerror buffer as the last argument
to strerror_r, the buffer pointer is converted to a size_t, and this will only
be a problem if an error string is > 256 bytes, which none are ; if one was,
then the bounds of the strerror buffer would be exceeded and strerror_r could
overwrite other memory - I suggest fixing the invocation of strerror_r.

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From @JVD66

OK, I found & fixed the main issues here :

1) wrong prototype assumed for strerror_r

  perl was assuming :
  int strerror_r( int errno, char *buf, size_t buflen )
  meaning strerror_r returns an int status ( XSI style )
  but if , strerror_r has prototype​:
  const char *strerror_r( int errno, char *buf, size_t buflen);

  with the effective CFLAGS produced by config.sh :

gcc -c -DPERL_CORE -g -fPIC -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fwrapv -std=c89 -mtune=native -O2 -g -fPIC -Wall -Werror=declaration-after-statement -Wextra -Wc++-compat -Wwrite-strings -fPIC perl.c

( this is how perl.c gets compiled ).

From GLIBC-2.25's /usr/include/string.h :

#ifdef __USE_XOPEN2K
/* Reentrant version of `strerror'.
  There are 2 flavors of `strerror_r', GNU which returns the string
  and may or may not use the supplied temporary buffer and POSIX one
  which fills the string into the buffer.
  To use the POSIX version, -D_XOPEN_SOURCE=600 or -D_POSIX_C_SOURCE=200112L
  without -D_GNU_SOURCE is needed, otherwise the GNU version is
  preferred. */
# if defined __USE_XOPEN2K && !defined __USE_GNU
/* Fill BUF with a string describing the meaning of the `errno' code in
  ERRNUM. */
# ifdef __REDIRECT_NTH
extern int __REDIRECT_NTH (strerror_r,
  (int __errnum, char *__buf, size_t __buflen),
  __xpg_strerror_r) __nonnull ((2));
# else
extern int __xpg_strerror_r (int __errnum, char *__buf, size_t __buflen)
  __THROW __nonnull ((2));
# define strerror_r __xpg_strerror_r
# endif
# else
/* If a temporary buffer is required, at most BUFLEN bytes of BUF will be
  used. */
extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
  __THROW __nonnull ((2)) __wur;
# endif
#endif

In config.h, we see :
#if defined(HAS_GNULIBC) && !defined(_GNU_SOURCE)
# define _GNU_SOURCE

that is why the GNU prototype, that returns a const char*, gets used ,
instead of the POSIX prototype.

The attached patch uses the GNU prototype if GNU_SOURCE is defined -
the test comes from the strerror_r manual page.

If I might make a suggestion to PERL testers, a platform containing
the 'latest stable releases' of Linux (4.10+), gcc 4 (4.9), gcc 5 (5.4.0), gcc 6 (6.3.0), and glibc (2.25) and binutils (2.28) should be included in automated testing -
some people, like me, do continue to build their own systems from scratch from
latest upstream 'stable' releases instead of a binary linux distro - (as does linuxfromscratch.org).

If you had compiled PERL under GLIBC 2.25, you would see same issues.

So all the test failures except the ExtUtils​::Install issue are fixed when PERL
is built with the patch applied on a Linux that supports times() correctly.

The ExtUtils​::Install issue was because I gave the same value for '$Config{man1direxp}' as for $Config{man3direxp} - the test doesn't like it when these are the same.

Sorry for confusion! This test resolved alot of issues on my system.

Thanks for your time, Jason

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From @JVD66

perl_bug_131126.patch
diff -up perl-5.24.1/perl.c.5.24.1 perl-5.24.1/perl.c
--- perl-5.24.1/perl.c.5.24.1	2017-01-02 17:27:54.000000000 +0000
+++ perl-5.24.1/perl.c	2017-04-11 11:04:22.064538560 +0000
@@ -3857,10 +3857,11 @@ S_open_script(pTHX_ const char *scriptna
     if (fd < 0 ||
         (PerlLIO_fstat(fd, &tmpstatbuf) >= 0
          && S_ISDIR(tmpstatbuf.st_mode)))
+    {   register const char *em = Strerror(errno=EISDIR);
         Perl_croak(aTHX_ "Can't open perl script \"%s\": %s\n",
             CopFILE(PL_curcop),
-            Strerror(EISDIR));
-
+            em);
+    }
     return rsfp;
 }
 
diff -up perl-5.24.1/reentr.h.5.24.1 perl-5.24.1/reentr.h
--- perl-5.24.1/reentr.h.5.24.1	2016-07-14 19:07:47.000000000 +0000
+++ perl-5.24.1/reentr.h	2017-04-11 20:27:19.314194174 +0000
@@ -1395,7 +1395,11 @@ typedef struct {
 #  if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1)
 #   undef strerror
 #   if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_I_IBW
+#     if ((_POSIX_C_SOURCE >= 200112L) && (!defined(_GNU_SOURCE)))
 #       define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)
+#     else
+#       define strerror(a) strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size)
+#     endif
 #   endif
 #   if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_I_IBI
 #       define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2017

From @khwilliamson

On 04/11/2017 02​:46 PM, Jason Vas Dias via RT wrote​:

OK, I found & fixed the main issues here :

1) wrong prototype assumed for strerror_r

perl was assuming :
  int strerror\_r\( int errno\, char \*buf\, size\_t buflen \)
meaning strerror\_r returns an int status \( XSI style \)
but if \, strerror\_r has prototype&#8203;:
  const char \*strerror\_r\( int errno\, char \*buf\, size\_t buflen\);

with the effective CFLAGS produced by config\.sh :

gcc -c -DPERL_CORE -g -fPIC -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fwrapv -std=c89 -mtune=native -O2 -g -fPIC -Wall -Werror=declaration-after-statement -Wextra -Wc++-compat -Wwrite-strings -fPIC perl.c

( this is how perl.c gets compiled ).

From GLIBC-2.25's /usr/include/string.h :

#ifdef __USE_XOPEN2K
/* Reentrant version of `strerror'.
There are 2 flavors of `strerror_r', GNU which returns the string
and may or may not use the supplied temporary buffer and POSIX one
which fills the string into the buffer.
To use the POSIX version, -D_XOPEN_SOURCE=600 or -D_POSIX_C_SOURCE=200112L
without -D_GNU_SOURCE is needed, otherwise the GNU version is
preferred. */
# if defined __USE_XOPEN2K && !defined __USE_GNU
/* Fill BUF with a string describing the meaning of the `errno' code in
ERRNUM. */
# ifdef __REDIRECT_NTH
extern int __REDIRECT_NTH (strerror_r,
(int __errnum, char *__buf, size_t __buflen),
__xpg_strerror_r) __nonnull ((2));
# else
extern int __xpg_strerror_r (int __errnum, char *__buf, size_t __buflen)
__THROW __nonnull ((2));
# define strerror_r __xpg_strerror_r
# endif
# else
/* If a temporary buffer is required, at most BUFLEN bytes of BUF will be
used. */
extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
__THROW __nonnull ((2)) __wur;
# endif
#endif

In config.h, we see :
#if defined(HAS_GNULIBC) && !defined(_GNU_SOURCE)
# define _GNU_SOURCE

that is why the GNU prototype, that returns a const char*, gets used ,
instead of the POSIX prototype.

The attached patch uses the GNU prototype if GNU_SOURCE is defined -
the test comes from the strerror_r manual page.

Darwin uses only the int returning version. I don't see how your patch
handles that, though I haven't spent much time looking at it. You also
don't test for _XOPEN_SOURCE >= 600 which the Linux man page calls for.

We don't use 'register' declarations in the Perl core any more. The
argument is that the compiler is better at determining what to do than
we are.

If I might make a suggestion to PERL testers, a platform containing
the 'latest stable releases' of Linux (4.10+), gcc 4 (4.9), gcc 5 (5.4.0), gcc 6 (6.3.0), and glibc (2.25) and binutils (2.28) should be included in automated testing -
some people, like me, do continue to build their own systems from scratch from
latest upstream 'stable' releases instead of a binary linux distro - (as does linuxfromscratch.org).

If you had compiled PERL under GLIBC 2.25, you would see same issues.

So all the test failures except the ExtUtils​::Install issue are fixed when PERL
is built with the patch applied on a Linux that supports times() correctly.

The ExtUtils​::Install issue was because I gave the same value for '$Config{man1direxp}' as for $Config{man3direxp} - the test doesn't like it when these are the same.

Sorry for confusion! This test resolved alot of issues on my system.

Thanks for your time, Jason

---
via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=131126

@p5pRT
Copy link
Author

p5pRT commented Apr 12, 2017

From @JVD66

On Tue, 11 Apr 2017 15​:02​:23 -0700, public@​khwilliamson.com wrote​:

Darwin uses only the int returning version. I don't see how your
patch
handles that, though I haven't spent much time looking at it. You
also
don't test for _XOPEN_SOURCE >= 600 which the Linux man page calls
for.

We don't use 'register' declarations in the Perl core any more. The
argument is that the compiler is better at determining what to do than
we are.

Yes, by all means paraphrase my patch / add the test for
_XOPEN_SOURCE >= 600
and take out the register declarations , but please fix
this issue - it does really break PERL's croak facility,
as shown by many test failures, which fail in confusing ways.

That patch is just what I put together to get the test
suite to pass on my platform.

I think GNU's prototype is more sensible - what is
one to assume about the value of errno one is trying
to record with strerror_r if strerror_r returns non zero ?

Perhaps PERL should really be backing up the value of errno -
strerror_r can set it!

On Darwin, if using GCC, can't you use _GNU_SOURCE and
the GNU prototype ?

You can view the string.h of GLIBC 2.25 online :
  https://sourceware.org/git/?p=glibc.git;a=blob;f=include/string.h;h=f166de9c43c8cb89e7a7a796c632e514af41edd1;hb=HEAD

you can see the const char * returning prototype is used if
_GNU_SOURCE is defined .

@p5pRT
Copy link
Author

p5pRT commented Apr 13, 2017

From @iabyn

On Tue, Apr 11, 2017 at 01​:46​:53PM -0700, Jason Vas Dias via RT wrote​:

@​@​ -3857,10 +3857,11 @​@​ S_open_script(pTHX_ const char *scriptna
if (fd < 0 ||
(PerlLIO_fstat(fd, &tmpstatbuf) >= 0
&& S_ISDIR(tmpstatbuf.st_mode)))
+ { register const char *em = Strerror(errno=EISDIR);
Perl_croak(aTHX_ "Can't open perl script \"%s\"​: %s\n",
CopFILE(PL_curcop),
- Strerror(EISDIR));
-
+ em);
+ }
return rsfp;

Ok, the errno=EISDIR change is to fix the exit value from "perl /dir".
What is the purpose of assigning the return value of Strerror() to a
temporary variable? What issues does this fix?

diff -up perl-5.24.1/reentr.h.5.24.1 perl-5.24.1/reentr.h
--- perl-5.24.1/reentr.h.5.24.1 2016-07-14 19​:07​:47.000000000 +0000
+++ perl-5.24.1/reentr.h 2017-04-11 20​:27​:19.314194174 +0000
@​@​ -1395,7 +1395,11 @​@​ typedef struct {
# if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1)
# undef strerror
# if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_I_IBW
+# if ((_POSIX_C_SOURCE >= 200112L) && (!defined(_GNU_SOURCE)))
# define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)
+# else
+# define strerror(a) strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size)
+# endif
# endif
# if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_I_IBI
# define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)

I think this is fixing things from the wrong end. reentr.h already
has a branch which handles GNU_C-variant stderror_r​:

# if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_B_IBW
# define strerror(a) strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size)

The real question is why Configure on your system is concluding that
the prototype for syserror_r() is REENTRANT_PROTO_I_IBW rather than
REENTRANT_PROTO_B_IBW. Are you able to investigate this?

--
No man treats a motor car as foolishly as he treats another human being.
When the car will not go, he does not attribute its annoying behaviour to
sin, he does not say, You are a wicked motorcar, and I shall not give you
any more petrol until you go. He attempts to find out what is wrong and
set it right.
  -- Bertrand Russell,
  Has Religion Made Useful Contributions to Civilization?

@p5pRT
Copy link
Author

p5pRT commented Apr 14, 2017

From @Leont

On Thu, Apr 13, 2017 at 10​:52 AM, Dave Mitchell <davem@​iabyn.com> wrote​:

diff -up perl-5.24.1/reentr.h.5.24.1 perl-5.24.1/reentr.h
--- perl-5.24.1/reentr.h.5.24.1 2016-07-14 19​:07​:47.000000000 +0000
+++ perl-5.24.1/reentr.h 2017-04-11 20​:27​:19.314194174 +0000
@​@​ -1395,7 +1395,11 @​@​ typedef struct {
# if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1)
# undef strerror
# if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_I_IBW
+# if ((_POSIX_C_SOURCE >= 200112L) && (!defined(_GNU_SOURCE)))
# define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)
+# else
+# define strerror(a) strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size)
+# endif
# endif
# if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_I_IBI
# define strerror(a) (strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ? PL_reentrant_buffer->_strerror_buffer : 0)

I think this is fixing things from the wrong end. reentr.h already
has a branch which handles GNU_C-variant stderror_r​:

# if !defined(strerror) && STRERROR_R_PROTO == REENTRANT_PROTO_B_IBW
# define strerror(a) strerror_r(a, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size)

The real question is why Configure on your system is concluding that
the prototype for syserror_r() is REENTRANT_PROTO_I_IBW rather than
REENTRANT_PROTO_B_IBW. Are you able to investigate this?

That's exactly what I was thinking.

Leon

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2017

From @JVD66

On Fri, 14 Apr 2017 07​:24​:15 -0700, LeonT wrote​:

On Thu, Apr 13, 2017 at 10​:52 AM, Dave Mitchell <davem@​iabyn.com>
wrote​:

diff -up perl-5.24.1/reentr.h.5.24.1 perl-5.24.1/reentr.h
--- perl-5.24.1/reentr.h.5.24.1 2016-07-14 19​:07​:47.000000000
+0000
+++ perl-5.24.1/reentr.h 2017-04-11 20​:27​:19.314194174 +0000
@​@​ -1395,7 +1395,11 @​@​ typedef struct {
# if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1)
# undef strerror
# if !defined(strerror) && STRERROR_R_PROTO ==
REENTRANT_PROTO_I_IBW
+# if ((_POSIX_C_SOURCE >= 200112L) && (!defined(_GNU_SOURCE)))
# define strerror(a) (strerror_r(a, PL_reentrant_buffer-

_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ?
PL_reentrant_buffer->_strerror_buffer : 0)
+# else
+# define strerror(a) strerror_r(a, PL_reentrant_buffer-
_strerror_buffer, PL_reentrant_buffer->_strerror_size)
+# endif
# endif
# if !defined(strerror) && STRERROR_R_PROTO ==
REENTRANT_PROTO_I_IBI
# define strerror(a) (strerror_r(a, PL_reentrant_buffer-
_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ?
PL_reentrant_buffer->_strerror_buffer : 0)

I think this is fixing things from the wrong end. reentr.h already
has a branch which handles GNU_C-variant stderror_r​:

# if !defined(strerror) && STRERROR_R_PROTO ==
REENTRANT_PROTO_B_IBW
# define strerror(a) strerror_r(a, PL_reentrant_buffer-

_strerror_buffer, PL_reentrant_buffer->_strerror_size)

The real question is why Configure on your system is concluding that
the prototype for syserror_r() is REENTRANT_PROTO_I_IBW rather than
REENTRANT_PROTO_B_IBW. Are you able to investigate this?

That's exactly what I was thinking.

Leon

Sorry I didn't see this post until now.
Investigating and will post back .

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2017

From @JVD66

On Fri, 14 Apr 2017 07​:24​:15 -0700, LeonT wrote​:

On Thu, Apr 13, 2017 at 10​:52 AM, Dave Mitchell <davem@​iabyn.com>
wrote​:

diff -up perl-5.24.1/reentr.h.5.24.1 perl-5.24.1/reentr.h
--- perl-5.24.1/reentr.h.5.24.1 2016-07-14 19​:07​:47.000000000
+0000
+++ perl-5.24.1/reentr.h 2017-04-11 20​:27​:19.314194174 +0000
@​@​ -1395,7 +1395,11 @​@​ typedef struct {
# if defined(PERL_REENTR_API) && (PERL_REENTR_API+0 == 1)
# undef strerror
# if !defined(strerror) && STRERROR_R_PROTO ==
REENTRANT_PROTO_I_IBW
+# if ((_POSIX_C_SOURCE >= 200112L) && (!defined(_GNU_SOURCE)))
# define strerror(a) (strerror_r(a, PL_reentrant_buffer-

_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ?
PL_reentrant_buffer->_strerror_buffer : 0)
+# else
+# define strerror(a) strerror_r(a, PL_reentrant_buffer-
_strerror_buffer, PL_reentrant_buffer->_strerror_size)
+# endif
# endif
# if !defined(strerror) && STRERROR_R_PROTO ==
REENTRANT_PROTO_I_IBI
# define strerror(a) (strerror_r(a, PL_reentrant_buffer-
_strerror_buffer, PL_reentrant_buffer->_strerror_size) == 0 ?
PL_reentrant_buffer->_strerror_buffer : 0)

I think this is fixing things from the wrong end. reentr.h already
has a branch which handles GNU_C-variant stderror_r​:

# if !defined(strerror) && STRERROR_R_PROTO ==
REENTRANT_PROTO_B_IBW
# define strerror(a) strerror_r(a, PL_reentrant_buffer-

_strerror_buffer, PL_reentrant_buffer->_strerror_size)

The real question is why Configure on your system is concluding that
the prototype for syserror_r() is REENTRANT_PROTO_I_IBW rather than
REENTRANT_PROTO_B_IBW. Are you able to investigate this?

That's exactly what I was thinking.

Leon

OK, I can explain this now .

In Configure, you are running gcc for the test programs WITHOUT _GNU_SOURCE
defined, so it sees the I_IBW strerror proto ; but something is inserting
_GNU_SOURCE in config.sh .

I'm glad PERL is deciding to use _GNU_SOURCE - if it weren't, I'd have to
make it do so by adding '-std=gnu89' or '-D_GNU_SOURCE' to the $CFLAGS ,
because alot of my PERL module code uses GNU extensions.

But then it should use _GNU_SOURCE for all the Configure tests, too .

I've attached an excerpt from the log produced by a clean Configure​:
  $ Unpack ~/downloads/perl-5.24.1.tar.gz && cd perl-5.24.1
I edited the resulting ./Configure to turn on 'set -x' for the
strerror prototype tests @​ line 19240 .
  $ ./Configure 2>&1 | tee Configure.log
...

An excerpt from the log is attached, showing the I_IBW prototype is used,
because _GNU_SOURCE is not set .
 

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2017

From @JVD66

STRERROR​:
+ test X = X -o X = X
+ set strerror val -f d_strerror
+ eval 'tlook=$1;' case '"$3"' in '-v)' 'tf=libc.tmp;' 'tdc="";;' '-a)' 'tf=libc.tmp;' 'tdc="[]";;' '*)' 'tlook="^$1\$";' 'tf=libc.list;' 'tdc="()";;' 'esac;' case '"$d_cplusplus"' in '$define)' 'extern_C="extern' '\"C\""' ';;' '*)' 'extern_C="extern"' ';;' 'esac;' 'tx=yes;' case '"$reuseval-$4"' in 'true-)' ';;' 'true-*)' 'tx=no;' eval '"tval=\$$4";' case '"$tval"' in '"")' 'tx=yes;;' 'esac;;' 'esac;' case '"$tx"' in 'yes)' 'tval=false;' if '$test' '"$runnm"' = 'true;' then if '$contains' '$tlook' '$tf' '>/dev/null' '2>&1;' then 'tval=true;' elif '$test' '"$mistrustnm"' = compile -o '"$mistrustnm"' = 'run;' then echo '"$extern_C' void '*$1$tdc;' void '*(*(p()))$tdc' '{' return '&$1;' '}' int 'main()' '{' 'if(p()' '&&' 'p()' '!=' '(void' '*)main)' 'return(0);' else 'return(1);' '}">' 'try.c;' '$cc' -o try '$optimize' '$ccflags' '$ldflags' try.c '>/dev/null' '2>&1' '$libs' '&&' 'tval=true;' '$test' '"$mistrustnm"' = run -a -x try '&&' '{' '$run' './try$_exe' '>/dev/null' '2>&1' '||' 'tval=false;' '};' '$rm_try;' 'fi;' else echo '"$extern_C' void '*$1$tdc;' void '*(*(p()))$tdc' '{' return '&$1;' '}' int 'main()' '{' 'if(p()' '&&' 'p()' '!=' '(void' '*)main)' 'return(0);' else 'return(1);' '}">' 'try.c;' '$cc' -o try '$optimize' '$ccflags' '$ldflags' try.c '$libs' '>/dev/null' '2>&1' '&&' 'tval=true;' '$rm_try;' 'fi;' ';;' '*)' case '"$tval"' in '$define)' 'tval=true;;' '*)' 'tval=false;;' 'esac;' ';;' 'esac;' eval '"$2=$tval"'
++ tlook=strerror
++ case "$3" in
++ tlook='^strerror$'
++ tf=libc.list
++ tdc='()'
++ case "$d_cplusplus" in
++ extern_C=extern
++ tx=yes
++ case "$reuseval-$4" in
++ case "$tx" in
++ tval=false
++ test true = true
++ grep '^strerror$' libc.list
++ tval=true
++ eval val=true
+++ val=true
+ true
+ echo 'strerror() found.'
strerror() found.
+ d_strerror=define
+ d_strerrm='strerror(e)'
+ set sys_errlist val -a d_syserrlst
+ eval 'tlook=$1;' case '"$3"' in '-v)' 'tf=libc.tmp;' 'tdc="";;' '-a)' 'tf=libc.tmp;' 'tdc="[]";;' '*)' 'tlook="^$1\$";' 'tf=libc.list;' 'tdc="()";;' 'esac;' case '"$d_cplusplus"' in '$define)' 'extern_C="extern' '\"C\""' ';;' '*)' 'extern_C="extern"' ';;' 'esac;' 'tx=yes;' case '"$reuseval-$4"' in 'true-)' ';;' 'true-*)' 'tx=no;' eval '"tval=\$$4";' case '"$tval"' in '"")' 'tx=yes;;' 'esac;;' 'esac;' case '"$tx"' in 'yes)' 'tval=false;' if '$test' '"$runnm"' = 'true;' then if '$contains' '$tlook' '$tf' '>/dev/null' '2>&1;' then 'tval=true;' elif '$test' '"$mistrustnm"' = compile -o '"$mistrustnm"' = 'run;' then echo '"$extern_C' void '*$1$tdc;' void '*(*(p()))$tdc' '{' return '&$1;' '}' int 'main()' '{' 'if(p()' '&&' 'p()' '!=' '(void' '*)main)' 'return(0);' else 'return(1);' '}">' 'try.c;' '$cc' -o try '$optimize' '$ccflags' '$ldflags' try.c '>/dev/null' '2>&1' '$libs' '&&' 'tval=true;' '$test' '"$mistrustnm"' = run -a -x try '&&' '{' '$run' './try$_exe' '>/dev/null' '2>&1' '||' 'tval=false;' '};' '$rm_try;' 'fi;' else echo '"$extern_C' void '*$1$tdc;' void '*(*(p()))$tdc' '{' return '&$1;' '}' int 'main()' '{' 'if(p()' '&&' 'p()' '!=' '(void' '*)main)' 'return(0);' else 'return(1);' '}">' 'try.c;' '$cc' -o try '$optimize' '$ccflags' '$ldflags' try.c '$libs' '>/dev/null' '2>&1' '&&' 'tval=true;' '$rm_try;' 'fi;' ';;' '*)' case '"$tval"' in '$define)' 'tval=true;;' '*)' 'tval=false;;' 'esac;' ';;' 'esac;' eval '"$2=$tval"'
++ tlook=sys_errlist
++ case "$3" in
++ tf=libc.tmp
++ tdc='[]'
++ case "$d_cplusplus" in
++ extern_C=extern
++ tx=yes
++ case "$reuseval-$4" in
++ case "$tx" in
++ tval=false
++ test true = true
++ grep sys_errlist libc.tmp
++ tval=true
++ eval val=true
+++ val=true
+ true
+ echo '(You also have sys_errlist[], so we could roll our own strerror.)'
(You also have sys_errlist[], so we could roll our own strerror.)
+ d_syserrlst=define
+ : see if strerror_r exists
+ set strerror_r d_strerror_r
+ eval echo '"' '";' 'td=$define;' 'tu=$undef;' 'sym=$1;' 'var=$2;' eval '"was=\$$2";' 'tx=yes;' case '"$reuseval$was"' in 'true)' ';;' 'true*)' 'tx=no;;' 'esac;' case '"$tx"' in 'yes)' set '$sym' tres '-f;' eval '$csym;' case '"$tres"' in 'true)' echo '"$sym()' 'found."' '>&4;' case '"$was"' in '$undef)' . './whoa;' 'esac;' eval '"$var=\$td";;' '*)' echo '"$sym()' NOT 'found."' '>&4;' case '"$was"' in '$define)' . './whoa;' 'esac;' eval '"$var=\$tu";;' 'esac;;' '*)' case '"$was"' in '$define)' echo '"$sym()' 'found."' '>&4;;' '*)' echo '"$sym()' NOT 'found."' '>&4;;' 'esac;;' esac
++ echo ' '

++ td=define
++ tu=undef
++ sym=strerror_r
++ var=d_strerror_r
++ eval 'was=$d_strerror_r'
+++ was=
++ tx=yes
++ case "$reuseval$was" in
++ case "$tx" in
++ set strerror_r tres -f
++ eval 'tlook=$1;' case '"$3"' in '-v)' 'tf=libc.tmp;' 'tdc="";;' '-a)' 'tf=libc.tmp;' 'tdc="[]";;' '*)' 'tlook="^$1\$";' 'tf=libc.list;' 'tdc="()";;' 'esac;' case '"$d_cplusplus"' in '$define)' 'extern_C="extern' '\"C\""' ';;' '*)' 'extern_C="extern"' ';;' 'esac;' 'tx=yes;' case '"$reuseval-$4"' in 'true-)' ';;' 'true-*)' 'tx=no;' eval '"tval=\$$4";' case '"$tval"' in '"")' 'tx=yes;;' 'esac;;' 'esac;' case '"$tx"' in 'yes)' 'tval=false;' if '$test' '"$runnm"' = 'true;' then if '$contains' '$tlook' '$tf' '>/dev/null' '2>&1;' then 'tval=true;' elif '$test' '"$mistrustnm"' = compile -o '"$mistrustnm"' = 'run;' then echo '"$extern_C' void '*$1$tdc;' void '*(*(p()))$tdc' '{' return '&$1;' '}' int 'main()' '{' 'if(p()' '&&' 'p()' '!=' '(void' '*)main)' 'return(0);' else 'return(1);' '}">' 'try.c;' '$cc' -o try '$optimize' '$ccflags' '$ldflags' try.c '>/dev/null' '2>&1' '$libs' '&&' 'tval=true;' '$test' '"$mistrustnm"' = run -a -x try '&&' '{' '$run' './try$_exe' '>/dev/null' '2>&1' '||' 'tval=false;' '};' '$rm_try;' 'fi;' else echo '"$extern_C' void '*$1$tdc;' void '*(*(p()))$tdc' '{' return '&$1;' '}' int 'main()' '{' 'if(p()' '&&' 'p()' '!=' '(void' '*)main)' 'return(0);' else 'return(1);' '}">' 'try.c;' '$cc' -o try '$optimize' '$ccflags' '$ldflags' try.c '$libs' '>/dev/null' '2>&1' '&&' 'tval=true;' '$rm_try;' 'fi;' ';;' '*)' case '"$tval"' in '$define)' 'tval=true;;' '*)' 'tval=false;;' 'esac;' ';;' 'esac;' eval '"$2=$tval"'
+++ tlook=strerror_r
+++ case "$3" in
+++ tlook='^strerror_r$'
+++ tf=libc.list
+++ tdc='()'
+++ case "$d_cplusplus" in
+++ extern_C=extern
+++ tx=yes
+++ case "$reuseval-$4" in
+++ case "$tx" in
+++ tval=false
+++ test true = true
+++ grep '^strerror_r$' libc.list
+++ tval=true
+++ eval tres=true
++++ tres=true
++ case "$tres" in
++ echo 'strerror_r() found.'
strerror_r() found.
++ case "$was" in
++ eval 'd_strerror_r=$td'
+++ d_strerror_r=define
+ case "$d_strerror_r" in
+ hdrs='define sys/types.h define stdio.h define string.h'
+ case "$d_strerror_r_proto​:$usethreads" in
+ d_strerror_r_proto=define
+ set d_strerror_r_proto strerror_r define sys/types.h define stdio.h define string.h
+ eval 'varname=$1;' 'func=$2;' 'shift;' 'shift;' while '$test' '$#' -ge '2;' do case '"$1"' in '$define)' echo '"#include' '<$2>";;' esac ';' shift '2;' done '>' 'try.c;' '$cppstdin' '$cppflags' '$cppminus' '<' try.c '>' tryout.c '2>/dev/null;' if '$contains' '"$func.*("' tryout.c '>/dev/null' '2>&1;' then echo '"$func()' prototype 'found.";' 'val="$define";' else echo '"$func()' prototype NOT 'found.";' 'val="$undef";' 'fi;' set '$varname;' eval '$setvar;' '$rm_try' tryout.c
++ varname=d_strerror_r_proto
++ func=strerror_r
++ shift
++ shift
++ test 6 -ge 2
++ case "$1" in
++ echo '#include <sys/types.h>'
++ shift 2
++ test 4 -ge 2
++ case "$1" in
++ echo '#include <stdio.h>'
++ shift 2
++ test 2 -ge 2
++ case "$1" in
++ echo '#include <string.h>'
++ shift 2
++ test 0 -ge 2
++ gcc -E -D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -
++ grep 'strerror_r.*(' tryout.c
++ echo 'strerror_r() prototype found.'
strerror_r() prototype found.
++ val=define
++ set d_strerror_r_proto
++ eval 'var=$1;' eval '"was=\$$1";' 'td=$define;' 'tu=$undef;' case '"$val$was"' in '$define$undef)' . './whoa;' eval '"$var=\$td";;' '$undef$define)' . './whoa;' eval '"$var=\$tu";;' '*)' eval '"$var=$val";;' esac
+++ var=d_strerror_r_proto
+++ eval 'was=$d_strerror_r_proto'
++++ was=define
+++ td=define
+++ tu=undef
+++ case "$val$was" in
+++ eval d_strerror_r_proto=define
++++ d_strerror_r_proto=define
++ /usr/bin/rm -f try try a.out .out try.c try..o core 'core.try*' 'try.core*' tryout.c
+ case "$d_strerror_r_proto" in
+ case "$strerror_r_proto" in
+ try='int strerror_r(int, char*, size_t);'
+ ./protochk 'extern int strerror_r(int, char*, size_t);' define sys/types.h define stdio.h define string.h
+ case "$strerror_r_proto" in
+ try='int strerror_r(int, char*, int);'
+ ./protochk 'extern int strerror_r(int, char*, int);' define sys/types.h define stdio.h define string.h
+ case "$strerror_r_proto" in
+ try='char* strerror_r(int, char*, size_t);'
+ ./protochk 'extern char* strerror_r(int, char*, size_t);' define sys/types.h define stdio.h define string.h
+ strerror_r_proto=B_IBW
+ case "$strerror_r_proto" in
+ case "$strerror_r_proto" in
+ strerror_r_proto=REENTRANT_PROTO_B_IBW
+ echo 'Prototype​: char* strerror_r(int, char*, size_t);'
Prototype​: char* strerror_r(int, char*, size_t);
+ set +x

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2017

From @JVD66

And of course, that log is showing the opposite - it IS using _GNU_SOURCE !

The Configure.log from the original perl-5.24.1 build that fails shows
it does NOT set _GNU_SOURCE in $CFLAGS :

Doing variable substitutions on .SH files...
Extracting config.h (with variable substitutions)
cflags.SH​: Adding -std=c89.
cflags.SH​: Adding -Werror=declaration-after-statement.
cflags.SH​: Adding -Wextra.
cflags.SH​: Adding -Wc++-compat.
cflags.SH​: Adding -Wwrite-strings.
cflags.SH​: cc = gcc
cflags.SH​: ccflags = -g -fPIC -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fwrapv
cflags.SH​: stdflags = -std=c89
cflags.SH​: optimize = -mtune=native -O2 -g -fPIC
cflags.SH​: warn = -Wall -Werror=declaration-after-statement -Wextra -Wc++-compat -Wwrite-strings
Extracting cflags (with variable substitutions)
Not re-extracting config.h
Extracting makedepend (with variable substitutions)
Extracting Makefile (with variable substitutions)
Extracting myconfig (with variable substitutions)
Extracting pod/Makefile (with variable substitutions)
Extracting Policy.sh (with variable substitutions)
Extracting runtests (with variable substitutions)

and it gets the I_IBW strerror prototype, but it does set _GNU_SOURCE in
config.sh / config.h , while the new Configure above defines _GNU_SOURCE :
Extracting config.h (with variable substitutions)
cflags.SH​: Adding -std=c89.
cflags.SH​: Adding -Werror=declaration-after-statement.
cflags.SH​: Adding -Wextra.
cflags.SH​: Adding -Wc++-compat.
cflags.SH​: Adding -Wwrite-strings.
cflags.SH​: cc = gcc
cflags.SH​: ccflags = -D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
cflags.SH​: stdflags = -std=c89
cflags.SH​: optimize = -mtune=native -g -O2
cflags.SH​: warn = -Wall -Werror=declaration-after-statement -Wextra -Wc++-compat -Wwrite-strings

I think this was because for the version that failed, I
had a $CFLAGS setting in the environment​:
  CFLAGS="-std=gnu11 -march=x86-64 -mtune=native -O2 -g -fPIC -pipe"
whereas in the run that succeeded, I did not have any $CFLAGS in
the environment.

Perhaps PERL should be making extra checks that if it is going to insert '#define _GNU_SOURCE'
in config.h / config.sh , then _GNU_SOURCE is added to the $CFLAGS used for all test programs
if not present.

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2017

From [Unknown Contact. See original ticket]

And of course, that log is showing the opposite - it IS using _GNU_SOURCE !

The Configure.log from the original perl-5.24.1 build that fails shows
it does NOT set _GNU_SOURCE in $CFLAGS :

Doing variable substitutions on .SH files...
Extracting config.h (with variable substitutions)
cflags.SH​: Adding -std=c89.
cflags.SH​: Adding -Werror=declaration-after-statement.
cflags.SH​: Adding -Wextra.
cflags.SH​: Adding -Wc++-compat.
cflags.SH​: Adding -Wwrite-strings.
cflags.SH​: cc = gcc
cflags.SH​: ccflags = -g -fPIC -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fwrapv
cflags.SH​: stdflags = -std=c89
cflags.SH​: optimize = -mtune=native -O2 -g -fPIC
cflags.SH​: warn = -Wall -Werror=declaration-after-statement -Wextra -Wc++-compat -Wwrite-strings
Extracting cflags (with variable substitutions)
Not re-extracting config.h
Extracting makedepend (with variable substitutions)
Extracting Makefile (with variable substitutions)
Extracting myconfig (with variable substitutions)
Extracting pod/Makefile (with variable substitutions)
Extracting Policy.sh (with variable substitutions)
Extracting runtests (with variable substitutions)

and it gets the I_IBW strerror prototype, but it does set _GNU_SOURCE in
config.sh / config.h , while the new Configure above defines _GNU_SOURCE :
Extracting config.h (with variable substitutions)
cflags.SH​: Adding -std=c89.
cflags.SH​: Adding -Werror=declaration-after-statement.
cflags.SH​: Adding -Wextra.
cflags.SH​: Adding -Wc++-compat.
cflags.SH​: Adding -Wwrite-strings.
cflags.SH​: cc = gcc
cflags.SH​: ccflags = -D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
cflags.SH​: stdflags = -std=c89
cflags.SH​: optimize = -mtune=native -g -O2
cflags.SH​: warn = -Wall -Werror=declaration-after-statement -Wextra -Wc++-compat -Wwrite-strings

I think this was because for the version that failed, I
had a $CFLAGS setting in the environment​:
  CFLAGS="-std=gnu11 -march=x86-64 -mtune=native -O2 -g -fPIC -pipe"
whereas in the run that succeeded, I did not have any $CFLAGS in
the environment.

Perhaps PERL should be making extra checks that if it is going to insert '#define _GNU_SOURCE'
in config.h / config.sh , then _GNU_SOURCE is added to the $CFLAGS used for all test programs
if not present.

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2017

From @Leont

On Sat, Apr 15, 2017 at 2​:54 PM, Jason Vas Dias via RT
<perlbug-comment@​perl.org> wrote​:

I think this was because for the version that failed, I
had a $CFLAGS setting in the environment​:
CFLAGS="-std=gnu11 -march=x86-64 -mtune=native -O2 -g -fPIC -pipe"
whereas in the run that succeeded, I did not have any $CFLAGS in
the environment.

Perhaps PERL should be making extra checks that if it is going to insert '#define _GNU_SOURCE'
in config.h / config.sh , then _GNU_SOURCE is added to the $CFLAGS used for all test programs
if not present.

What Configure arguments are you using exactly?

Leon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants