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

Infinite recursion on FILENO in tied handle leads to segfault #5272

Open
p5pRT opened this issue Mar 19, 2002 · 34 comments
Open

Infinite recursion on FILENO in tied handle leads to segfault #5272

p5pRT opened this issue Mar 19, 2002 · 34 comments

Comments

@p5pRT
Copy link

p5pRT commented Mar 19, 2002

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

Searchable as RT8861$

@p5pRT
Copy link
Author

p5pRT commented Mar 19, 2002

From @schwern

Created by @schwern

The following code leads to an infinite recursion on FILENO.

{
  package Handle;
 
  sub TIEHANDLE {
  bless \$_[1];
  }
  sub FILENO { fileno $_[0] }
}

open FOO, ">foo.tmp" or die $!;
tie *FOO, 'Handle', *FOO;
print fileno *FOO;

This leads to a segfault inside malloc (I happen to have threads
compiled in, but they're not relevent).

#0 0x0fee4818 in __pthread_alt_lock () from /lib/libpthread.so.0
#1 0x0fee062c in pthread_mutex_lock () from /lib/libpthread.so.0
#2 0x100237d8 in Perl_malloc (nbytes=28) at malloc.c​:1060
#3 0x100ad978 in Perl_av_extend (my_perl=0x101c5988, av=0x102826f0, key=2)
  at av.c​:150
#4 0x100adf68 in Perl_av_store (my_perl=0x101c5988, av=0x102826f0, key=2,
  val=0x102826fc) at av.c​:275
#5 0x100c0260 in Perl_pp_entersub (my_perl=0x101c5988) at pp_hot.c​:2785
#6 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#7 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01248, is_eval=0)
  at perl.c​:1967
#8 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x102826e4, flags=64)
  at perl.c​:1846
#9 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
  methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#10 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#11 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#12 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01538, is_eval=0)
  at perl.c​:1967
#13 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x102826b4, flags=64)
  at perl.c​:1846
#14 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
  methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#15 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#16 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#17 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01828, is_eval=0)
  at perl.c​:1967
#18 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x10282684, flags=64)
  at perl.c​:1846
#19 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
  methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#20 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#21 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#22 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01b18, is_eval=0)
  at perl.c​:1967
#23 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x10282654, flags=64)
  at perl.c​:1846
#24 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
  methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#25 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#26 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#27 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01e08, is_eval=0)
  at perl.c​:1967
#28 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x10282624, flags=64)
  at perl.c​:1846
#29 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
....etc...

The bug only effects bleadperl back to 5.6.0. 5.005_03 and back don't
go into a recursion.

schwern@​blackrider​:~$ bleadperl -lw ~/tmp/bug2.plx
Deep recursion on subroutine "Handle​::FILENO" at /home/schwern/tmp/bug2.plx line 7.
Segmentation fault
schwern@​blackrider​:~$ perl5.6.1 -lw ~/tmp/bug2.plx
Deep recursion on subroutine "Handle​::FILENO" at /home/schwern/tmp/bug2.plx line 7.
Segmentation fault
schwern@​blackrider​:~$ perl5.6.0 -lw ~/tmp/bug2.plx
Deep recursion on subroutine "Handle​::FILENO" at /home/schwern/tmp/bug2.plx line 7.
Segmentation fault
schwern@​blackrider​:~$ perl5.004_05 -lw ~/tmp/bug2.plx
3
schwern@​blackrider​:~$ perl5.005_03 -lw ~/tmp/bug2.plx
3
schwern@​blackrider​:~$ perl5.004_04 -lw ~/tmp/bug2.plx
3
schwern@​blackrider​:~$ perl5.004 -lw ~/tmp/bug2.plx
3

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.7.3:

Configured by schwern at Tue Mar 12 23:27:46 EST 2002.

Summary of my perl5 (revision 5.0 version 7 subversion 3 patch 15209) configuration:
  Platform:
    osname=linux, osvers=2.4.17-ben0, archname=ppc-linux-thread-multi-64int
    uname='linux blackrider 2.4.17-ben0 #1 sun dec 23 18:59:02 est 2001 ppc unknown '
    config_args=''
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=define use64bitall=undef uselongdouble=undef
    usemymalloc=y, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_GNU_SOURCE -D_REENTRANT -DDEBUGGING -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-g',
    cppflags='-D_GNU_SOURCE -D_REENTRANT -DDEBUGGING -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='2.95.4  (Debian prerelease)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=87654321
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
    ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -lgdbm -ldbm -ldb -ldl -lm -lpthread -lc -lcrypt -lutil
    perllibs=-lnsl -ldl -lm -lpthread -lc -lcrypt -lutil
    libc=/lib/libc-2.2.5.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    DEVEL15172


@INC for perl v5.7.3:
    /home/schwern/lib/perl5/site_perl
    /usr/local/bleadperl/lib/5.7.3/ppc-linux-thread-multi-64int
    /usr/local/bleadperl/lib/5.7.3
    /usr/local/bleadperl/lib/site_perl/5.7.3/ppc-linux-thread-multi-64int
    /usr/local/bleadperl/lib/site_perl/5.7.3
    /usr/local/bleadperl/lib/site_perl
    .


Environment for perl v5.7.3:
    HOME=/home/schwern
    LANG=en_US
    LANGUAGE=en
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/schwern/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/X11/bin:/usr/bin/X11:/usr/games
    PERL5LIB=/home/schwern/lib/perl5/site_perl
    PERL_BADLANG (unset)
    SHELL=/bin/bash


@p5pRT
Copy link
Author

p5pRT commented Mar 20, 2002

From @andk

