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

every OS child procs hangs forever if there is a blocked flock() in a win32 psuedofork #14320

Open
p5pRT opened this issue Dec 10, 2014 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 10, 2014

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

Searchable as RT123402$

@p5pRT
Copy link
Author

p5pRT commented Dec 10, 2014

From @bulk88

based on work in ingydotnet/inline-c-pm#31

on HP-UX (any posix perl is good enough for the example)

~$perl hang.pl
core delete-me2 hang.pl refreshperl
delete-me delete-me3 perl the_lock
~$core delete-me2 hang.pl refreshperl
delete-me delete-me3 perl the_lock

~$perl -v

This is perl, v5.8.3 built for PA-RISC1.1-thread-multi
(with 8 registered patches, see perl -V for more detail)

on Win32 with psuedofork 5.21.6

C:\sources\hang>perl hang.pl
Volume in drive C has no label.
Volume Serial Number is 4C2D-0BFA

Directory of C:\sources\hang

12/09/2014 11:49 PM <DIR> .
12/09/2014 11:49 PM <DIR> ..
12/09/2014 11:45 PM 404 hang.pl
12/09/2014 11:50 PM 0 the_lock
2 File(s) 404 bytes
2 Dir(s) 1,918,545,920 bytes free
*****hanged forever******

This is because CloseHandle or kernel mode equivelent during process
exit resource cleanup is a blocking call that prevents the process
object from exiting untill all its resources are freed. "dir" AKA
cmd.exe inherited the handle in the flock from the parent OS process's
child psudofork (note the "dir" was launched from the parent
psuedoprocess). Adding "$^F = -1;" before the fork on Win32 Perl is of
no help (the default is "2" on Win32 Perl (and all Perls I think). So
$^F is either broken or NA (Im not sure what its supposed to exactly do
in pp_sys.c), or needs to be implemented for Win32 perl. Also in code I
dont see any uses of FD_CLOEXEC compiled in but I'm not sure if its
because of "#if defined(HAS_FCNTL) && defined(F_SETFD)" or outer
enclosing CPP macros. Is Win32 Perl supposed to support (in libc or
emulated in win32/win32.c like alot of other posix things) FD_CLOEXEC
and $^F? (assuming $^F does what I think its supposed to do).

This bug did/does affect a real world CPAN module so its marked medium
priority.

related reading
http://www.agent31.eu/2007/01/perl-windows-and-file-locking.html
http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx but
EXTENDED_STARTUPINFO_PRESENT isn't supported in XP/2003, so perl would
have to serialize in perlhost.h/PERL_IMPLICIT_SYS, and remove then readd
the inherit flag to libc file handles (good enough, rather than using
debugging apis to get a list of all file handles in the process from NT
kernel) with
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724935%28v=vs.85%29.aspx
SetHandleInformation , if you think about it, isn't SetHandleInformation
and HANDLE_FLAG_INHERIT the Win32 equivelent to FD_CLOEXEC?

So what is the plan for this bug? comments from p5p?

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.21.6:

Configured by Owner at Thu Nov 13 18:20:06 2014.

Summary of my perl5 (revision 5 version 21 subversion 6) configuration:
  Derived from: 5e1acb3ae8d10f0a0404ec4d30afb925b08b53fd
  Ancestor: b255a112693312907754193cdbc1648d9182cb0d
  Platform:
    osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    useithreads=define, usemultiplicity=define
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cl', ccflags ='-nologo -GF -W3 -Od -MD -Zi -DDEBUGGING -G7 -GL 
-DWIN32 -D_CONSOLE -DNO_STRICT  -DPERL_TEXTMODE_SCRIPTS 
-DPERL_HASH_FUNC_ONE_AT_A_TIME -DNO_MATHOMS -DPERL_IMPLICIT_CONTEXT 
-DPERL_IMPLICIT_SYS -DUSE_PERLIO -D_USE_32BIT_TIME_T',
    optimize='-Od -MD -Zi -DDEBUGGING -G7 -GL',
    cppflags='-DWIN32'
    ccversion='13.10.6030', gccversion='', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234, 
doublekind=3
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8, 
longdblkind=0
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', 
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='link', ldflags ='-nologo -nodefaultlib -debug  -opt:ref,icf  
-libpath:"c:\perl521\lib\CORE"  -machine:x86'
    libpth="C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\lib"
    libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  
netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib 
odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
    perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib 
winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib 
oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  
version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
    libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl521.lib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug  
-opt:ref,icf  -libpath:"c:\perl521\lib\CORE"  -machine:x86'

Locally applied patches:
    uncommitted-changes
    02b4b73f6c4578c66ae7106592964b8853d4db30
    45e05eceb42cd889a80ef0875887fcb62181cbb6
    225b72a0c1e8cf621f10ed445e0260410082bfc6
    7f871da7cac3993a56343b032f9d7eff91422224
    0b68901531d0a01506365798f883b5f08b1adb89
    a87204c1df9892bf05451407ab107a76ece4810b
    5e1acb3ae8d10f0a0404ec4d30afb925b08b53fd


@INC for perl 5.21.6:
    C:/perl521/site/lib
    C:/perl521/lib
    .


Environment for perl 5.21.6:
    HOME (unset)
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=C:\perl521\bin;C:\Program Files\Microsoft Visual Studio .NET 
2003\Common7\IDE;C:\Program Files\Microsoft Visual Studio .NET 
2003\VC7\BIN;C:\Program Files\Microsoft Visual Studio .NET 
2003\Common7\Tools;C:\Program Files\Microsoft Visual Studio .NET 
2003\Common7\Tools\bin\prerelease;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\wbem;
    PERL_BADLANG (unset)
    SHELL (unset)


@p5pRT
Copy link
Author

p5pRT commented Dec 10, 2014

From @bulk88

hang.pl

use Fcntl ':flock';
my $file = 'the_lock';

$^F = -1;
if(fork == 0){
    sleep 1;
    open my $lockfh, '>', $file or die "lockfile $file: $!";
    flock($lockfh, LOCK_EX) or die "flock: $!\n";
    flock($lockfh, LOCK_UN);
}
open my $lockfh, '>', $file or die "lockfile $file: $!";
flock($lockfh, LOCK_EX) or die "flock: $!\n";
sleep 2;
system($^O eq 'MSWin32' ? 'dir' : 'ls');
flock($lockfh, LOCK_UN);

@p5pRT
Copy link
Author

p5pRT commented Dec 10, 2014

From @tonycoz

This doesn't hang on Windows 7 x64.

Tony

@p5pRT
Copy link
Author

p5pRT commented Dec 10, 2014

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

@p5pRT
Copy link
Author

p5pRT commented Dec 10, 2014

From @bulk88

Hangs on Server 2003 R2 SP2 x64 and XP SP3 x86 for me. Ill make a guess and say it hangs on < NT 6.0 kernel.
--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Jul 22, 2015

From @bulk88

Related reading http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Aug 3, 2015

From @bulk88

I tested hang.pl on my Win7 32 bit. It didn't hang. That confirms its NT <6 bug.

--
bulk88 ~ bulk88 at hotmail.com

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

3 participants