Skip to content

Reading from STDIN fails if SIGCHLD handler is set #12753

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

Closed
p5pRT opened this issue Feb 3, 2013 · 5 comments
Closed

Reading from STDIN fails if SIGCHLD handler is set #12753

p5pRT opened this issue Feb 3, 2013 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Feb 3, 2013

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

Searchable as RT116621$

@p5pRT
Copy link
Author

p5pRT commented Feb 3, 2013

From [email protected]

This is a bug report for perl from dmitry.panov@​yahoo.co.uk,
generated with the help of perlbug 1.39 running under perl 5.14.2.

Hi,

After upgrading from Debian Squeeze to Ubuntu 12.04 I noticed that one of the perl scripts was failing.
I've managed to narrow it down to a simple test case consisting of 2 files listed below. In order to
reproduce the problem you need to run 1.pl. Within one second it will fail producting the following
message​:

error​: Illegal seek at ./2.pl line 11, <STDIN> line 16.
Exiting main_stdin() at ./2.pl line 11, <STDIN> line 16.

It looks like the text of the error is irrelevant, it's just the latest error. For the script it looks
like eof although it's clear that it isn't.

I'm actually not sure whether it's a perl or a libc bug because I was able to reproduce it on Debian
Wheezy with both distribution perl and ActivePerl 5.16, however the same ActivePerl 5.16 works fine on
Debian Squeeze.

So it looks like glibc 2.11 is fine, but 2.13+ is not.

If I change the SIGCHLD handler to 'INGORE' it works fine in all cases.

File listings below​:

1.pl​:

#!/usr/bin/perl

use Time​::HiRes qw( usleep );

open my $f, "| ./2.pl";

my $s = "1\n1\n1\n1\n";
my $l = length($s);

while (1) {
  syswrite($f, $s, $l);
  usleep(rand()*30000);
}

2.pl​:

#!/usr/bin/perl

use POSIX qw/​:sys_wait_h /;

use strict;

sub _log {
  warn($_[0]);
}

sub REAPER {
  local ($!, $?);
  while ((my $waitedpid = waitpid(-1, WNOHANG)) > 0) {
  _log("Reaper​: child $waitedpid exited");
  }
  $SIG{CHLD} = \&REAPER;
}

sub main_stdin {

  while (1) {
  my $l = <STDIN>;
  if (!defined($l)) {
  _log("error​: ".$!);
  }
  last if (!defined($l));
  if (!fork()) { exit(0); }
  }
  _log("Exiting main_stdin()");
}

# main

$SIG{CHLD} = \&REAPER;
#$SIG{CHLD} = 'IGNORE';

print $], "\n";

main_stdin();
exit 0;


Flags​:
  category=core
  severity=medium


Site configuration information for perl 5.14.2​:

Configured by Debian Project at Tue Nov 27 00​:34​:23 UTC 2012.

Summary of my perl5 (revision 5 version 14 subversion 2) configuration​:
 
  Platform​:
  osname=linux, osvers=2.6.42-32-generic, archname=x86_64-linux-gnu-thread-multi
  uname='linux allspice 2.6.42-32-generic #51-ubuntu smp wed sep 26 21​:33​:09 utc 2012 x86_64 x86_64 x86_64 gnulinux '
  config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.14 -Darchlib=/usr/lib/perl/5.14 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.14.2 -Dsitearch=/usr/local/lib/perl/5.14.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.14.2 -des'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=define, usemultiplicity=define
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2 -g',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
  ccversion='', gccversion='4.6.3', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
  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 -L/usr/local/lib'
  libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib
  libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
  perllibs=-ldl -lm -lpthread -lc -lcrypt
  libc=, so=so, useshrplib=true, libperl=libperl.so.5.14.2
  gnulibc_version='2.15'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib -fstack-protector'

Locally applied patches​:
 


@​INC for perl 5.14.2​:
  /etc/perl
  /usr/local/lib/perl/5.14.2
  /usr/local/share/perl/5.14.2
  /usr/lib/perl5
  /usr/share/perl5
  /usr/lib/perl/5.14
  /usr/share/perl/5.14
  /usr/local/lib/site_perl
  .