On Tue, 19 Mar 2002 22​:58​:24 -0500 (EST), schwern@​hse-montreal-ppp106142.qc.sympatico.ca (Michael G Schwern) said​:

  > This leads to a segfault inside malloc (I happen to have threads
  > compiled in, but they're not relevent).

  > The bug only effects bleadperl back to 5.6.0. 5.005_03 and back don't
  > go into a recursion.

Confirmed for all non-threaded perls from 5.6.0 to bleadperl. Not
confirmed for threaded perls from 5.6.0 to 5.7.2@​11535. For threaded
perls the bug apparently was introduced with patch 11536.

For non-threaded perls the bug seems to have been introduced in 5.005_57.

--
andreas

@p5pRT
Copy link
Author

p5pRT commented Mar 20, 2002

From [Unknown Contact. See original ticket]

Michael G Schwern <schwern@​pobox.com> writes​:

This is a bug report for perl from schwern@​pobox.com,
generated with the help of perlbug 1.33 running under perl v5.7.3.

-----------------------------------------------------------------
[Please enter your report here]

The following code leads to an infinite recursion on FILENO.

{
package Handle;

sub TIEHANDLE {
bless \$_[1];
}
sub FILENO { fileno $_[0] }
}

open FOO, ">foo.tmp" or die $!;
tie *FOO, 'Handle', *FOO;
print fileno *FOO;

This is due to the fact that 5.7.* adds the TIEHANDLE magic to the IO
rather than the GV - so the self-tie recursion avoidance stuff
does not catch.

I am not defending the change - it has bitten me ...

This leads to a segfault inside malloc (I happen to have threads
compiled in, but they're not relevent).

#0 0x0fee4818 in __pthread_alt_lock () from /lib/libpthread.so.0
#1 0x0fee062c in pthread_mutex_lock () from /lib/libpthread.so.0
#2 0x100237d8 in Perl_malloc (nbytes=28) at malloc.c​:1060
#3 0x100ad978 in Perl_av_extend (my_perl=0x101c5988, av=0x102826f0, key=2)
at av.c​:150
#4 0x100adf68 in Perl_av_store (my_perl=0x101c5988, av=0x102826f0, key=2,
val=0x102826fc) at av.c​:275
#5 0x100c0260 in Perl_pp_entersub (my_perl=0x101c5988) at pp_hot.c​:2785
#6 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#7 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01248, is_eval=0)
at perl.c​:1967
#8 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x102826e4, flags=64)
at perl.c​:1846
#9 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#10 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#11 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#12 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01538, is_eval=0)
at perl.c​:1967
#13 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x102826b4, flags=64)
at perl.c​:1846
#14 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#15 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#16 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#17 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01828, is_eval=0)
at perl.c​:1967
#18 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x10282684, flags=64)
at perl.c​:1846
#19 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#20 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#21 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#22 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01b18, is_eval=0)
at perl.c​:1967
#23 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x10282654, flags=64)
at perl.c​:1846
#24 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#25 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#26 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at dump.c​:1392
#27 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01e08, is_eval=0)
at perl.c​:1967
#28 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x10282624, flags=64)
at perl.c​:1846
#29 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
....etc...

The bug only effects bleadperl back to 5.6.0. 5.005_03 and back don't
go into a recursion.

schwern@​blackrider​:~$ bleadperl -lw ~/tmp/bug2.plx
Deep recursion on subroutine "Handle​::FILENO" at /home/schwern/tmp/bug2.plx line 7.
Segmentation fault
schwern@​blackrider​:~$ perl5.6.1 -lw ~/tmp/bug2.plx
Deep recursion on subroutine "Handle​::FILENO" at /home/schwern/tmp/bug2.plx line 7.
Segmentation fault
schwern@​blackrider​:~$ perl5.6.0 -lw ~/tmp/bug2.plx
Deep recursion on subroutine "Handle​::FILENO" at /home/schwern/tmp/bug2.plx line 7.
Segmentation fault
schwern@​blackrider​:~$ perl5.004_05 -lw ~/tmp/bug2.plx
3
schwern@​blackrider​:~$ perl5.005_03 -lw ~/tmp/bug2.plx
3
schwern@​blackrider​:~$ perl5.004_04 -lw ~/tmp/bug2.plx
3
schwern@​blackrider​:~$ perl5.004 -lw ~/tmp/bug2.plx
3

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags​:
category=core
severity=low
---
Site configuration information for perl v5.7.3​:

Configured by schwern at Tue Mar 12 23​:27​:46 EST 2002.

Summary of my perl5 (revision 5.0 version 7 subversion 3 patch 15209) configuration​:
Platform​:
osname=linux, osvers=2.4.17-ben0, archname=ppc-linux-thread-multi-64int
uname='linux blackrider 2.4.17-ben0 #1 sun dec 23 18​:59​:02 est 2001 ppc unknown '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=define use64bitall=undef uselongdouble=undef
usemymalloc=y, bincompat5005=undef
Compiler​:
cc='cc', ccflags ='-D_GNU_SOURCE -D_REENTRANT -DDEBUGGING -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-g',
cppflags='-D_GNU_SOURCE -D_REENTRANT -DDEBUGGING -fno-strict-aliasing -I/usr/local/include'
ccversion='', gccversion='2.95.4 (Debian prerelease)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=87654321
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries​:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lgdbm -ldbm -ldb -ldl -lm -lpthread -lc -lcrypt -lutil
perllibs=-lnsl -ldl -lm -lpthread -lc -lcrypt -lutil
libc=/lib/libc-2.2.5.so, so=so, useshrplib=false, libperl=libperl.a
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:
DEVEL15172

---
@​INC for perl v5.7.3​:
/home/schwern/lib/perl5/site_perl
/usr/local/bleadperl/lib/5.7.3/ppc-linux-thread-multi-64int
/usr/local/bleadperl/lib/5.7.3
/usr/local/bleadperl/lib/site_perl/5.7.3/ppc-linux-thread-multi-64int
/usr/local/bleadperl/lib/site_perl/5.7.3
/usr/local/bleadperl/lib/site_perl
.

---
Environment for perl v5.7.3​:
HOME=/home/schwern
LANG=en_US
LANGUAGE=en
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/home/schwern/bin​:/usr/local/sbin​:/usr/sbin​:/sbin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/local/X11/bin​:/usr/bin/X11​:/usr/games
PERL5LIB=/home/schwern/lib/perl5/site_perl
PERL_BADLANG (unset)
SHELL=/bin/bash
--
Nick Ing-Simmons
http​://www.ni-s.u-net.com/

@p5pRT
Copy link
Author

p5pRT commented Mar 20, 2002

From [Unknown Contact. See original ticket]

At 2002-03-20 11​:53​:01, nick.ing-simmons@​elixent.com wrote​:

This is due to the fact that 5.7.* adds the TIEHANDLE magic to the IO
rather than the GV - so the self-tie recursion avoidance stuff does
not catch.

Could you please point me to the self-tie recursion avoidance stuff in
question?

- ams

@p5pRT
Copy link
Author

p5pRT commented Mar 20, 2002

From [Unknown Contact. See original ticket]

Abhijit Menon-Sen <ams@​wiw.org> writes​:

At 2002-03-20 11​:53​:01, nick.ing-simmons@​elixent.com wrote​:

This is due to the fact that 5.7.* adds the TIEHANDLE magic to the IO
rather than the GV - so the self-tie recursion avoidance stuff does
not catch.

Could you please point me to the self-tie recursion avoidance stuff in
question?

Not easily - it "just worked" like self-tied scalars before... and
I never really understood that - and as Ilya has pointed out it is
not well described (even by comments never mind pod...)

- ams
--
Nick Ing-Simmons
http​://www.ni-s.u-net.com/

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2003

From cmoore@hellyeah.org

Segfaults 5.8.0 as well.

[schwern <!--c--> <i>at</i> <!--a--> hse-montreal-ppp106142.qc.sympatico.ca -
Tue Mar 19 11​:58​:35 2002]​:

This is a bug report for perl from schwern <!--c--> <i>at</i> <!--a-->
pobox.com,
generated with the help of perlbug 1.33 running under perl v5.7.3.

-----------------------------------------------------------------
[Please enter your report here]

The following code leads to an infinite recursion on FILENO.

{
package Handle;

sub TIEHANDLE \{
    bless \\$\_\[1\];
\}
sub FILENO \{ fileno $\_\[0\] \}

}

open FOO, ">foo.tmp" or die $!;
tie *FOO, 'Handle', *FOO;
print fileno *FOO;

This leads to a segfault inside malloc (I happen to have threads
compiled in, but they're not relevent).

#0 0x0fee4818 in __pthread_alt_lock () from /lib/libpthread.so.0
#1 0x0fee062c in pthread_mutex_lock () from /lib/libpthread.so.0
#2 0x100237d8 in Perl_malloc (nbytes=28) at malloc.c​:1060
#3 0x100ad978 in Perl_av_extend (my_perl=0x101c5988, av=0x102826f0,
key=2)
at av.c​:150
#4 0x100adf68 in Perl_av_store (my_perl=0x101c5988, av=0x102826f0,
key=2,
val=0x102826fc) at av.c​:275
#5 0x100c0260 in Perl_pp_entersub (my_perl=0x101c5988) at
pp_hot.c​:2785
#6 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at
dump.c​:1392
#7 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01248,
is_eval=0)
at perl.c​:1967
#8 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x102826e4,
flags=64)
at perl.c​:1846
#9 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#10 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#11 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at
dump.c​:1392
#12 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01538,
is_eval=0)
at perl.c​:1967
#13 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x102826b4,
flags=64)
at perl.c​:1846
#14 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#15 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#16 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at
dump.c​:1392
#17 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01828,
is_eval=0)
at perl.c​:1967
#18 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x10282684,
flags=64)
at perl.c​:1846
#19 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#20 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#21 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at
dump.c​:1392
#22 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01b18,
is_eval=0)
at perl.c​:1967
#23 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x10282654,
flags=64)
at perl.c​:1846
#24 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
methname=0x101a2d2c "FILENO", flags=0) at perl.c​:1779
#25 0x1012302c in Perl_pp_fileno (my_perl=0x101c5988) at pp_sys.c​:645
#26 0x10092f24 in Perl_runops_debug (my_perl=0x101c5988) at
dump.c​:1392
#27 0x1001d7b4 in S_call_body (my_perl=0x101c5988, myop=0x7fe01e08,
is_eval=0)
at perl.c​:1967
#28 0x1001cdf0 in Perl_call_sv (my_perl=0x101c5988, sv=0x10282624,
flags=64)
at perl.c​:1846
#29 0x1001ca5c in Perl_call_method (my_perl=0x101c5988,
....etc...

