Front page | perl.perl5.porters |
Postings from April 2010
[perl #74196] No equivalent of POSIX::_exit() for MSWin32 pseudo-processes?
From:
perl@0ne.us
Date:
April 10, 2010 05:09
Subject:
[perl #74196] No equivalent of POSIX::_exit() for MSWin32 pseudo-processes?
Message ID:
rt-3.6.HEAD-6227-1270882049-1563.74196-75-0@perl.org
# New Ticket Created by "perl@0ne.us"
# Please include the string: [perl #74196]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=74196 >
This is a bug report for perl from apocal@cpan.org,
generated with the help of perlbug 1.39 running under perl 5.10.1.
-----------------------------------------------------------------
[Please describe your issue here]
Hello,
I am filing this perlbug after some experimentation and talking with
Jan Dubois ( jdb ) for Perl+MSWin32.
The problem is that I am doing fork under MSWin32 and wanted to exit
the child process cleanly. What this
means is that no END or DESTROY blocks gets executed. Running "perldoc
-f exit" clearly shows that you need to use
POSIX::_exit() to do a real exit. However, under MSWin32 using that will
terminate the entire process!
At first I was clueless on how to simulate the same POSIX behavior
under MSWin32. I hopped over to irc and
caught Jan online. He was very helpful, helping me to work out the root
cause. After some discussion, he helped me
to discover that CORE::kill( KILL => $$ ) will work on a pseudo-process.
I was happy to find that it didn't execute
extra code, and that's exactly what I wanted. However, Jan noted that
doing it this way will leak memory. I confirmed
that it does leak every time I fork a pseudo-process and exit it via
kill. However, my calculations were unscientific
and I simply took Jan's word that doing it that way wasn't good.
After talking with Jan again, we agreed that this definitely should
be fixed in a future version of Perl, and
he told me to go file the perlbug. The fix would be to make
POSIX::_exit() also work for pseudo-processes. While filing
the perlbug I golfed the testcase ( it originally included POE and a
couple more modules! ) and in the process of
playing with it I noticed some things:
* Running the testcase via "perl test.pl 1 0" will result in the
warn being printed twice
* This is expected, I just included it here as a "proof" that
END gets executed in the child
* Running the testcase via "perl test.pl 1 1" will result in the
warn being printed once
* This is the "perfect" behavior, but it leaks memory like Jan said
* Looking at the testcase, I had to add the "next if $$ < 0" code
* I wonder why this has to be done? At first I was experiencing
weird exponential memory usage
and had my process being OOMkilled after a measly 100 loops or
so. Then after digging around
the answer was that the loop was continuing in the child! So, a
forked child trying to fork more
children... no wonder why it was blowing up hardcore! Is this
also a bug? Under linux
this testcase doesn't run the loop in the child...
* If you comment out the "next if $$ < 0" line and run ( "perl
test.pl 2 1" ) it ends up running the
loop in the child, and you end up with 3 prints of "Hello from
child" - does that mean CORE::kill failed
to kill the process? However, the END block didn't trigger...
But, "perl test.pl 2 0" triggered the
END block as expected...
* Playing around with the testcase I got more and more confused. Why
does CORE::kill() return 0? When I
started to comment out various things in my quest to further
understand this I noticed that sometimes
the END doesn't get triggered even if I wanted it to happen! (
"perl test.pl 1" )
* Running the testcase on my Ubuntu linux system, CORE::kill worked
( no END triggering )
* Also, using die resulted in END being executed in the child as
expected...
* BUT, doing "perl test.pl 1" resulted in END being executed
twice! ( while on MSWin32 it doesnt... )
At this point I'm just handing the baton over to the p5p wizards. I
hope Jan/p5p can look at this someday and
tell me if it's really a bug or just an expected side effect that I
missed. By digging into this I learned something about
Perl and how it interacts with MSWin32! However, I got more confused the
more I tried to dig into this. I finally decided
to give up fooling around with the testcase and submit the perlbug.
Please let me know how I can help with this, as I would
love to have the issue fully resolved so I can patch my favorite module
( POE ) to work even better on MSWin32 :)
My system info:
Windows XP Professional 32bit SP3
Strawberry Bootperl 5.10.1
Intel Core2Duo T5750@2ghz + 3GB of ram
Here's the testcase:
#!/usr/bin/perl
use strict; use warnings;
END {
warn "THIS SHOULD BE PRINTED ONCE!";
}
for ( 0 .. ($ARGV[0] - 1) ) {
next if $$ < 0; # needed to stop loop in child ( a bug? )
warn "Loop $_";
my $pid = fork;
unless ( $pid ) {
warn "Hello from child ($$)";
if ( defined $ARGV[1] ) {
if ( $ARGV[1] ) {
warn "kill: " . CORE::kill( KILL => $$ );
} else {
die;
}
} else {
# do nothing?
}
} else {
warn "Hello from parent ($$)";
wait;
}
}
[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=high
---
Site configuration information for perl 5.10.1:
Configured by win32-vanilla at Sun Nov 8 10:38:35 2009.
Summary of my perl5 (revision 5 version 10 subversion 1) configuration:
Platform:
osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
uname='Win32 bootperl 5.10.1.0 #1 7 i386'
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='gcc', ccflags =' -s -O2 -DWIN32 -DHAVE_DES_FCRYPT
-DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS
-fno-strict-aliasing -DPERL_MSVCRT_READFIX',
optimize='-s -O2',
cppflags='-DWIN32'
ccversion='', gccversion='3.4.5', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long
long', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='g++', ldflags ='-s -L"C:\bootperl\perl\lib\CORE"
-L"C:\bootperl\c\lib"'
libpth=C:\bootperl\c\lib
libs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32
perllibs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool
-lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid
-lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32
libc=, so=dll, useshrplib=true, libperl=libperl510.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-mdll -s -L"C:\bootperl\perl\lib\CORE"
-L"C:\bootperl\c\lib"'
Locally applied patches:
---
@INC for perl 5.10.1:
C:/bootperl/perl/lib
C:/bootperl/perl/site/lib
C:\bootperl\perl\vendor\lib
.
---
Environment for perl 5.10.1:
HOME (unset)
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;c:\Program
Files\ATI
Technologies\ATI.ACE\Core-Static;C:\WINDOWS\system32\WindowsPowerShell\v1.0;C:\bootperl\c\bin;C:\bootperl\perl\bin
PERL_BADLANG (unset)
SHELL (unset)
-
[perl #74196] No equivalent of POSIX::_exit() for MSWin32 pseudo-processes?
by perl@0ne.us