Skip Menu |
Report information
Id: 113906
Status: open
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: mjp [at]

Operating System: Linux
PatchStatus: (no value)
Severity: low
Type: core
Perl Version: 5.16.0
Fixed In: (no value)

Subject: Unexpected variable assignment after restarted readline
Date: Fri, 29 Jun 2012 15:00:11 -0500
To: perlbug [...]
From: Mike Pomraning <mjp [...]>
Download (untitled) / with headers
text/plain 4.1k
When ``$line = <STDIN>'' is restarted after an ALRM handler, and a line of input given, $line might not contain the line read from STDIN if the handler assigned a *number* (but not a string) to $line. Contrast the unexpected when $line is a number: my $line; $SIG{ALRM} = sub { print "Please type something now\n"; $line = 100; }; alarm 3; $line = <STDIN>; alarm 0; print $line; # surprise! prints 100 With the expected when $line is a string: my $line; $SIG{ALRM} = sub { print "Please type something now\n"; $line = '100'; }; alarm 3; $line = <STDIN>; alarm 0; print $line; # prints whatever was read from STDIN With the expected when $line is a number but a tmp var is involved: my $line; $SIG{ALRM} = sub { print "Please type something now\n"; $line = 100; }; alarm 3; $line = my $tmp = <STDIN>; alarm 0; print $line; # prints whatever was read from STDIN I find the first case unexpected -- <STDIN> should restart after the ALRM handler runs, and then $line should be overwritten by the return value once the user enters input. That is, the technique shown above for assigning a default value upon timeout should *not* work, but it does when the default is a number and the assignment is direct. I see the same behavior on even releases from 5.8 through 5.16. Is my expectation flawed? --- Flags: category=core severity=low --- Site configuration information for perl 5.16.0: Configured by mjp at Fri Jun 8 10:30:45 CDT 2012. Summary of my perl5 (revision 5 version 16 subversion 0) configuration: Platform: osname=linux, osvers=2.6.18-308.4.1.el5, archname=i686-linux-thread-multi uname='linux wrench 2.6.18-308.4.1.el5 #1 smp tue apr 17 17:08:10 edt 2012 i686 i686 i386 gnulinux ' config_args='-des -Duseithreads -Dprefix=/opt/perl-5.16.0' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2', cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.1.2 20080704 (Red Hat 4.1.2-52)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib /usr/lib64 libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=/lib/, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.5' 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' Locally applied patches: --- @INC for perl 5.16.0: /home/mjp/.perl/5.16/lib/perl5/i686-linux-thread-multi /home/mjp/.perl/5.16/lib/perl5 /home/mjp/.perl/5.16/lib/perl5/i686-linux-thread-multi/ /opt/perl-5.16.0/lib/site_perl/5.16.0/i686-linux-thread-multi /opt/perl-5.16.0/lib/site_perl/5.16.0 /opt/perl-5.16.0/lib/5.16.0/i686-linux-thread-multi /opt/perl-5.16.0/lib/5.16.0 . --- Environment for perl 5.16.0: HOME=/home/mjp LANG=en_US.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib::/usr/lib LOGDIR (unset) PATH=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin:/home/mjp/.gem/ruby/1.9.2/bin:/opt/ruby-1.9.2/bin:/home/mjp/.perl/5.16/bin:/opt/perl-5.16.0/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/mjp/bin PERL5LIB=/home/mjp/.perl/5.16/lib/perl5:/home/mjp/.perl/5.16/lib/perl5/i686-linux-thread-multi/ PERL_BADLANG (unset) SHELL=/bin/bash
RT-Send-CC: perl5-porters [...]
Download (untitled) / with headers
text/plain 1.2k
So I think I fixed this specific issue in the branch doy/signal_interrupts_readline_rt113906, but this is really a specific case of a more general (and harder to fix) problem. This specific case is pretty easy because the only things that change when a number is assigned to $line is that the SV is upgraded to a SVt_PVIV, the IV slot is filled in, and some of the SV flags are adjusted, so the only thing that needs to be done here is to readjust those SV flags. In the case where you assign something to $line that needs to use the PV field for something else though ($line = {}, for instance), things get extra screwed up, because earlier in sv_gets, there is a bunch of code that works with pointers and offsets into the string stored in the PV, and assigning over that makes all of those variables invalid (in particular, at sv.c:7841, bp now points to some completely unrelated (and possibly deallocated) piece of memory). Unfortunately, I don't really follow what's going on in that section of the code (it is doing a lot of encapsulation-breaking peeking into internal buffers for speed reasons), and so I don't really feel comfortable fiddling with that part of the code. Someone who has a better idea of how that section of code works would need to decide how to best restructure things.

This service is sponsored and maintained by Best Practical Solutions and runs on infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at