Environment for perl 5.14.2​:
  HOME=/home/dop
  LANG=en_GB.UTF-8
  LANGUAGE=en_GB​:en
  LC_ADDRESS=en_GB.UTF-8
  LC_IDENTIFICATION=en_GB.UTF-8
  LC_MEASUREMENT=en_GB.UTF-8
  LC_MONETARY=en_GB.UTF-8
  LC_NAME=en_GB.UTF-8
  LC_NUMERIC=en_GB.UTF-8
  LC_PAPER=en_GB.UTF-8
  LC_TELEPHONE=en_GB.UTF-8
  LC_TIME=en_GB.UTF-8
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/usr/StorMan/pegasus/bin​:/usr/StorMan/ssl/bin​:/usr/lib/lightdm/lightdm​:/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Feb 5, 2013

From @iabyn

On Sun, Feb 03, 2013 at 10​:36​:39AM -0800, dmitry.panov@​yahoo.co.uk wrote​:

After upgrading from Debian Squeeze to Ubuntu 12.04 I noticed that one
of the perl scripts was failing. I've managed to narrow it down to a
simple test case consisting of 2 files listed below. In order to
reproduce the problem you need to run 1.pl. Within one second it will
fail producting the following message​:

error​: Illegal seek at ./2.pl line 11, <STDIN> line 16.
Exiting main_stdin() at ./2.pl line 11, <STDIN> line 16.

It looks like the text of the error is irrelevant, it's just the latest
error. For the script it looks like eof although it's clear that it
isn't.

I'm actually not sure whether it's a perl or a libc bug because I was
able to reproduce it on Debian Wheezy with both distribution perl and
ActivePerl 5.16, however the same ActivePerl 5.16 works fine on Debian
Squeeze.

So it looks like glibc 2.11 is fine, but 2.13+ is not.

I can reproduce it on perl 5.14.x but not 5.16.0 or later (both with
glibc 2.16).

I bisected, and it appears to have been fixed by this commit​:

  commit be48bbe
  Author​: Chip <chip@​pobox.com>
  AuthorDate​: Mon Sep 19 23​:51​:49 2011 -0700

  add a couple missing LEAVEs in perlio_async_run()

Which made it into 5.15.4.

The fact that you're still seeing this issue with 5.16 makes me wonder
whether your 2.pl is being invoked with the right perl version.

If you change this line in 1.pl​:

  open my $f, "| ./2.pl";

to

  open my $f, "| $^X ./2.pl";

then explicitly run 1.pl with the correct perl version, e.g.

  perl5.16.0 ./1.pl

do you still see the issue?

--
"There's something wrong with our bloody ships today, Chatfield."
  -- Admiral Beatty at the Battle of Jutland, 31st May 1916.

@p5pRT
Copy link
Author

p5pRT commented Feb 5, 2013

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

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2013

From [email protected]

On 05/02/13 14​:00, Dave Mitchell via RT wrote​:

On Sun, Feb 03, 2013 at 10​:36​:39AM -0800, dmitry.panov@​yahoo.co.uk wrote​:

So it looks like glibc 2.11 is fine, but 2.13+ is not.
I can reproduce it on perl 5.14.x but not 5.16.0 or later (both with
glibc 2.16).

I bisected, and it appears to have been fixed by this commit​:

 commit be48bbe8d671b6841c3ec7cb734b98071afe3cd9
 Author&#8203;:     Chip \<chip@&#8203;pobox\.com>
 AuthorDate&#8203;: Mon Sep 19 23&#8203;:51&#8203;:49 2011 \-0700

add a couple missing LEAVEs in perlio\_async\_run\(\)

Which made it into 5.15.4.

The fact that you're still seeing this issue with 5.16 makes me wonder
whether your 2.pl is being invoked with the right perl version.

If you change this line in 1.pl​:

 open my $f\, "| \./2\.pl";

to

 open my $f\, "| $^X \./2\.pl";

then explicitly run 1.pl with the correct perl version, e.g.

 perl5\.16\.0 \./1\.pl

do you still see the issue?

Hmm... I was fairly sure it was the correct version (that's why I have
the print $]) and that I was able to reproduce it with 5.16, it just
took a bit longer. However I left it running for a few hours now and the
problem is not showing.

I also found the same bug (by googling the commit id) reported and fixed
in Fedora​: https://bugzilla.redhat.com/show_bug.cgi?id=767931 It's a
shame it's still present in Ubuntu and Debian...

Anyway, thanks a lot for your help, I'm going to update the ubuntu bug I
posted ( https://bugs.launchpad.net/ubuntu/+source/perl/+bug/1100359)
hoping that ubuntu folks will pay attention at last :)

Best regards,

--
Dmitry Panov

@p5pRT p5pRT closed this as completed Feb 7, 2013
@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2013

@iabyn - Status changed from 'open' 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