The bug only effects bleadperl back to 5.6.0. 5.005_03 and back don't
go into a recursion.

schwern@​blackrider​:~$ bleadperl -lw ~/tmp/bug2.plx
Deep recursion on subroutine "Handle​::FILENO" at
/home/schwern/tmp/bug2.plx line 7.
Segmentation fault
schwern@​blackrider​:~$ perl5.6.1 -lw ~/tmp/bug2.plx
Deep recursion on subroutine "Handle​::FILENO" at
/home/schwern/tmp/bug2.plx line 7.
Segmentation fault
schwern@​blackrider​:~$ perl5.6.0 -lw ~/tmp/bug2.plx
Deep recursion on subroutine "Handle​::FILENO" at
/home/schwern/tmp/bug2.plx line 7.
Segmentation fault
schwern@​blackrider​:~$ perl5.004_05 -lw ~/tmp/bug2.plx
3
schwern@​blackrider​:~$ perl5.005_03 -lw ~/tmp/bug2.plx
3
schwern@​blackrider​:~$ perl5.004_04 -lw ~/tmp/bug2.plx
3
schwern@​blackrider​:~$ perl5.004 -lw ~/tmp/bug2.plx
3

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags​:
category=core
severity=low
---
Site configuration information for perl v5.7.3​:

