develooper 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)




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About