Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Perl: porters

[perl #88840] t/op/fork.t blocks in external process test on Win32

 

 

Perl porters RSS feed   Index | Next | Previous | View Threaded


perlbug-followup at perl

Apr 18, 2011, 6:05 AM

Post #1 of 8 (277 views)
Permalink
[perl #88840] t/op/fork.t blocks in external process test on Win32

# New Ticket Created by Tony Cook
# Please include the string: [perl #88840]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=88840 >


This is a bug report for perl from tony [at] develop-help,
generated with the help of perlbug 1.39 running under perl 5.14.0.


-----------------------------------------------------------------
[Please describe your issue here]

t/op/fork.t blocks running the test code:

system $^X, "-e", "if (\$pid=fork){kill(9, \$pid)} else {sleep 5}";

This leaves a process running that Ctrl-C does not kill and needs to be
killed with Task Manager.

Simply reproducable with:

..\perl -I..\lib -le "if ($pid=fork){ kill 9, $pid; } else { sleep 5;}"

Loading a non-trivial module prevents the lockup:

..\perl -I..\lib -MEncode -le "if ($pid=fork){ kill 9, $pid; } else { sleep 5;}"

Modifying win32.c to include Sleep(1) immediately before the call to
TerminateThread() prevents the lockup. Sleep(0) does not prevent the
problem.


[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=medium
---
Site configuration information for perl 5.14.0:

Configured by tony at Mon Apr 18 20:41:14 2011.

Summary of my perl5 (revision 5 version 14 subversion 0) configuration:
Derived from: d12b49d6e531fdc354980af14eb2efa34756c1d8
Platform:
osname=MSWin32, osvers=6.1, 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='cl', ccflags ='-nologo -GF -W3 -Od -MD -Zi -DDEBUGGING -DWIN32 -D_CONSOLE -DNO_STRICT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO',
optimize='-Od -MD -Zi -DDEBUGGING',
cppflags='-DWIN32'
ccversion='15.00.30729.01', gccversion='', 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='link', ldflags ='-nologo -nodefaultlib -debug -libpath:"c:\notthere\lib\CORE" -machine:x86 "/manifestdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"'
libpth=\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=perl514.lib
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -libpath:"c:\notthere\lib\CORE" -machine:x86 "/manifestdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"'

Locally applied patches:
RC0

---
@INC for perl 5.14.0:
lib
C:/Users/tony/dev/perl/git/perl/lib
.

---
Environment for perl 5.14.0:
HOME (unset)
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN;C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools;C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\bin;C:\Windows\Microsoft.NET\Framework\;C:\Windows\Microsoft.NET\Framework\\Microsoft .NET Framework 3.5 (Pre-Release Version);C:\Windows\Microsoft.NET\Framework\v2.0.50727;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\VCPackages;C:\Program Files\Microsoft SDKs\Windows\v7.0\bin;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\Bin\amd64;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcpackages;C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE;C:\apps\platsdk\win7\Bin\x64;C:\apps\platsdk\win7\Bin;C:\Windows\Microsoft.NET\Framework64\v3.5;C:\Windows\Microsoft.NET\Framework\v3.5;C:\Windows\Microsoft.NET\Framework64\v2.0.50727;C:\Windows\Microsoft.NET\Framework\v2.0.50727;C:\apps\platsdk\win7\
Setup;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\MiKTeX 2.8\miktex\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;C:\Program Files (x86)\QuickTime\QTSystem\;C:\apps\git\Git\cmd
PERL_BADLANG (unset)
SHELL (unset)


tony at develop-help

Aug 5, 2012, 12:09 AM

Post #2 of 8 (163 views)
Permalink
Re: [perl #88840] t/op/fork.t blocks in external process test on Win32 [In reply to]

On Fri, Aug 03, 2012 at 12:59:18PM -0700, bulk 88 via RT wrote:
> I've been wondering, has this test always failed? or it only fails on
> SMP >1 CPU Windows (fails for me on 2 core and 8 core PCs)? Or does it
> only fail on fast CPUs? or on Server 2003 (my machine) or NT 6 and not
> XP (does for me) or 2000 because kernel scheduler tweaks by MS over the
> years.

This is my suspicion for the cause.

> Does it only fail on Visual Studio compiled Perl that uses a VS
> specific CRT instead of msvcrt.dll (ActivePerl's C lib) (I blindly
> guess, because a FreeLibrary that lowers the reference count but doesn't
> free the DLL does so without using the loader lock maybe???). How was
> 5.16.0 released with this failing supposedly since 5.14 according to
> tony cook?

Because no-one with sufficient Win32 knowledge cares enough about
fixing the problems.

Win32 isn't the only platform where blead fails, and has failed for a
long time.

Tony


tony at develop-help

Aug 5, 2012, 12:15 AM

Post #3 of 8 (165 views)
Permalink
Re: [perl #88840] t/op/fork.t blocks in external process test on Win32 [In reply to]

On Thu, Aug 02, 2012 at 06:03:33PM -0700, bulk 88 via RT wrote:
> A half baked solution is to not have perlhost.h load a 2nd C std Lib
> into the perl OS process, and therefore never need to call FreeLibrary
> in ~Vmem destroyer which will freeze the parent interp. Why the loader
> lock never times out with a software exception (similar to access vio
> GUI wise) IDK enough about windows to say. Any XS library that does a
> FreeLibrary or a LoadLibrary, either explicitly or secretly in a pure
> C/C++ DLL it wraps, probably even Dynaloader bootstrap will freeze
> indefinitely, aslong as you Perl Lang kill 9ed a child fork "process"
> earlier in runtime fast enough to never run win32_start_child.

The problem is other libraries (eg. any XS module) loads DLLs at
runtime, which means there's always the possibility of the loader lock
causing a problem.

It doesn't need to be an early kill to cause the lockup.

I can see ways to fix this specific instance of the bug - eg. have
win32_kill() wait a little for the child hwnd to be created (see the
default case in the win32_kill() thread kill code.), but it won't
protect against the more general problem that TerminateThread() isn't
a safe function to call.

Tony


nick at ccl4

Aug 5, 2012, 12:34 AM

Post #4 of 8 (164 views)
Permalink
Re: [perl #88840] t/op/fork.t blocks in external process test on Win32 [In reply to]

On Sun, Aug 05, 2012 at 05:09:20PM +1000, Tony Cook wrote:
> On Fri, Aug 03, 2012 at 12:59:18PM -0700, bulk 88 via RT wrote:

> > Does it only fail on Visual Studio compiled Perl that uses a VS
> > specific CRT instead of msvcrt.dll (ActivePerl's C lib) (I blindly
> > guess, because a FreeLibrary that lowers the reference count but doesn't
> > free the DLL does so without using the loader lock maybe???). How was
> > 5.16.0 released with this failing supposedly since 5.14 according to
> > tony cook?

Because it's not a regression, Ricardo has no way to compel anyone to fix
it, and if the choice is between delaying a release indefinitely and
making a release with known problems, releasing with known problems is the
lesser of two evils.

> Because no-one with sufficient Win32 knowledge cares enough about
> fixing the problems.

There actually aren't very many people working on the perl core.
(I'd describe it as about 4 and 4 halves worth of very active contributors,
and it's been this way for years. This surprises people. Ohloh has graphs,
eg https://www.ohloh.net/p/perl/contributors/summary )

Even out into the "long tail" there is very little knowledge of Win32
specifics. As there's also plenty of other stuff that needs doing, pretty
much everyone elects to do things they are able to do well, as that gets
the best return soonest. So Win32 doesn't get worked on that way.

And as there's no hiring organisation in "charge" of Perl 5, it means that
it doesn't get worked on the "other" way, by paying people to work on the
things that no volunteer volunteers to work on.

> Win32 isn't the only platform where blead fails, and has failed for a
> long time.

And whilst we'd love it to be otherwise, it's really not obvious how to
get from where we are to where we want to be, short of hoping that someone
(or someones) volunteers to start digging into fixing it.

There's no hostility to Win32 (or any other platform). It's just that there
are no active core developers who use it as a primary development platform.

Nicholas Clark


jand at activestate

Aug 6, 2012, 1:14 PM

Post #5 of 8 (158 views)
Permalink
RE: [perl #88840] t/op/fork.t blocks in external process test on Win32 [In reply to]

On Sun, 05 Aug 2012, Tony Cook wrote:
> On Fri, Aug 03, 2012 at 12:59:18PM -0700, bulk 88 via RT wrote:
> > I've been wondering, has this test always failed? or it only fails on
> > SMP >1 CPU Windows (fails for me on 2 core and 8 core PCs)? Or does it
> > only fail on fast CPUs? or on Server 2003 (my machine) or NT 6 and not
> > XP (does for me) or 2000 because kernel scheduler tweaks by MS over the
> > years.
>
> This is my suspicion for the cause.

I suspect it also doesn't happen when you link Perl against MSVCRT.dll
because LoadLibrary("MSVCRT.dll") then just increments the reference
count and won't hold the loader lock for very long. Both VC6 and MinGW
builds use MSVCRT.

Cheers,
-Jan


jand at activestate

Aug 6, 2012, 1:25 PM

Post #6 of 8 (159 views)
Permalink
RE: [perl #88840] t/op/fork.t blocks in external process test on Win32 [In reply to]

On Sun, 05 Aug 2012, Tony Cook wrote:
> On Thu, Aug 02, 2012 at 06:03:33PM -0700, bulk 88 via RT wrote:
> > A half baked solution is to not have perlhost.h load a 2nd C std Lib
> > into the perl OS process, and therefore never need to call FreeLibrary
> > in ~Vmem destroyer which will freeze the parent interp. Why the loader
> > lock never times out with a software exception (similar to access vio
> > GUI wise) IDK enough about windows to say. Any XS library that does a
> > FreeLibrary or a LoadLibrary, either explicitly or secretly in a pure
> > C/C++ DLL it wraps, probably even Dynaloader bootstrap will freeze
> > indefinitely, aslong as you Perl Lang kill 9ed a child fork "process"
> > earlier in runtime fast enough to never run win32_start_child.

I wonder if there isn't a simpler solution: Just add

#undef malloc
#undef free
#undef realloc

after all the Perl headers have been #included, and then later
assign

m_pfree = (LPFREE)free;

etc and get rid of the whole LoadLibrary/FreeLibrary stuff. That way VMem
will just use the current CRT versions of these functions. I suspect the
whole LoadLibrary/FreeLibrary dance is only done because the Perl headers
redefine malloc to Perl_malloc, and VMem needs to provide the implementation
to Perl_malloc, so can't use the redefined malloc() functions. Just getting
rid of the wrapper macros should solve the issue though.

There are more chances for code cleanup, but someone who observes the
problem should try this "fix" to see if it works first. :)

> [...] It won't
> protect against the more general problem that TerminateThread() isn't
> a safe function to call.

Yes, the whole fork() emulation stuff is rather brittle and can never cease
to be "experimental". I wish we could just get rid of it, but CPAN modules
seem to rely on it to use forking regression tests on Windows, so I guess it
is at least marginally useful.

Cheers,
-Jan


tony at develop-help

Aug 11, 2012, 7:48 PM

Post #7 of 8 (151 views)
Permalink
Re: [perl #88840] t/op/fork.t blocks in external process test on Win32 [In reply to]

On Fri, Aug 10, 2012 at 09:42:22AM -0700, bulk 88 via RT wrote:
> On Fri Aug 10 00:33:07 2012, tonyc wrote:
> > I tried this and ran t/op/fork.t in a loop.
> >
> > First time it deadlocked after 7 runs, second it deadlocked after 27
> > runs.
> >
> > I increased delay to 10 ms and it successfully ran the test 500 times.
> >
> > Also, please use git format-patch to produce patches.
> >
> > Tony
> >
> I wrote a script

> If it deadlocked for you, I am very interested in that, since my patch
> is supposed to die or succeed, not deadlock. The only thing I can think
> of, unless you can produce a callstack that shows otherwise (that would
> be greatly appreciated), you are probably deadlocking on the heap
> critical section (but how timing wise? child interp is supposed to be in
> a sleep 5;, is it really taking that long from the hwnd message send,
> thus unlocking get_hwnd_delay to runops calling the sleep opcode
> function?), since the DLL loader lock is guaranteed to not be on in the
> child interp unless your doing XS. In child interp's VMem, the
> LoadLibrary on msvcrt.dll is done in the parent interp thread and it
> does use the loader lock even though msvcrt.dll is already in the
> process from the parent interp's VMem. Why MS uses the loader lock on a
> refcount increase only LoadLibrary IDK.

I rebuilt from scratch and ran my test again, and couldn't reproduce
the failures.

Sorry for the noise.

So I'm happy with this change.

Tony


Steve.Hay at verosoftware

Aug 14, 2012, 1:14 AM

Post #8 of 8 (145 views)
Permalink
RE: [perl #88840] t/op/fork.t blocks in external process test on Win32 [In reply to]

bulk 88 via RT wrote on 2012-08-14:
> Can someone apply the patch to perl git?
>
> ---
> via perlbug: queue: perl5 status: open
> https://rt.perl.org:443/rt3/Ticket/Display.html?id=88840

Apologies for the delay. I will test it and expect to apply it in a few hours. Thanks for your contributions!

Perl porters RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.