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

On Win32 setting any encoding on STD(IN|OUT|ERR) with binmode causes subsequent fork calls to crash perl #11274

Closed
p5pRT opened this issue Apr 23, 2011 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 23, 2011

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

Searchable as RT89142$

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2011

From @wchristian

Created by @wchristian

This piece of code crashes when it reaches the fork call and never reaches the print statement​:

  perl -e "binmode STDOUT, '​:encoding(greek)'; fork; print 1;"

Instead of STDOUT, these can also be used and will cause the crash too​: STDIN, STDERR. Instead of greek, any other encoding can be used as well and will also cause the crash.

Perl Info

Flags:
     category=core
     severity=low

Site configuration information for perl 5.10.1:

Configured by SYSTEM at Tue Jan 26 23:14:33 2010.

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

   Platform:
     osname=MSWin32, osvers=5.00, archname=MSWin32-x86-multi-thread
     uname=''
     config_args='undef'
     hint=recommended, useposix=true, d_sigaction=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='C:/MinGW/bin/gcc.exe', ccflags ='-DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX -DHASATTRIBUTE -fno-strict-aliasing -mms-bitfields',
     optimize='-O2',
     cppflags='-DWIN32'
     ccversion='', gccversion='4.5.2', gccosandvers=''
     intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
     d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8
     ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8
     alignbytes=8, prototype=define
   Linker and Libraries:
     ld='C:\MinGW\bin\g++.exe', ldflags ='-L"C:\Perl\lib\CORE"'
     libpth=\lib
     libs=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 -lmsvcrt
     perllibs=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 -lmsvcrt
     libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl510.lib
     gnulibc_version=''
   Dynamic Linking:
     dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
     cccdlflags=' ', lddlflags='-mdll -L"C:\Perl\lib\CORE"'

Locally applied patches:
     ACTIVEPERL_LOCAL_PATCHES_ENTRY
     0abd0d disable non-unicode case insensitive trie matching


@INC for perl 5.10.1:
     C:/Perl/site/lib
     C:/Perl/lib
     .


Environment for perl 5.10.1:
     CYGWIN=nodosfilewarning
     HOME=c:\Dokumente und Einstellungen\Administrator
     LANG (unset)
     LANGUAGE (unset)
     LD_LIBRARY_PATH (unset)
     LOGDIR (unset)
     PATH=C:\Programme\PC Connectivity Solution\;C:\Programme\ActiveState Komodo IDE 6;C:\Programme\NVIDIA Corporation\PhysX\Common;C:\wamp\bin\php\php5.3.0\;C:\Programme\ImageMagick-6.6.7-Q16;C:\Perl\bin;C:\Perl\site\bin;C:\Programme\CollabNet Subversion Server\;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\Programme\Gemeinsame Dateien\Lenovo;C:\Programme\Microsoft SQL Server\90\Tools\binn\;C:\Programme\WinSCP\;C:\Programme\VDMSound;C:\Programme\Subversion;C:\Programme\QuickTime\QTSystem\;C:\WINDOWS\system32\WindowsPowerShell\v1.0;C:\Programme\Intel\WiFi\bin\;c:\Programme\PostgreSQL\8.4\bin\;C:\Programme\TortoiseSVN\bin;C:\Programme\Git\cmd;c:\MinGW\dmake\;C:\MinGW\bin\;C:\blast\bin;C:\Programme\OpenVPN\bin;c:\Sysinternals;c:\Programme\MySQL\MySQL Server 5.1\bin\;C:\cygwin\bin;C:\Programme\Graphviz2.26.3\bin;C:\Programme\TortoiseGit\bin
     PERL_BADLANG (unset)
     SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2011

From @kmx

just adding cross reference to related RT

http​://rt.perl.org/rt3/Ticket/Display.html?id=85366

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2011

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

@p5pRT
Copy link
Author

p5pRT commented May 17, 2011

From @iabyn

On Sat, Apr 23, 2011 at 03​:12​:17AM -0700, Christian Walde wrote​:

This piece of code crashes when it reaches the fork call and never reaches the print statement​:

 perl \-e "binmode STDOUT\, '​:encoding\(greek\)'; fork; print 1;"

Instead of STDOUT, these can also be used and will cause the crash too​:
STDIN, STDERR. Instead of greek, any other encoding can be used as well
and will also cause the crash.

Just to note, that since this is using the ithreads pseudo-fork on win32,
the issue can also be reproduced on linux with blead using threads​:

