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

No equivalent of POSIX::_exit() for MSWin32 pseudo-processes? #10295

Open
p5pRT opened this issue Apr 10, 2010 · 5 comments
Open

No equivalent of POSIX::_exit() for MSWin32 pseudo-processes? #10295

p5pRT opened this issue Apr 10, 2010 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 10, 2010

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

Searchable as RT74196$

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2010

From @apocalypse

Created by apocal@cpan.org

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;
  }
}

Perl Info

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)


@p5pRT
Copy link
Author

p5pRT commented Feb 17, 2017

From @jkeenan

This ticket has received no response in nearly seven years. To facilitate discussion, I am attaching the test program supplied by the original poster. I am also attaching the STDERR output I got from running the test program on perl-5.24.1 on Linux.

Could we get the test program run on an up-to-date perl on Windows?

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Feb 17, 2017

From @jkeenan

74196-fork.pl

#!/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;
    }
}

@p5pRT
Copy link
Author

p5pRT commented Feb 17, 2017

From @jkeenan

Loop 0 at 74196-fork.pl line 11.
Hello from parent (15338) at 74196-fork.pl line 26.
Hello from child (15339) at 74196-fork.pl line 14.
Loop 1 at 74196-fork.pl line 11.
Hello from parent (15339) at 74196-fork.pl line 26.
Hello from child (15340) at 74196-fork.pl line 14.
Loop 2 at 74196-fork.pl line 11.
Hello from parent (15340) at 74196-fork.pl line 26.
Hello from child (15341) at 74196-fork.pl line 14.
THIS SHOULD BE PRINTED ONCE! at 74196-fork.pl line 6.
THIS SHOULD BE PRINTED ONCE! at 74196-fork.pl line 6.
Loop 2 at 74196-fork.pl line 11.
Hello from parent (15339) at 74196-fork.pl line 26.
Hello from child (15342) at 74196-fork.pl line 14.
THIS SHOULD BE PRINTED ONCE! at 74196-fork.pl line 6.
THIS SHOULD BE PRINTED ONCE! at 74196-fork.pl line 6.
Loop 1 at 74196-fork.pl line 11.
Hello from parent (15338) at 74196-fork.pl line 26.
Hello from child (15343) at 74196-fork.pl line 14.
Loop 2 at 74196-fork.pl line 11.
Hello from parent (15343) at 74196-fork.pl line 26.
Hello from child (15344) at 74196-fork.pl line 14.
THIS SHOULD BE PRINTED ONCE! at 74196-fork.pl line 6.
THIS SHOULD BE PRINTED ONCE! at 74196-fork.pl line 6.
Loop 2 at 74196-fork.pl line 11.
Hello from parent (15338) at 74196-fork.pl line 26.
Hello from child (15345) at 74196-fork.pl line 14.
THIS SHOULD BE PRINTED ONCE! at 74196-fork.pl line 6.
THIS SHOULD BE PRINTED ONCE! at 74196-fork.pl line 6.

@p5pRT
Copy link
Author

p5pRT commented Feb 17, 2017

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

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