Configured by schwern at Tue Mar 12 23​:27​:46 EST 2002.

Summary of my perl5 (revision 5.0 version 7 subversion 3 patch 15209)
configuration​:
Platform​:
osname=linux, osvers=2.4.17-ben0, archname=ppc-linux-thread-multi-
64int
uname='linux blackrider 2.4.17-ben0 #1 sun dec 23 18​:59​:02 est
2001 ppc unknown '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define
usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=define use64bitall=undef uselongdouble=undef
usemymalloc=y, bincompat5005=undef
Compiler​:
cc='cc', ccflags ='-D_GNU_SOURCE -D_REENTRANT -DDEBUGGING
-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64',
optimize='-g',
cppflags='-D_GNU_SOURCE -D_REENTRANT -DDEBUGGING
-fno-strict-aliasing -I/usr/local/include'
ccversion='', gccversion='2.95.4 (Debian prerelease)',
gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=87654321
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
ivtype='long long', ivsize=8, nvtype='double', nvsize=8,
Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries​:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lgdbm -ldbm -ldb -ldl -lm -lpthread -lc -lcrypt -lutil
perllibs=-lnsl -ldl -lm -lpthread -lc -lcrypt -lutil
libc=/lib/libc-2.2.5.so, so=so, useshrplib=false,
libperl=libperl.a
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-
rdynamic'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:
DEVEL15172

---
@​INC for perl v5.7.3​:
/home/schwern/lib/perl5/site_perl
/usr/local/bleadperl/lib/5.7.3/ppc-linux-thread-multi-64int
/usr/local/bleadperl/lib/5.7.3
/usr/local/bleadperl/lib/site_perl/5.7.3/ppc-linux-thread-multi-
64int
/usr/local/bleadperl/lib/site_perl/5.7.3
/usr/local/bleadperl/lib/site_perl
.

---
Environment for perl v5.7.3​:
HOME=/home/schwern
LANG=en_US
LANGUAGE=en
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/home/schwern/bin​:/usr/local/sbin​:/usr/sbin​:/sbin​:/usr/local/bin​:/usr/
bin​:/bin​:/usr/local/X11/bin​:/usr/bin/X11​:/usr/games
PERL5LIB=/home/schwern/lib/perl5/site_perl
PERL_BADLANG (unset)
SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jul 18, 2003

From @schwern

Still an issue in 5.8.1 RC2.

@p5pRT
Copy link
Author

p5pRT commented Dec 27, 2005

From markus.krumpoeck@cybirion.com

Created by markus.krumpoeck@cybirion.com

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags​:
  category=core
  severity=medium
---
Site configuration information for perl v5.8.4​:

Configured by Debian Project at Tue Mar 8 20​:31​:23 EST 2005.

Summary of my perl5 (revision 5 version 8 subversion 4) configuration​:
  Platform​:
  osname=linux, osvers=2.4.27-ti1211, archname=i386-linux-thread-multi
  uname='linux kosh 2.4.27-ti1211 #1 sun sep 19 18​:17​:45 est 2004 i686
gnulinux '
  config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN
-Dcccdlflags=-fPIC -Darchname=i386-linux -Dprefix=/usr
-Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr
-Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5
-Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.4
-Dsitearch=/usr/local/lib/perl/5.8.4 -Dman1dir=/usr/share/man/man1
-Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1
-Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib
-Dlibperl=libperl.so.5.8.4 -Dd_dosuid -des'
  hint=recommended, useposix=true, d_sigaction=define
  usethreads=define use5005threads=undef 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 -DTHREADS_HAVE_PIDS -DDEBIAN
-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN
-fno-strict-aliasing -I/usr/local/include'
  ccversion='', gccversion='3.3.5 (Debian 1​:3.3.5-9)', 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 =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib
  libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
  perllibs=-ldl -lm -lpthread -lc -lcrypt
  libc=/lib/libc-2.3.2.so, so=so, useshrplib=true, libperl=libperl.so.5.8.4
  gnulibc_version='2.3.2'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:
 

---
@​INC for perl v5.8.4​:
  /etc/perl
  /usr/local/lib/perl/5.8.4
  /usr/local/share/perl/5.8.4
  /usr/lib/perl5
  /usr/share/perl5
  /usr/lib/perl/5.8
  /usr/share/perl/5.8
  /usr/local/lib/site_perl
  .

---
Environment for perl v5.8.4​:
  HOME=/root
  LANG (unset)
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
 
PATH=/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/bin/X11
  PERL_BADLANG (unset)
  SHELL=/bin/bash

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl v5.8.7:

Configured by Debian Project at Mon Dec 12 13:59:01 UTC 2005.

Summary of my perl5 (revision 5 version 8 subversion 7) configuration:
  Platform:
    osname=linux, osvers=2.6.10, archname=i486-linux-gnu-thread-multi
    uname='linux rothera 2.6.10 #1 smp fri may 13 09:24:22 utc 2005 i686 
gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN 
-Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr 
-Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr 
-Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 
-Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.7 
-Dsitearch=/usr/local/lib/perl/5.8.7 -Dman1dir=/usr/share/man/man1 
-Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 
-Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl 
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib 
-Dlibperl=libperl.so.5.8.7 -Dd_dosuid -des'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef 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 -DTHREADS_HAVE_PIDS -DDEBIAN 
-fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE 
-D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN 
-fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='4.0.2 20050808 (prerelease) (Ubuntu 
4.0.1-4ubuntu9)', 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 =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.3.5.so, so=so, useshrplib=true, libperl=libperl.so.5.8.7
    gnulibc_version='2.3.5'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    SPRINTF0 - fixes for sprintf formatting issues - CVE-2005-3962


@INC for perl v5.8.7:
    /etc/perl
    /usr/local/lib/perl/5.8.7
    /usr/local/share/perl/5.8.7
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.8
    /usr/share/perl/5.8
    /usr/local/lib/site_perl
    /usr/local/lib/perl/5.8.4
    /usr/local/share/perl/5.8.4
    .