$ ./perl -Ilib -e "use threads; binmode STDOUT, '​:encoding(greek)'; async { print 1} print 1"
1Segmentation fault (core dumped)

--
You're only as old as you look.

@p5pRT
Copy link
Author

p5pRT commented May 17, 2011

From @nwc10

On Tue, May 17, 2011 at 10​:10​:42AM +0100, Dave Mitchell wrote​:

On Sat, Apr 23, 2011 at 03​:12​:17AM -0700, Christian Walde wrote​:

This piece of code crashes when it reaches the fork call and never reaches the print statement​:

 perl \-e "binmode STDOUT\, '​:encoding\(greek\)'; fork; print 1;"

Instead of STDOUT, these can also be used and will cause the crash too​:
STDIN, STDERR. Instead of greek, any other encoding can be used as well
and will also cause the crash.

Just to note, that since this is using the ithreads pseudo-fork on win32,
the issue can also be reproduced on linux with blead using threads​:

$ ./perl -Ilib -e "use threads; binmode STDOUT, '​:encoding(greek)'; async { print 1} print 1"
1Segmentation fault (core dumped)

And I think it's a "hard" problem to solve, because the PerlIO system wants to
sit at both the bottom and top, conceptually. sv.

perl_clone_using() has this​:

#ifdef PERLIO_LAYERS
  /* Clone PerlIO tables as soon as we can handle general xx_dup() */
  PerlIO_clone(aTHX_ proto_perl, param);
#endif

which makes sense. However, PerlIO also wants to provide fully perl-space
layers, which means that they require a working interpreter to work. Which
isn't the case until the interpreter is fully cloned.

Gah! This isn't thought through.

I think a solution might be to change things so that​:

a​: all IO continues to be in parent interpreter for the duration of cloning
b​: PerlIO cloning happens "late"

b is easy. a probably is not. I'm not even sure if it can be done without
needing a second piece of thread local storage, because you end up needing
*some* of the code to think that the "current" interpreter is the one under
construction, and other code (at least the IO code) to think that the
"current" interpreter is the parent.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Aug 17, 2016

From @dcollinsn

This is fixed in 5.24.0​:

dcollins@​nightshade64​:~$ perl5.22.0-thread-multi -wle "use threads; binmode STDOUT, '​:encoding(greek)'; async { print 1} print 1"
1
Segmentation fault
dcollins@​nightshade64​:~$ perl5.24.0-thread-multi -wle "use threads; binmode STDOUT, '​:encoding(greek)'; async { print 1} print 1"
1
Perl exited with active threads​:
  1 running and unjoined
  0 finished and unjoined
  0 running and detached

Bisect says it was fixed by​:

0ee3fa2 is the first new commit
commit 0ee3fa2
Author​: Vincent Pit <perl@​profvince.com>
Date​: Fri Aug 28 14​:17​:00 2015 -0300

  Properly duplicate PerlIO​::encoding objects

  PerlIO​::encoding objects are usually initialized by calling Perl methods,
  essentially from the pushed() and getarg() callbacks. During cloning, the
  PerlIO API will by default call these methods to initialize the duplicate
  struct when the PerlIOBase parent struct is itself duplicated. This does
  not behave so well because the perl interpreter is not ready to call
  methods at this point, for the stacks are not set up yet.

  The proper way to duplicate the PerlIO​::encoding object is to call sv_dup()
  on its members from the dup() PerlIO callback. So the only catch is to make
  the getarg() and pushed() calls implied by the duplication of the underlying
  PerlIOBase object aware that they are called during cloning, and make them
  wait that the control flow returns to the dup() callback. Fortunately,
  getarg() knows since its param argument is then non-null, and its return
  value is passed immediately to pushed(), so it is enough to tag this
  returned value with a custom magic so that pushed() can see it is being
  called during cloning.

  This fixes [RT #31923].

:100644 100644 f79df008098f4df1f97f7f104171b89c31049a90 34c2e2436a2a14e776725ca5c40a74c8f0a4bdb7 M MANIFEST
:040000 040000 ce197fb6173fb13198e80fa4a743778f88a797d4 16376953f016ecdaf6dbe144a432d6d683e00229 M ext

I'm marking this resolved.

--
Respectfully,
Dan Collins

@p5pRT
Copy link
Author

p5pRT commented Aug 17, 2016

@dcollinsn - 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