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

implicit file handle close during global destruction segfaults if no PL_curcop #15591

Closed
p5pRT opened this issue Sep 7, 2016 · 13 comments
Closed

Comments

@p5pRT
Copy link

p5pRT commented Sep 7, 2016

Migrated from rt.perl.org#129223 (status was 'resolved')

Searchable as RT129223$

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 2016

From @toddr

Created by @toddr

We are seeing a segfault while running this minimized code. It happens
both in 5.22.0 as well as 5.24.

Note that the segfault happened in the child process. On Linux, the
easy way to see this is to do​:

tail -1f /var/log/messages |grep libperl

The minimized script​:

sub do_in_child {
  require $0;
  fork() or exit;
}

sub script {
  open( my $fh, '>', '/tmp/foo' ) or die;
  do_in_child();
}

script if(!caller);
1;

Perl Info



Flags:
    category=core
    severity=low


Site configuration information for perl 5.24.1:

Configured by cPanel at Fri Aug 19 13:33:21 CDT 2016.

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


  Platform:
    osname=linux, osvers=3.10.0-123.20.1.el7.x86_64, archname=x86_64-linux-64int
    uname='linux rpmbuild-64-centos-7.dev.cpanel.net
3.10.0-123.20.1.el7.x86_64 #1 smp thu jan 29 18:05:33 utc 2015 x86_64
x86_64 x86_64 gnulinux '
    config_args='-des -Dusedevel -Darchname=x86_64-linux-64int
-Dcc=/usr/bin/gcc -Dcpp=/usr/bin/cpp -DDEBUGGING=none -Doptimize=-Os
-Dusemymalloc=n -Duseshrplib -Duselargefiles=yes -Duseposix=true
-Dhint=recommended -Duseperlio=yes -Dccflags=-DPERL_DISABLE_PMC
-I/usr/local/cpanel/3rdparty/perl/524/include
-L/usr/local/cpanel/3rdparty/perl/524/lib64
-I/usr/local/cpanel/3rdparty/include
-L/usr/local/cpanel/3rdparty/lib64
-Dcppflags=-I/usr/local/cpanel/3rdparty/perl/524/include
-L/usr/local/cpanel/3rdparty/perl/524/lib64
-I/usr/local/cpanel/3rdparty/include
-L/usr/local/cpanel/3rdparty/lib64 -Dldflags=-Wl,-rpath
-Wl,/usr/local/cpanel/3rdparty/perl/524/lib64
-L/usr/local/cpanel/3rdparty/perl/524/lib64
-L/usr/local/cpanel/3rdparty/lib64
-Dprefix=/usr/local/cpanel/3rdparty/perl/524
-Dsiteprefix=/opt/cpanel/perl5/524 -Dsitebin=/opt/cpanel/perl5/524/bin
-Dsitelib=/opt/cpanel/perl5/524/site_lib -Dusevendorprefix=true
-Dvendorbin=/usr/local/cpanel/3rdparty/perl/524/bin
-Dvendorprefix=/usr/local/cpanel/3rdparty/perl/524/lib64/perl5
-Dvendorlib=/usr/local/cpanel/3rdparty/perl/524/lib64/perl5/cpanel_lib
-Dprivlib=/usr/local/cpanel/3rdparty/perl/524/lib64/perl5/5.24.1
-Dman1dir=none -Dman3dir=none
-Dscriptdir=/usr/local/cpanel/3rdparty/perl/524/bin
-Dscriptdirexp=/usr/local/cpanel/3rdparty/perl/524/bin
-Dsiteman1dir=none -Dsiteman3dir=none -Dinstallman1dir=none
-Dversiononly=no -Dinstallusrbinperl=no -Dcf_by=cPanel
-Dmyhostname=localhost -Dperladmin=root@localhost
-Dcf_email=support@cpanel.net
-Di_dbm=/usr/local/cpanel/3rdparty/include
-Di_gdbm=/usr/local/cpanel/3rdparty/include
-Di_ndbm=/usr/local/cpanel/3rdparty/include -DDB_File=true -Ud_dosuid
-Uuserelocatableinc -Umad -Uusethreads -Uusemultiplicity -Uusesocks
-Uuselongdouble -Aldflags=-L/usr/local/cpanel/3rdparty/perl/524/lib64
-L/usr/local/cpanel/3rdparty/lib64 -L/usr/lib64 -L/lib64 -lgdbm
-Dlocincpth=/usr/local/cpanel/3rdparty/perl/524/include
/usr/local/cpanel/3rdparty/include /usr/local/include  -Duse64bitint
-Uuse64bitall -Acflags=-fPIC -DPIC -m64
-I/usr/local/cpanel/3rdparty/perl/524/include
/usr/local/cpanel/3rdparty/include
-Dlibpth=/usr/local/cpanel/3rdparty/perl/524/lib64
/usr/local/cpanel/3rdparty/lib64 /usr/local/lib64 /usr/local/lib
/lib64 /usr/lib64 '
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    use64bitint=define, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef

  Compiler:
    cc='/usr/bin/gcc', ccflags ='-DPERL_DISABLE_PMC