Environment for perl v5.8.7:
    HOME=/home/m2k
    LANG=de_AT@euro
    LANGUAGE=de_AT:de_DE:de:en_GB:en
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games:/root/bin:/data/utility/scripts/
    PERL_BADLANG (unset)
    SHELL=/bin/bash




Kind regards,
Markus Krumpöck

--
http://www.clausfischer.com/markus/

@p5pRT
Copy link
Author

p5pRT commented Dec 27, 2005

From @smpeters

On Tue, Dec 27, 2005 at 04​:31​:43AM -0800, Markus Krumpöck wrote​:

# New Ticket Created by Markus Krumpöck
# Please include the string​: [perl #38045]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=38045 >

This is a bug report for perl from markus.krumpoeck@​cybirion.com,
generated with the help of perlbug 1.35 running under perl v5.8.4 and v.5.8.7.

After upgrading from Debian Woody (PERL 5.6.1) to Debian Sarge (PERL 5.8.4) a
script which worked with the older version now stops with a segmentation
fault / core dump. The problem also appears with PERL 5.8.7 (Ubuntu 5.10).

By commenting out parts of the source-code in the PERL-Script I found out,
that the problem appears when calling the line

$result = $class->SUPER​::process(@​params);

A colleague of mine found out, that there seems to be some kind of endless
loop (maybe a recursive function call?)​:

(gdb) where
#0 0x0806965b in Perl_gv_fetchmethod ()
#1 0x080c3f82 in Perl_pp_method_named ()
#2 0x080c3dc5 in Perl_pp_method ()
#3 0x080bbdc9 in Perl_runops_standard ()
#4 0x080640c9 in Perl_call_sv ()
#5 0x08063fe5 in Perl_call_sv ()
#6 0x080bd2b1 in Perl_pp_print ()
#7 0x080bbdc9 in Perl_runops_standard ()
#8 0x080640c9 in Perl_call_sv ()
#9 0x08063fe5 in Perl_call_sv ()
#10 0x080bd2b1 in Perl_pp_print ()
#11 0x080bbdc9 in Perl_runops_standard ()
#12 0x080640c9 in Perl_call_sv ()
#13 0x08063fe5 in Perl_call_sv ()
#14 0x080bd2b1 in Perl_pp_print ()
#15 0x080bbdc9 in Perl_runops_standard ()

[...]

#20103 0x080bbdc9 in Perl_runops_standard ()
#20104 0x080640c9 in Perl_call_sv ()
#20105 0x08063fe5 in Perl_call_sv ()
#20106 0x080bd2b1 in Perl_pp_print ()
#20107 0x080bbdc9 in Perl_runops_standard ()
#20108 0x080640c9 in Perl_call_sv ()
#20109 0x08063fe5 in Perl_call_sv ()
#20110 0x080bd2b1 in Perl_pp_print ()
#20111 0x080bbdc9 in Perl_runops_standard ()
#20112 0x080640c9 in Perl_call_sv ()
#20113 0x08063fe5 in Perl_call_sv ()
#20114 0x080bd2b1 in Perl_pp_print ()
#20115 0x080bbdc9 in Perl_runops_standard ()
#20116 0x080635e8 in perl_run ()
#20117 0x080633f5 in perl_run ()
#20118 0x0805fb9f in main ()
(gdb)

Can you please send some source code that demonstrates the problem? Without
code to work with, it will be extremely difficult to help you.

@p5pRT
Copy link
Author

p5pRT commented Dec 27, 2005

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

@p5pRT
Copy link
Author

p5pRT commented Dec 27, 2005

From markus.krumpoeck@cybirion.com

Am Dienstag 27 Dezember 2005 14​:22 schrieb Steve Peters via RT​:

By commenting out parts of the source-code in the PERL-Script I found
out, that the problem appears when calling the line

$result = $class->SUPER​::process(@​params);

Can you please send some source code that demonstrates the problem?
Without code to work with, it will be extremely difficult to help you.

Please see attachments for complete code.

"main.pl" is the script started, which includes "Template.pm"​:

my $template = new WebApp​::Template ($config);

In "Template.pm" the segmentation fault happens when executing

$result = $class->SUPER​::process(@​params);

Kind regards,
Markus Krumpöck

--
http​://www.clausfischer.com/markus/

@p5pRT
Copy link
Author

p5pRT commented Dec 27, 2005

@p5pRT
Copy link
Author

p5pRT commented Dec 27, 2005

@p5pRT
Copy link
Author

p5pRT commented Dec 27, 2005

From guest@guest.guest.xxxxxxxx

You haven't included all the files necessary to run the example​: main.pl seems to need (at least)
the following additional modules​:

WebApp​::Output, WebApp​::System, WebApp​::Error, WebApp​::Input.

I take it that the 'Template' module from which WebApp​::Template inherits is the one from And
Wardley's template toolkit? If that's correct, the problem seems to be happening within template
toolkit. Which version of template toolkit are you using? If it's not the latest one, have you tried
upgrading?

Robin

@p5pRT
Copy link
Author

p5pRT commented Dec 27, 2005

From guest@guest.guest.xxxxxxxx

I've just had another thought. I don't think Perl 5.8 is binary compatible
with 5.6, and Template Toolkit has an XS component, so you probably
need to recompile it against 5.8 if you haven't already done that.

Robin

@p5pRT
Copy link
Author

p5pRT commented Dec 27, 2005

From @nwc10

On Tue, Dec 27, 2005 at 02​:36​:07PM +0100, Markus Krumpöck wrote​:

Am Dienstag 27 Dezember 2005 14​:22 schrieb Steve Peters via RT​:

By commenting out parts of the source-code in the PERL-Script I found
out, that the problem appears when calling the line

$result = $class->SUPER​::process(@​params);