-I/usr/local/cpanel/3rdparty/perl/524/include
-L/usr/local/cpanel/3rdparty/perl/524/lib64
-I/usr/local/cpanel/3rdparty/include
-L/usr/local/cpanel/3rdparty/lib64 -fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2',
    optimize='-Os',
    cppflags='-I/usr/local/cpanel/3rdparty/perl/524/include
-L/usr/local/cpanel/3rdparty/perl/524/lib64
-I/usr/local/cpanel/3rdparty/include
-L/usr/local/cpanel/3rdparty/lib64 -DPERL_DISABLE_PMC
-I/usr/local/cpanel/3rdparty/perl/524/include
-L/usr/local/cpanel/3rdparty/perl/524/lib64
-I/usr/local/cpanel/3rdparty/include
-L/usr/local/cpanel/3rdparty/lib64 -fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include'
    ccversion='', gccversion='4.8.2 20140120 (Red Hat 4.8.2-16)',
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='/usr/bin/gcc', ldflags ='-Wl,-rpath
-Wl,/usr/local/cpanel/3rdparty/perl/524/lib64
-L/usr/local/cpanel/3rdparty/perl/524/lib64
-L/usr/local/cpanel/3rdparty/lib64
-L/usr/local/cpanel/3rdparty/perl/524/lib64
-L/usr/local/cpanel/3rdparty/lib64 -L/usr/lib64 -L/lib64 -lgdbm
-fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/cpanel/3rdparty/perl/524/lib64
/usr/local/cpanel/3rdparty/lib64 /usr/local/lib64 /usr/local/lib
/lib64 /usr/lib64 /usr/local/lib /usr/lib /lib/../lib64
/usr/lib/../lib64 /lib
    libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.17.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.17'

  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E
-Wl,-rpath,/usr/local/cpanel/3rdparty/perl/524/lib64/perl5/5.24.1/x86_64-linux-64int/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -Os
-L/usr/local/cpanel/3rdparty/perl/524/lib64
-L/usr/local/cpanel/3rdparty/lib64 -L/usr/lib64 -L/lib64
-L/usr/local/lib -fstack-protector-strong'

Locally applied patches:
    cPanel patches
    cPanel INC path changes
    Remove . from @INC



@INC for perl 5.24.1:
    /usr/local/cpanel
    /usr/local/cpanel/3rdparty/perl/524/lib64/perl5/cpanel_lib/x86_64-linux-64int
    /usr/local/cpanel/3rdparty/perl/524/lib64/perl5/cpanel_lib
    /usr/local/cpanel/3rdparty/perl/524/lib64/perl5/5.24.1/x86_64-linux-64int
    /usr/local/cpanel/3rdparty/perl/524/lib64/perl5/5.24.1
    /opt/cpanel/perl5/524/site_lib/x86_64-linux-64int
    /opt/cpanel/perl5/524/site_lib




Environment for perl 5.24.1:
    HOME=/root
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/local/cpanel/3rdparty/perl/524/bin:/usr/local/cpanel/bin:/usr/local/cpanel/3rdparty/bin:/usr/local/cpanel/3rdparty/perl/524/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/cpanel/perl5/524/bin
    PERL_BADLANG (unset)
    SHELL=/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 2016

From @toddr

This bisects to​:

commit 96d7c88
Author​: Father Chrysostomos <sprout@​cpan.org>
Date​: Wed Sep 17 21​:16​:58 2014 -0800
  [perl #57512] Warnings for implicitly closed handles
 
  If the implicit close() fails, warn about it, mentioning $! in the
  message. This is a default warning in the io category.
 
  We do this in two spots, sv_clear and gp_free. While sv_clear would
  be sufficient to get the warning emitted, the warning won’t contain
  the name of the handle when called from there, because lone IO thing-
  ies are nameless. Doing it also when a GV’s glob pointer is freed--as
  long as the IO thingy in there has a reference count of 1--allows the
  name to be included in the message, because we still have the glob,
  which is where the name is stored.
 
  The result​:
 
  $ ./miniperl -Ilib -e 'open fh, ">/Volumes/Disk Image/foo"; print fh "x"x1000, "\n" for 1..50; undef *fh'
  Warning​: unable to close filehandle fh properly​: No space left on device at -e line 1.
:100644 100644 1df3535092d1e2d31036796a1b97f22215e17fe7 60876127b5fc71113eca53b04a120c82f5eca54b M doio.c
:100644 100644 ab5bb0d3c20ede37602fd1d0f195a956d1a5cca2 78ad3d80948e227f72041525db2558806868e9c8 M embed.fnc
:100644 100644 b9ff3c6c1d023edcf289da2e6f89333ca20d1831 1a98de566f8ab8a010accc24c5856e96f046b56d M embed.h
:100644 100644 7abc6ccacba6f83f9d275fc6929957ef1bb9cb5d c8d434544c36789393c188737410d250ab306d17 M gv.c
:040000 040000 d431afcec8a9ead7923528b6d97977b68ac1e2b7 074b15ad99bf232956290cb8afcf34e48e9d8643 M pod
:100644 100644 3835a17fda0e0ee5cf279f4613f2451440200108 67415639b4ebb07e948d634b2e89a1f748dca0f6 M proto.h
:100644 100644 70683a12430e4b3ff0130044d9be444090090956 f398a930521fd4be5b9ab2dd330b62389987e659 M sv.c
:040000 040000 4d52cb8c929d736b73e9a8d3432cc9ffc9b57066 1fde52a5c0ece4f93d92e50dc063ea0349d3c36b M t

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 2016

From [Unknown Contact. See original ticket]

This bisects to​:

commit 96d7c88
Author​: Father Chrysostomos <sprout@​cpan.org>
Date​: Wed Sep 17 21​:16​:58 2014 -0800
  [perl #57512] Warnings for implicitly closed handles
 
  If the implicit close() fails, warn about it, mentioning $! in the
  message. This is a default warning in the io category.
 
  We do this in two spots, sv_clear and gp_free. While sv_clear would
  be sufficient to get the warning emitted, the warning won’t contain
  the name of the handle when called from there, because lone IO thing-
  ies are nameless. Doing it also when a GV’s glob pointer is freed--as
  long as the IO thingy in there has a reference count of 1--allows the
  name to be included in the message, because we still have the glob,
  which is where the name is stored.
 
  The result​:
 
  $ ./miniperl -Ilib -e 'open fh, ">/Volumes/Disk Image/foo"; print fh "x"x1000, "\n" for 1..50; undef *fh'
  Warning​: unable to close filehandle fh properly​: No space left on device at -e line 1.
:100644 100644 1df3535092d1e2d31036796a1b97f22215e17fe7 60876127b5fc71113eca53b04a120c82f5eca54b M doio.c
:100644 100644 ab5bb0d3c20ede37602fd1d0f195a956d1a5cca2 78ad3d80948e227f72041525db2558806868e9c8 M embed.fnc
:100644 100644 b9ff3c6c1d023edcf289da2e6f89333ca20d1831 1a98de566f8ab8a010accc24c5856e96f046b56d M embed.h
:100644 100644 7abc6ccacba6f83f9d275fc6929957ef1bb9cb5d c8d434544c36789393c188737410d250ab306d17 M gv.c
:040000 040000 d431afcec8a9ead7923528b6d97977b68ac1e2b7 074b15ad99bf232956290cb8afcf34e48e9d8643 M pod
:100644 100644 3835a17fda0e0ee5cf279f4613f2451440200108 67415639b4ebb07e948d634b2e89a1f748dca0f6 M proto.h
:100644 100644 70683a12430e4b3ff0130044d9be444090090956 f398a930521fd4be5b9ab2dd330b62389987e659 M sv.c
:040000 040000 4d52cb8c929d736b73e9a8d3432cc9ffc9b57066 1fde52a5c0ece4f93d92e50dc063ea0349d3c36b M t

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 2016

From @atoomic

After using gdb on the program it appears that the COP is empty when calling isLEXWARN_off
which is defined as

#define isLEXWARN_off (PL_curcop->cop_warnings == pWARN_STD)

there is not protection when PL_curcop is empty

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7ff16c0 (LWP 4770)]
0x00296d10 in Perl_ckwarn_d (w=5) at util.c​:1975
1975 util.c​: No such file or directory.
  in util.c
Missing separate debuginfos, use​: debuginfo-install cpanel-perl-522-debug-5.22.0-0.cp1154.i686
(gdb) bt
#0 0x00296d10 in Perl_ckwarn_d (w=5) at util.c​:1975
#1 0x001c2210 in Perl_gp_free (gv=0x804c288) at gv.c​:2549
#2 0x0033056b in Perl_sv_clear (orig_sv=0x804c288) at sv.c​:6683
#3 0x00332570 in Perl_sv_free2 (sv=0x804c288, rc=1) at sv.c​:7032
#4 0x002f923f in S_SvREFCNT_dec_NN (sv=0x804c288) at inline.h​:177
#5 0x0034771e in Perl_sv_unref_flags (ref=0x805d8ac, flags=5) at sv.c​:10397
#6 0x0032542d in Perl_sv_force_normal_flags (sv=0x805d8ac, flags=5) at sv.c​:5282
#7 0x0038deda in Perl_leave_scope (base=3) at scope.c​:1045
#8 0x0039b016 in Perl_dounwind (cxix=-1) at pp_ctl.c​:1533
#9 0x001abd23 in S_my_exit_jump () at perl.c​:5022
#10 0x001aba56 in Perl_my_exit (status=0) at perl.c​:4917
#11 0x003a856e in Perl_pp_exit () at pp_ctl.c​:3172
#12 0x0028f5bb in Perl_runops_debug () at dump.c​:2234
#13 0x0019fd72 in S_run_body (oldscope=1) at perl.c​:2448
#14 0x0019f325 in perl_run (my_perl=0x804a008) at perl.c​:2371
#15 0x08048b3a in main (argc=2, argv=0xbffff284, env=0xbffff290) at perlmain.c​:116
(gdb) p PL_curcop
$1 = (COP *) 0x0
(gdb) quit

On Wed Sep 07 16​:27​:03 2016, TODDR wrote​:

This bisects to​:

commit 96d7c88
Author​: Father Chrysostomos <sprout@​cpan.org>
Date​: Wed Sep 17 21​:16​:58 2014 -0800
[perl #57512] Warnings for implicitly closed handles

If the implicit close() fails, warn about it, mentioning $! in the
message. This is a default warning in the io category.

We do this in two spots, sv_clear and gp_free. While sv_clear would
be sufficient to get the warning emitted, the warning won’t contain
the name of the handle when called from there, because lone IO thing-
ies are nameless. Doing it also when a GV’s glob pointer is freed--as
long as the IO thingy in there has a reference count of 1--allows the
name to be included in the message, because we still have the glob,
which is where the name is stored.

The result​:

$ ./miniperl -Ilib -e 'open fh, ">/Volumes/Disk Image/foo"; print fh
"x"x1000, "\n" for 1..50; undef *fh'
Warning​: unable to close filehandle fh properly​: No space left on
device at -e line 1.
:100644 100644 1df3535092d1e2d31036796a1b97f22215e17fe7
60876127b5fc71113eca53b04a120c82f5eca54b M doio.c
:100644 100644 ab5bb0d3c20ede37602fd1d0f195a956d1a5cca2
78ad3d80948e227f72041525db2558806868e9c8 M embed.fnc
:100644 100644 b9ff3c6c1d023edcf289da2e6f89333ca20d1831
1a98de566f8ab8a010accc24c5856e96f046b56d M embed.h
:100644 100644 7abc6ccacba6f83f9d275fc6929957ef1bb9cb5d
c8d434544c36789393c188737410d250ab306d17 M gv.c
:040000 040000 d431afcec8a9ead7923528b6d97977b68ac1e2b7
074b15ad99bf232956290cb8afcf34e48e9d8643 M pod
:100644 100644 3835a17fda0e0ee5cf279f4613f2451440200108
67415639b4ebb07e948d634b2e89a1f748dca0f6 M proto.h
:100644 100644 70683a12430e4b3ff0130044d9be444090090956
f398a930521fd4be5b9ab2dd330b62389987e659 M sv.c
:040000 040000 4d52cb8c929d736b73e9a8d3432cc9ffc9b57066
1fde52a5c0ece4f93d92e50dc063ea0349d3c36b M t

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 2016

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

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 2016

From @toddr

On Wed Sep 07 16​:30​:10 2016, atoomic wrote​:

After using gdb on the program it appears that the COP is empty when
calling isLEXWARN_off
which is defined as

#define isLEXWARN_off (PL_curcop->cop_warnings == pWARN_STD)

there is not protection when PL_curcop is empty

This may point to the fact that Father's commit is not the issue.

The issue seems to be that PL_curcop was cleared when we redefined a subroutine we happened to be in and then we exited inside that subroutine.

Had PL_curcop not been cleared, we wouldn't have had this issue. It's not clear why re-defining a subroutine necessarily needs to clear PL_curcop?

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 2016

From [Unknown Contact. See original ticket]

On Wed Sep 07 16​:30​:10 2016, atoomic wrote​:

After using gdb on the program it appears that the COP is empty when
calling isLEXWARN_off
which is defined as

#define isLEXWARN_off (PL_curcop->cop_warnings == pWARN_STD)

there is not protection when PL_curcop is empty

This may point to the fact that Father's commit is not the issue.

The issue seems to be that PL_curcop was cleared when we redefined a subroutine we happened to be in and then we exited inside that subroutine.

Had PL_curcop not been cleared, we wouldn't have had this issue. It's not clear why re-defining a subroutine necessarily needs to clear PL_curcop?

@p5pRT
Copy link
Author

p5pRT commented Sep 8, 2016

From @cpansprout

On Wed Sep 07 16​:55​:31 2016, TODDR wrote​:

On Wed Sep 07 16​:30​:10 2016, atoomic wrote​:

After using gdb on the program it appears that the COP is empty when
calling isLEXWARN_off
which is defined as

#define isLEXWARN_off (PL_curcop->cop_warnings == pWARN_STD)

there is not protection when PL_curcop is empty

This may point to the fact that Father's commit is not the issue.

The issue seems to be that PL_curcop was cleared when we redefined a
subroutine we happened to be in and then we exited inside that
subroutine.

Had PL_curcop not been cleared, we wouldn't have had this issue. It's
not clear why re-defining a subroutine necessarily needs to clear
PL_curcop?

It means that the op that PL_curcop was pointing to got freed. You can’t have PL_curcop pointing to a freed op, because Bad Things happen.

But clearing PL_curcop also makes Bad Things happen, due to bugs elsewhere.

BTW, this is a duplicate of #128597, which is fixed in blead by a2637ca.

I have proposed that it be backported to 5.2[24], but nobody else has put forward any votes.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 8, 2016

From @toddr

On Wed Sep 07 19​:40​:35 2016, sprout wrote​:

BTW, this is a duplicate of #128597, which is fixed in blead by
a2637ca.

DOH! Thanks, I should have checked blead. Confirmed this fixes our issue. Thanks!

@p5pRT
Copy link
Author

p5pRT commented Sep 8, 2016

@cpansprout - Status changed from 'open' to 'pending release'

@p5pRT
Copy link
Author

p5pRT commented Sep 12, 2016

From @xsawyerx

On 09/08/2016 04​:40 AM, Father Chrysostomos via RT wrote​:

[...]

I have proposed that it be backported to 5.2[24], but nobody else has put forward any votes.

One from you, one from Karl, one from me.

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release today of Perl 5.26.0, this and 210 other issues have been
resolved.

Perl 5.26.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.26.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

@khwilliamson - Status changed from 'pending release' to 'resolved'

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

1 participant