Can you please send some source code that demonstrates the problem?
Without code to work with, it will be extremely difficult to help you.

Please see attachments for complete code.

This code is not complete, in that it can't be run without 4 modules that
you've not supplied, sample files, and installing 2 non-core modules.

Please send a complete example that works, and can be run stand alone to
recreate the problem. And given that you're using 2 non-core modules, it would
be better if your first worked with their author (Andy Wardley) to verify that
the problem is not in his code.

Until you are able to provide the examples sufficient for someone else to
recreate the crash, it's very hard for anyone else to help you further.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Dec 28, 2005

From markus.krumpoeck@cybirion.com

Am Dienstag 27 Dezember 2005 22​:53 schrieb Nicholas Clark via RT​:

Please send a complete example that works, and can be run stand alone to
recreate the problem. And given that you're using 2 non-core modules, it
would be better if your first worked with their author to verify that the
problem is not in his code.

Attachted to this mail you will find a minimal example, which produces an
segmentation fault with 5.8.7 (and 5.8.4) , but not with 5.6.1.

The problem may be in the "Filter​::Handle" - Module.

Kind regards,
Markus Krumpöck

--
http​://www.clausfischer.com/markus/

@p5pRT
Copy link
Author

p5pRT commented Dec 28, 2005

@p5pRT
Copy link
Author

p5pRT commented Dec 28, 2005

From @nwc10

On Wed, Dec 28, 2005 at 11​:06​:49AM +0100, Markus Krumpöck wrote​:

Attachted to this mail you will find a minimal example, which produces an
segmentation fault with 5.8.7 (and 5.8.4) , but not with 5.6.1.

I can get it down to this​:

#!perl -w
use strict;

sub TIEHANDLE {
  my ($class, $fh) = @​_;
  bless { fh => $fh }, $class;
}

sub PRINT {
  my $self = shift;
  my $fh = *{ $self->{fh} };
  print $fh @​_;
}

tie *STDOUT, 'main', \*STDOUT;

# use Devel​::Peek; Dump (*STDOUT); Dump (${*STDOUT{IO}});

print "Bang!\n";
__END__

The problem may be in the "Filter​::Handle" - Module.

I think it is. Well, it's more that it's exploiting some of the internals of
perl that changed between 5.6.x and 5.8.x, something I wasn't aware of.

In 5.6.x it turns out that tied filehandle magic is applied to the typeglob.
In 5.8.x it's applied to the IO directly.

The upshot is that the line

  my $fh = *{ $self->{fh} };

make a copy of values of the typeglob, without copying over the magic. So on
5.6.x $fh is a magic free typeglob pointing to the IO for STDOUT, so the call
to print on the next line sees no magic and calls the real print operator.

Whereas on 5.8.x that line still copies the typeglob, which still points to
the IO for STDOUT, only here the IO has the magic, so the call to print on the
next line sees the tie magic (still) and calls PRINT again. Which copies and
recurses, etc, until the C stack is blown.

If I change PRINT to avoid the typeglob copy​:

sub PRINT {
  my $self = shift;
  # my $fh = *{ $self->{fh} };
  print {$self->{fh}} @​_;
}

then it segfaults on both 5.6.x and 5.8.x

I don't know of a good way to temporarily untie the file handle inside PRINT
so that it could access the underlying file handle.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Dec 29, 2005

From RandyS@ThePierianSpring.org

Nicholas Clark wrote​:

On Wed, Dec 28, 2005 at 11​:06​:49AM +0100, Markus Krumpöck wrote​:

Attachted to this mail you will find a minimal example, which produces an
segmentation fault with 5.8.7 (and 5.8.4) , but not with 5.6.1.

I can get it down to this​:

#!perl -w
use strict;

sub TIEHANDLE {
my ($class, $fh) = @​_;
bless { fh => $fh }, $class;
}

sub PRINT {
my $self = shift;
my $fh = *{ $self->{fh} };
print $fh @​_;
}

tie *STDOUT, 'main', \*STDOUT;

# use Devel​::Peek; Dump (*STDOUT); Dump (${*STDOUT{IO}});

print "Bang!\n";
__END__

The problem may be in the "Filter​::Handle" - Module.

I think it is. Well, it's more that it's exploiting some of the internals of
perl that changed between 5.6.x and 5.8.x, something I wasn't aware of.

In 5.6.x it turns out that tied filehandle magic is applied to the typeglob.
In 5.8.x it's applied to the IO directly.

The upshot is that the line

my $fh = *{ $self->{fh} };

make a copy of values of the typeglob, without copying over the magic. So on
5.6.x $fh is a magic free typeglob pointing to the IO for STDOUT, so the call
to print on the next line sees no magic and calls the real print operator.

Whereas on 5.8.x that line still copies the typeglob, which still points to
the IO for STDOUT, only here the IO has the magic, so the call to print on the
next line sees the tie magic (still) and calls PRINT again. Which copies and
recurses, etc, until the C stack is blown.

If I change PRINT to avoid the typeglob copy​:

sub PRINT {
my $self = shift;
# my $fh = *{ $self->{fh} };
print {$self->{fh}} @​_;
}

then it segfaults on both 5.6.x and 5.8.x

I don't know of a good way to temporarily untie the file handle inside PRINT
so that it could access the underlying file handle.

Not to divert from the more important issue of solving this bug, but is
there anyway at all to work around this?

I was planning to try something like the above to solve a problem we
have in Module​::Build reporting test output to API clients like
CPANPLUS. We need to tie STDOUT before invoking Test​::Harness so it will
print live to normal stdout and also to an unbuffered string that we can
return to the client (eg. to eventually end up as a test report for
cpan-testers).

With apologies for the diversion,

Randy.

@p5pRT
Copy link
Author

p5pRT commented Dec 29, 2005

From nick@ing-simmons.net

Nicholas Clark <nick@​ccl4.org> writes​:

On Wed, Dec 28, 2005 at 11​:06​:49AM +0100, Markus Krumpöck wrote​:

Attachted to this mail you will find a minimal example, which produces an
segmentation fault with 5.8.7 (and 5.8.4) , but not with 5.6.1.

I can get it down to this​:

#!perl -w
use strict;

sub TIEHANDLE {
my ($class, $fh) = @​_;
bless { fh => $fh }, $class;
}

sub PRINT {
my $self = shift;
my $fh = *{ $self->{fh} };
print $fh @​_;
}

tie *STDOUT, 'main', \*STDOUT;

# use Devel​::Peek; Dump (*STDOUT); Dump (${*STDOUT{IO}});

print "Bang!\n";
__END__

The problem may be in the "Filter​::Handle" - Module.

I think it is. Well, it's more that it's exploiting some of the internals of
perl that changed between 5.6.x and 5.8.x, something I wasn't aware of.

In 5.6.x it turns out that tied filehandle magic is applied to the typeglob.
In 5.8.x it's applied to the IO directly.

Tk​::Event​::IO avoids that issue by copying the IO.
The Tk code is XS so here is a quick hack
that does rough equivalent as perl code.
Not sure if the '=' does the right thing on close/untie
and presumably we need to handle read case as well.

#!perl -w
use strict;

sub TIEHANDLE {
  my ($class, $fh) = @​_;
  open(my $copy,">&=",$fh);
  bless { fh => $copy }, $class;
}

sub PRINT {
  my $self = shift;
  my $fh = *{ $self->{fh} };
  print $fh @​_;
}

tie *STDOUT, 'main', \*STDOUT;

#use Devel​::Peek; Dump (*STDOUT); Dump (${*STDOUT{IO}});

print "Bang!\n";
__END__

@p5pRT
Copy link
Author

p5pRT commented Dec 29, 2005

From @rgs

Nicholas Clark wrote​:

The upshot is that the line

my $fh = *{ $self->{fh} };

make a copy of values of the typeglob, without copying over the magic. So on
5.6.x $fh is a magic free typeglob pointing to the IO for STDOUT, so the call
to print on the next line sees no magic and calls the real print operator.

Whereas on 5.8.x that line still copies the typeglob, which still points to
the IO for STDOUT, only here the IO has the magic, so the call to print on the
next line sees the tie magic (still) and calls PRINT again. Which copies and
recurses, etc, until the C stack is blown.

I don't know of a good way to temporarily untie the file handle inside PRINT
so that it could access the underlying file handle.

Maybe we should add a language-level construct level for that.
Something like :
  my $fh = *{ $self->{fh} }{IO};
(except that this one won't be backwards-compatible)

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2008

From @smpeters

The code below SEGFAULTS with Perls back to at least 5.8.1-RC3 through
up to date bleadperls.

use strict;

package TestHandle;
require Tie​::Handle;

use base qw(Tie​::Handle);

sub TIEHANDLE { print "<TestHandle>\n"; my $i; bless \$i, shift }
sub PRINT { print $self "<TestHandle>​: ", shift }

package main;
tie *STDOUT, "TestHandle";
print "Hello";

The actual output is...

<TestHandle>
Deep recursion on subroutine "TestHandle​::PRINT" at Foo2.pl line 12.
Segmentation fault (core dumped)

I'm certainly doing something wrong, but a SEGV is probably not the
right feedback to give the users.

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2008

From @schwern

Steve Peters (via RT) wrote​:

The code below SEGFAULTS with Perls back to at least 5.8.1-RC3 through
up to date bleadperls.

$self is never defined, this code doesn't compile.

use strict;

package TestHandle;
require Tie​::Handle;

use base qw(Tie​::Handle);

sub TIEHANDLE { print "<TestHandle>\n"; my $i; bless \$i, shift }
sub PRINT { print $self "<TestHandle>​: ", shift }

package main;
tie *STDOUT, "TestHandle";
print "Hello";

The actual output is...

<TestHandle>
Deep recursion on subroutine "TestHandle​::PRINT" at Foo2.pl line 12.
Segmentation fault (core dumped)

I'm certainly doing something wrong, but a SEGV is probably not the
right feedback to give the users.

It segfaults because you're blowing out the stack, which isn't good but it
does give the right feedback​: 'Deep recursion on subroutine
"TestHandle​::PRINT"'. You're trying to use your own tied handle in PRINT it
goes into infinite recursion. You have to use the underlying bare handle.

--
You know what the chain of command is? It's the chain I go get and beat you
with 'til you understand who's in ruttin' command here.
  -- Jayne Cobb, "Firefly"

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2008

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

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2008

From @smpeters

On Thu Jan 03 20​:50​:53 2008, schwern wrote​:

Steve Peters (via RT) wrote​:

The code below SEGFAULTS with Perls back to at least 5.8.1-RC3 through
up to date bleadperls.

$self is never defined, this code doesn't compile.

use strict;

package TestHandle;
require Tie​::Handle;

use base qw(Tie​::Handle);

sub TIEHANDLE { print "<TestHandle>\n"; my $i; bless \$i, shift }
sub PRINT { print $self "<TestHandle>​: ", shift }

package main;
tie *STDOUT, "TestHandle";
print "Hello";

The actual output is...

<TestHandle>
Deep recursion on subroutine "TestHandle​::PRINT" at Foo2.pl line 12.
Segmentation fault (core dumped)

I'm certainly doing something wrong, but a SEGV is probably not the
right feedback to give the users.

It segfaults because you're blowing out the stack, which isn't good but it
does give the right feedback​: 'Deep recursion on subroutine
"TestHandle​::PRINT"'. You're trying to use your own tied handle in
PRINT it
goes into infinite recursion. You have to use the underlying bare handle.

OK, here's the right code.

#!perl -w

use strict;

package TestHandle;
require Tie​::Handle;

use base qw(Tie​::Handle);

sub TIEHANDLE { print "<TestHandle>\n"; my $i; bless \$i, shift }

sub PRINT { print "<TestHandle>​: ", shift }

package main;

tie *STDOUT, "TestHandle";

print "Hello";

Now, that you say it and I'm awake (coffee++), I see what's going on.

The "Deep recursion" warning is coming from sub_crush_depth() from
pp_entersub(). The warnings come when you reach a depth of 100
recursively called subroutines. This example, obviously, keeps going
until it finally blows the stack. Is there any argument for not die'ing
at some point because the level of recursion is just too high? Or is
this a special case where we should be looking for the tie to STDOUT and
stomping out this recursion early?

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2008

From @hvds

"Steve Peters via RT" <perlbug-followup@​perl.org> wrote​:
:The "Deep recursion" warning is coming from sub_crush_depth() from
:pp_entersub(). The warnings come when you reach a depth of 100
:recursively called subroutines. This example, obviously, keeps going
:until it finally blows the stack. Is there any argument for not die'ing
:at some point because the level of recursion is just too high? Or is
:this a special case where we should be looking for the tie to STDOUT and
:stomping out this recursion early?

In the general case​: recursion is good; unless you are sufficiently
halting-aware to know that it is a hard loop, or sufficiently stack-aware
to know that you're about to bust it, it would be wrong to die.

(As it happens, a while back I fixed a bug when recursion depth exceeds
64K, tickled by a maths problem I was solving; I have had it successfully
reach and return from recursion depths > 300K since fixing that.)

Hugo

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2008

From @schwern

hv@​crypt.org wrote​:

"Steve Peters via RT" <perlbug-followup@​perl.org> wrote​:
:The "Deep recursion" warning is coming from sub_crush_depth() from
:pp_entersub(). The warnings come when you reach a depth of 100
:recursively called subroutines. This example, obviously, keeps going
:until it finally blows the stack. Is there any argument for not die'ing
:at some point because the level of recursion is just too high? Or is
:this a special case where we should be looking for the tie to STDOUT and
:stomping out this recursion early?

In the general case​: recursion is good; unless you are sufficiently
halting-aware to know that it is a hard loop, or sufficiently stack-aware
to know that you're about to bust it, it would be wrong to die.

(As it happens, a while back I fixed a bug when recursion depth exceeds
64K, tickled by a maths problem I was solving; I have had it successfully
reach and return from recursion depths > 300K since fixing that.)

What he said. Slapping a limit on recursion depth sounds like training wheels.

But on the ideal rule that no Perl program should result in a segfault, it
would be dandy if Perl could die gracefully. However, it's not urgent as it
does at least get out a last gasp to the user before going under. Would the
error message say much more?

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2008

From ben@morrow.me.uk

Quoth schwern@​pobox.com (Michael G Schwern)​:

hv@​crypt.org wrote​:

In the general case​: recursion is good; unless you are sufficiently
halting-aware to know that it is a hard loop, or sufficiently stack-aware
to know that you're about to bust it, it would be wrong to die.

(As it happens, a while back I fixed a bug when recursion depth exceeds
64K, tickled by a maths problem I was solving; I have had it successfully
reach and return from recursion depths > 300K since fixing that.)

What he said. Slapping a limit on recursion depth sounds like
training wheels.

But on the ideal rule that no Perl program should result in a segfault, it
would be dandy if Perl could die gracefully. However, it's not urgent as it
does at least get out a last gasp to the user before going under. Would the
error message say much more?

If you could die just before (and only just before) the stack gives out,
that would be catchable from Perl, which could be useful. While catching
SIGSEGV is somewhat equivalent, it's a lot more dodgy​: it's not given
that returning (or calling longjmp) from a SEGV handler is even remotely
safe.

Ben

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2008

From @iabyn

On Sat, Jan 05, 2008 at 01​:04​:16AM +0000, Ben Morrow wrote​:

If you could die just before (and only just before) the stack gives out,
that would be catchable from Perl, which could be useful.

But as far as I'm aware, there's no portable way of checking the stack
limit in C.

--
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 Sep 26, 2010

From @cpansprout

On Wed Dec 28 08​:56​:35 2005, nicholas wrote​:

On Wed, Dec 28, 2005 at 11​:06​:49AM +0100, Markus Krumpöck wrote​:

I don't know of a good way to temporarily untie the file handle inside
PRINT
so that it could access the underlying file handle.

Nicholas Clark

Don’t tied scalars do exactly that?

@p5pRT
Copy link
Author

p5pRT commented Dec 10, 2017

From zefram@fysh.org

As with [perl #3054], this test case is calling for infinite recursion,
which cannot be made to work. This ticket should be closed.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 10, 2017

From @cpansprout

On Sun, 10 Dec 2017 14​:43​:23 -0800, zefram@​fysh.org wrote​:

As with [perl #3054], this test case is calling for infinite recursion,
which cannot be made to work. This ticket should be closed.

With string and reference overloading, an overload method can return the overloaded object itself, to bypass overloading. Wouldn’t it make sense to have a similar mechanism for tied handles?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Dec 11, 2017

From zefram@fysh.org

Father Chrysostomos via RT wrote​:

With string and reference overloading, an overload method can return
the overloaded object itself, to bypass overloading. Wouldn't it make
sense to have a similar mechanism for tied handles?

That really only makes sense for those few unary overloads where the
operation will be redirected to whatever value is returned. Tying is
less direct than overloading, making the tied object less available to the
methods, and is short of unary operations with such redirection semantics.
So it's certainly not easy to implement that sort of thing for tying.

Tie​::StdHandle does have some redirection semantics of that nature,
so it would make some kind of sense there. But it doesn't strike me
as a pattern to be encouraged. Ties that want to redirect operations
to some underlying object should use composition and should contain the
underlying object; claiming to *be* the underlying object is a mechanism
that doesn't play nicely. Especially with itself.

Anyway, such features are off topic for this ticket.

-zefram

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