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

win32_open/win32_popen deadlock #11221

Open
p5pRT opened this issue Mar 31, 2011 · 11 comments
Open

win32_open/win32_popen deadlock #11221

p5pRT opened this issue Mar 31, 2011 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Mar 31, 2011

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

Searchable as RT87410$

@p5pRT
Copy link
Author

p5pRT commented Mar 31, 2011

From avstuser@gmail.com

Hi,

minimal example - min.pl (it opens itself), it might take some time to hit
the right spot, it is a race condition, so wait for it​:

use threads;
use warnings;
use strict;
sub f { while(1) { my $x = `dir`; } }
sub fo { while(1) { open( X, "<min.pl" ) or die; close(X); } }
threads->create(\&f, 0);
threads->create(\&fo, 1);
threads->create(\&f, 2);
my $i = 0;
while(1) { open( X, "<min.pl" ) or die; close(X); if($i % 1000 ){print
STDERR $i."\n";} $i++; }

It probably affects all the windows perl versions.

Additional analysis​:

  0​:004> ~*k
  0 Id​: 15a8.206c Suspend​: 1 Teb​: 000007ff`fffde000 Unfrozen
Child-SP RetAddr Call Site
00000000`0140f108 00000000`77b9cf88 ntdll!NtWaitForSingleObject+0xa
00000000`0140f110 00000000`77b9ce82 ntdll!RtlpWaitOnCriticalSection+0xe8
00000000`0140f1c0 000007fe`ff638843 ntdll!RtlEnterCriticalSection+0xab
00000000`0140f1f0 000007fe`ff638f7c msvcrt!alloc_osfhnd+0x43
00000000`0140f250 000007fe`ff66922e msvcrt!mktemp_s+0x234
00000000`0140f300 00000000`28008b55 msvcrt!open+0x8a
00000000`0140f370 00000000`2801bba0 perl510!win32_open+0x85
00000000`0140f3b0 00000000`28018cc8 perl510!PerlIO_findFILE+0x280
00000000`0140f470 00000000`2801932f perl510!PerlIOBuf_open+0x258
00000000`0140f520 00000000`2814d4ef perl510!PerlIOBuf_open+0x8bf
00000000`0140f600 00000000`280b6929 perl510!Perl_do_openn+0xdff
00000000`0140f820 00000000`28152f92 perl510!Perl_setdefout+0xf699
00000000`0140f8b0 00000000`28101af4 perl510!Perl_runops_standard+0x52
00000000`0140f8e0 00000000`28101fbc perl510!Perl_sys_init+0x1894
00000000`0140f910 00000000`28023f2e perl510!perl_run+0x49c
00000000`0140fac0 00000000`00401351 perl510!RunPerl+0x1de
00000000`0140ff00 00000000`778cf56d perl+0x1351
00000000`0140ff60 00000000`77b83021 kernel32!BaseThreadInitThunk+0xd
00000000`0140ff90 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
  1 Id​: 15a8.21f0 Suspend​: 1 Teb​: 000007ff`fffdc000 Unfrozen
Child-SP RetAddr Call Site
00000000`043ff6d8 00000000`77b9cf88 ntdll!NtWaitForSingleObject+0xa
00000000`043ff6e0 00000000`77b9ce82 ntdll!RtlpWaitOnCriticalSection+0xe8
00000000`043ff790 000007fe`ff638843 ntdll!RtlEnterCriticalSection+0xab
00000000`043ff7c0 000007fe`ff63f51d msvcrt!alloc_osfhnd+0x43
00000000`043ff820 000007fe`ff63f49b msvcrt!creat+0xa1
00000000`043ff8b0 00000000`280108a0 msvcrt!dup+0xbe
00000000`043ff900 00000000`280b4498 perl510!win32_popen+0x120
00000000`043ff970 00000000`28152f92 perl510!Perl_setdefout+0xd208
00000000`043ffb40 00000000`280fec54 perl510!Perl_runops_standard+0x52
00000000`043ffb70 00000000`1000487f perl510!Perl_call_sv+0x584
00000000`043ffd90 00000000`778cf56d threads+0x487f
00000000`043fff60 00000000`77b83021 kernel32!BaseThreadInitThunk+0xd
00000000`043fff90 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
  2 Id​: 15a8.1ff8 Suspend​: 1 Teb​: 000007ff`fffda000 Unfrozen
Child-SP RetAddr Call Site
00000000`053ff398 00000000`77b9cf88 ntdll!NtWaitForSingleObject+0xa
00000000`053ff3a0 00000000`77b9ce82 ntdll!RtlpWaitOnCriticalSection+0xe8
00000000`053ff450 000007fe`ff6388b7 ntdll!RtlEnterCriticalSection+0xab
00000000`053ff480 000007fe`ff638f7c msvcrt!alloc_osfhnd+0xdd
00000000`053ff4e0 000007fe`ff66922e msvcrt!mktemp_s+0x234
00000000`053ff590 00000000`28008b55 msvcrt!open+0x8a
00000000`053ff600 00000000`2801bba0 perl510!win32_open+0x85
00000000`053ff640 00000000`28018cc8 perl510!PerlIO_findFILE+0x280
00000000`053ff700 00000000`2801932f perl510!PerlIOBuf_open+0x258
00000000`053ff7b0 00000000`2814d4ef perl510!PerlIOBuf_open+0x8bf
00000000`053ff890 00000000`280b6929 perl510!Perl_do_openn+0xdff
00000000`053ffab0 00000000`28152f92 perl510!Perl_setdefout+0xf699
00000000`053ffb40 00000000`280fec54 perl510!Perl_runops_standard+0x52
00000000`053ffb70 00000000`1000487f perl510!Perl_call_sv+0x584
00000000`053ffd90 00000000`778cf56d threads+0x487f
00000000`053fff60 00000000`77b83021 kernel32!BaseThreadInitThunk+0xd
00000000`053fff90 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
  3 Id​: 15a8.2a1c Suspend​: 1 Teb​: 000007ff`fffd8000 Unfrozen
Child-SP RetAddr Call Site
00000000`063ff708 00000000`77b9cf88 ntdll!NtWaitForSingleObject+0xa
00000000`063ff710 00000000`77b9ce82 ntdll!RtlpWaitOnCriticalSection+0xe8
00000000`063ff7c0 000007fe`ff638843 ntdll!RtlEnterCriticalSection+0xab
00000000`063ff7f0 000007fe`ff63e734 msvcrt!alloc_osfhnd+0x43
00000000`063ff850 00000000`28010867 msvcrt!pipe+0x140
00000000`063ff900 00000000`280b4498 perl510!win32_popen+0xe7
00000000`063ff970 00000000`28152f92 perl510!Perl_setdefout+0xd208
00000000`063ffb40 00000000`280fec54 perl510!Perl_runops_standard+0x52
00000000`063ffb70 00000000`1000487f perl510!Perl_call_sv+0x584
00000000`063ffd90 00000000`778cf56d threads+0x487f
00000000`063fff60 00000000`77b83021 kernel32!BaseThreadInitThunk+0xd
00000000`063fff90 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
# 4 Id​: 15a8.2720 Suspend​: 1 Teb​: 000007ff`fffd6000 Unfrozen
Child-SP RetAddr Call Site
00000000`078fff28 00000000`77c48778 ntdll!DbgBreakPoint
00000000`078fff30 00000000`778cf56d ntdll!DbgUiRemoteBreakin+0x38
00000000`078fff60 00000000`77b83021 kernel32!BaseThreadInitThunk+0xd
00000000`078fff90 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

0​:004> !cs 00000000003d9730


Critical section = 0x00000000003d9730 (+0x3D9730)
DebugInfo = 0x00000000000e2f80
LOCKED
LockCount = 0x3
WaiterWoken = No
OwningThread = 0x0000000000001ff8
RecursionCount = 0x1
LockSemaphore = 0x74
SpinCount = 0x0000000000000fa0

0​:004> ~~[1ff8]kv
Child-SP RetAddr : Args to
Child : Call Site
00000000`053ff398 00000000`77b9cf88 : 00000000`00000145 00000000`00000001
fffff1f0`00000001 0000002e`0000000f : ntdll!NtWaitForSingleObject+0xa
00000000`053ff3a0 00000000`77b9ce82 : 001e0003`00000000 ffffffff`ffffffff
00000000`ffffffff 00000000`003d4ec8 : ntdll!RtlpWaitOnCriticalSection+0xe8
00000000`053ff450 000007fe`ff6388b7 : 00000000`00000002 00000000`00000080
00000000`00000000 000007fe`00000080 : ntdll!RtlEnterCriticalSection+0xab
00000000`053ff480 000007fe`ff638f7c : 00000000`00000000 00000000`053ff5d0
00000000`00000003 000007fe`ff6313f2 : msvcrt!alloc_osfhnd+0xdd
00000000`053ff4e0 000007fe`ff66922e : 00000000`053ff5d4 00000000`000001b6
00000000`03275328 00000000`00000000 : msvcrt!mktemp_s+0x234
00000000`053ff590 00000000`28008b55 : 00000000`000001b6 00000000`00008000
00000000`000001b6 007daf9c`0002000e : msvcrt!open+0x8a
00000000`053ff600 00000000`2801bba0 : 00000000`00000020 00000000`00008000
00000000`000001b6 00000000`000001b6 : perl510!win32_open+0x85
00000000`053ff640 00000000`28018cc8 : 00000000`28172868 00000000`00000000
00000000`28172550 00000000`00000001 : perl510!PerlIO_findFILE+0x280
00000000`053ff700 00000000`2801932f : 00000000`28172700 00000000`281978f0
00000000`281727dc 00000000`053ff948 : perl510!PerlIOBuf_open+0x258
00000000`053ff7b0 00000000`2814d4ef : 00000000`00000074 00000000`03275738
00000000`00000074 00000000`ffffffff : perl510!PerlIOBuf_open+0x8bf
00000000`053ff890 00000000`280b6929 : 00000000`00000001 00000000`00000000
00000000`032c2aa0 00000000`28149cb1 : perl510!Perl_do_openn+0xdff
00000000`053ffab0 00000000`28152f92 : 00000000`03275738 00000000`032fbbf0
00000000`03298c58 00000000`0322e7e8 : perl510!Perl_setdefout+0xf699
00000000`053ffb40 00000000`280fec54 : 00000000`03275738 00000000`032fbbf0
00000000`03298c58 00000000`0322e7e8 : perl510!Perl_runops_standard+0x52
00000000`053ffb70 00000000`1000487f : 00000000`03275738 00000000`00000000
00000000`00000084 00000000`00000000 : perl510!Perl_call_sv+0x584
00000000`053ffd90 00000000`778cf56d : 00000000`00000000 00000000`00000000
00000000`00000000 00000000`00000000 : threads+0x487f
00000000`053fff60 00000000`77b83021 : 00000000`00000000 00000000`00000000
00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
00000000`053fff90 00000000`00000000 : 00000000`00000000 00000000`00000000
00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d

0​:004> !cs 003d4ec8


Critical section = 0x00000000003d4ec8 (+0x3D4EC8)
DebugInfo = 0x00000000000e1160
LOCKED
LockCount = 0x1
WaiterWoken = No
OwningThread = 0x00000000000021f0
RecursionCount = 0x1
LockSemaphore = 0x64
SpinCount = 0x0000000000000fa0

0​:004> ~~[21f0]kv
Child-SP RetAddr : Args to
Child : Call Site
00000000`043ff6d8 00000000`77b9cf88 : 00000000`03232488 00000000`778d2c51
00000000`00000002 00000000`03232488 : ntdll!NtWaitForSingleObject+0xa
00000000`043ff6e0 00000000`77b9ce82 : 00000000`00000000 ffffffff`ffffffff
00000000`ffffffff 00000000`003d9730 : ntdll!RtlpWaitOnCriticalSection+0xe8
00000000`043ff790 000007fe`ff638843 : 00000000`2816a254 00000000`00000038
00000000`00000000 00000000`043ff7f8 : ntdll!RtlEnterCriticalSection+0xab
00000000`043ff7c0 000007fe`ff63f51d : 00000000`00000001 00000000`00000000
00000000`00000000 00000000`00000000 : msvcrt!alloc_osfhnd+0x43
00000000`043ff820 000007fe`ff63f49b : 00000000`00000041 00000000`00000038
00000000`00000000 00000000`00000000 : msvcrt!creat+0xa1
00000000`043ff8b0 00000000`280108a0 : 00000000`00000001 00000000`00000001
00000000`00000001 00000000`00000001 : msvcrt!dup+0xbe
00000000`043ff900 00000000`280b4498 : 00000000`0324eaf8 00000000`03224cc0
00000000`00000000 00000000`2816a254 : perl510!win32_popen+0x120
00000000`043ff970 00000000`28152f92 : 00000000`00274b18 00000000`00274b18
00000000`0326d210 00000000`002537d8 : perl510!Perl_setdefout+0xd208
00000000`043ffb40 00000000`280fec54 : 00000000`00274b18 00000000`0326d210
00000000`002537d8 00000000`0322ebd8 : perl510!Perl_runops_standard+0x52
00000000`043ffb70 00000000`1000487f : 00000000`00274b18 00000000`00000000
00000000`00000084 00000000`00000000 : perl510!Perl_call_sv+0x584
00000000`043ffd90 00000000`778cf56d : 00000000`00000000 00000000`00000000
00000000`00000000 00000000`00000000 : threads+0x487f
00000000`043fff60 00000000`77b83021 : 00000000`00000000 00000000`00000000
00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
00000000`043fff90 00000000`00000000 : 00000000`00000000 00000000`00000000
00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d

3 threads waiting on a critical section (3d9730) held by thread 2 (TID
1ff8), thread's stack shows that it also waits on a critical section
(3d4ec8) and that critical section is owned by a thread that waits on lock
held by thread 2 again - deadlock msvcrt!dup vs msvcrt!open.

Looks like a bug in msvcrt itself. See this link​:
http​://bugs.mysql.com/bug.php?id=12071 they discuss quite the same thing.

Regards,
Frank

@p5pRT
Copy link
Author

p5pRT commented Apr 4, 2011

From @jandubois

On Thu, 31 Mar 2011, Frank Hruza (via RT) wrote​:

minimal example - min.pl (it opens itself), it might take some time to hit
the right spot, it is a race condition, so wait for it​:

[...]

3 threads waiting on a critical section (3d9730) held by thread 2 (TID
1ff8), thread's stack shows that it also waits on a critical section
(3d4ec8) and that critical section is owned by a thread that waits on lock
held by thread 2 again - deadlock msvcrt!dup vs msvcrt!open.

Looks like a bug in msvcrt itself. See this link​:
http​://bugs.mysql.com/bug.php?id=12071 they discuss quite the same thing.

Hi Frank!

Thank you for spending the time to narrow down the problem to a small
test case, and for even providing the stack traces of the blocking
threads.

I did not have time to look into your report beyond browsing the related
bug entry in the mysql bug database. Unfortunately that thread is over
5 years old, and while people claim to have reported the issue to Microsoft,
it doesn't seem to have been fixed.

It is not clear to me how we could work around the issue without either​:

a) finishing the :win32 I/O layer and not use stdio on Windows at all, or
b) replacing some of the msvcrt.dll function with our own fixed versions.

Both would be rather big efforts. So I was intrigued to read on #p5p on IRC​:

| wuser​: If I would make a patch, who would be reviewing it?

Did you have a specific idea how we could work around the problem in a more
surgical manner?

Cheers,
-Jan

PS​: You said you have found more problems with win32_popen(). Do you intend
  to file bug reports for those as well, or are they already covered by
  existing reports?

@p5pRT
Copy link
Author

p5pRT commented Apr 4, 2011

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

@p5pRT
Copy link
Author

p5pRT commented Apr 4, 2011

From @Leont

On Mon, Apr 4, 2011 at 7​:27 PM, Jan Dubois <jand@​activestate.com> wrote​:

a) finishing the :win32 I/O layer and not use stdio on Windows at all, or

I'm not harmed by much knowledge of the win32 api, but what exactly
would make that a rather big effort? It doesn't really look that way
to me.

Leon

@p5pRT
Copy link
Author

p5pRT commented Apr 4, 2011

From @jandubois

On Mon, 04 Apr 2011, Leon Timmermans wrote​:

On Mon, Apr 4, 2011 at 7​:27 PM, Jan Dubois <jand@​activestate.com> wrote​:

a) finishing the :win32 I/O layer and not use stdio on Windows at all, or

I'm not harmed by much knowledge of the win32 api, but what exactly
would make that a rather big effort? It doesn't really look that way
to me.

Sorry, I don't remember the details, but N-IS was working on the layer
stuff for quite a while, and at some point seems to have given up (at least
temporarily) on the :win32 layer. Given that he was the author of the
PerlIO layer subsystem, I would have thought that he would have finished
it if it was reasonably easy.

I haven't tried the code lately, but I think it doesn't pass Perl regression
tests at all. It also doesn't seem to have any code to implement sockets
as file handles I think.

But yes, I may very well be wrong and just have some irrational fear of that
part of the code. :)

Cheers,
-Jan

@p5pRT
Copy link
Author

p5pRT commented Apr 4, 2011

From @Leont

On Mon, Apr 4, 2011 at 8​:49 PM, Jan Dubois <jand@​activestate.com> wrote​:

Sorry, I don't remember the details, but N-IS was working on the layer
stuff for quite a while, and at some point seems to have given up (at least
temporarily) on the :win32 layer.  Given that he was the author of the
PerlIO layer subsystem, I would have thought that he would have finished
it if it was reasonably easy.

Almost all of the code is from the original commit a8c08e ("Work in
progress UNIX-side edit of win32 PerLIO layer"), except the
PerlIOWin32_dup code as that feature was added after :win32. To me it
looks more like a project in an early stage of development than a
stagnated one, but I may be mistaken​: I don't know what happened
outside of the repository.

I haven't tried the code lately, but I think it doesn't pass Perl regression tests at all.

It hasn't had significant maintenance in many years, I wouldn't expect
it to work flawlessly.

It also doesn't seem to have any code to implement sockets as file handles I think.

AFAIK they don't necessarily require special code, but I'm not sure of that.

Leon

@p5pRT
Copy link
Author

p5pRT commented Sep 8, 2012

From @bulk88

This list discussion is another report of this bug
http​://www.nntp.perl.org/group/perl.perl5.porters/2012/09/msg191761.html

I got the following idea on howto fix this. The fix is for perl to
acquire lock 11 before calling CRT's dup, this way the lock order is
restored (lock 11/_OSFHND_LOCK then a handle specific lock). Now the
question is whether _lock is exported from all the CRTs that Perl can be
compiled with.

All info below is from 32 bit dlls.

msvcrt.dll 7.0.2600.5512 (xpsp.080413-2111) exports _lock, disassembly
shows _OSFHND_LOCK in _alloc_osfhnd is 11
msvcr71.dll 7.10.6030.0 exports _lock, disassembly shows _OSFHND_LOCK
in _alloc_osfhnd is 11 and crt src code shows it is 11
msvcr100.dll 10.0.40219.1 exports _lock, disassembly shows _OSFHND_LOCK
in _alloc_osfhnd is 11
msvcrt90.dll 9.00.21022.8 exports _lock, disassembly shows _OSFHND_LOCK
in _alloc_osfhnd is 11 and crt src code shows it is 11
msvcrt40.dll 5.1.2600.5512 on WinXP, which contains zero machine code,
just export table forwards to msvcrt.dll does NOT export a _lock
msvcrt20.dll 2.11.0.0 from Windows 95 install disk, does not export
_lock, _lock exists internally though. disassembly shows _OSFHND_LOCK in
_alloc_osfhnd is 18
msvcrt.dll 6.1.8637.0 from WinME, exports _lock, disassembly shows
_OSFHND_LOCK in _alloc_osfhnd is 17, not 18, not 11 *scratches head*
msvcrt.dll 6.1.9844.0 from Win2K SP4-ish, exports _lock, disassembly
shows _OSFHND_LOCK in _alloc_osfhnd is 17

Reactos/Wine does the Dos Windows way _OSFHND_LOCK
http​://doxygen.reactos.org/d0/da9/mtdll_8h_a84d97c70b6831b4756cbe856b6419642.html#a84d97c70b6831b4756cbe856b6419642
is 18

VC 6 msvcrt.dll which I dont have a copy of, is probably 18 see
ftp​://ftp.cs.ntust.edu.tw/yang/PC-SIMSCRIPT/C%2B%2B/VC98/CRT/SRC/MTDLL.H

_lock was made public api by MS in VS 2010.
http​://preview.library.microsoft.com/en-us/library/634ca0c2%28v=VS.100%29.aspx
(VS 2010)
and
http​://preview.library.microsoft.com/en-us/library/634ca0c2%28v=VS.90%29.aspx
(VS 2008). I dont have a VS 2010 to check its headers.

VC 2003's msvcrt.lib exports _lock but it is never declared in the VS
2003 CRT headers so we dont have a GetProcAddress nightmare to use
_lock. I have a msvcrt.lib that I labeled "vc6" I found somewhere a long
time ago, it also has _lock.

Since WinCE and Win2K are supported platforms. How to figure out what
the _OSFHND_LOCK constant is in a particular CRT DLL?

@p5pRT
Copy link
Author

p5pRT commented Sep 9, 2012

From @bulk88

On Sat Sep 08 12​:56​:23 2012, bulk88 wrote​:

I got the following idea on howto fix this. The fix is for perl to
acquire lock 11 before calling CRT's dup, this way the lock order is
restored (lock 11/_OSFHND_LOCK then a handle specific lock). Now the
question is whether _lock is exported from all the CRTs that Perl can
be
compiled with.

I tried the lock 11 hack on a VC 2008 X64 5.17 perl on Server 2003 x64 8
core PC I have. The PC hung after a couple minutes before the fix below.
Its now been running 2 hours without a hang before I killed. I am using
the batch file loop thing.
_________________________________________
DllExport int
win32_dup(int fd)
{
  int ret;
  _lock(11);
  ret = dup(fd);
  _unlock(11);
  return ret;
}

DllExport int
win32_dup2(int fd1,int fd2)
{
  int ret;
  _lock(11);
  ret = dup2(fd1,fd2);
  _unlock(11);
  return ret;
}
___________________________________________
So lock 11 hack works to fix this bug. Build log also said
___________________________________________
win32.c(3220) : warning C4013​: '_lock' undefined; assuming extern
returning int
win32.c(3222) : warning C4013​: '_unlock' undefined; assuming extern
returning int
__________________________________________
so that also has to get trivially fixed. The biggest problem is that the
_OSFHND_LOCK isn't the same for each CRT, or even between different
version numbers of the same CRT DLL. 11 is the WinXP and "newer"-ish
value. So yeah, the fix above works, but how do we make turn this from a
alpha hack to RTM for 5.18 or any backports?

@p5pRT
Copy link
Author

p5pRT commented Sep 20, 2012

From Mike.B.Huang@emc.com

The patch works for some of my test programs, but it failed on the following,
_________________________________________
use threads;
use warnings;
use strict;

sub f
{
  while(1) {
  my $x = `dir`;
  print "$x\n";
  }
}

threads->create(\&f, 0);
threads->create(\&f, 1);
while (1) {
  sleep(1);
}
_________________________________________

-----Original Message-----
From​: bulk 88 via RT [mailto​:perlbug-followup@​perl.org]
Sent​: 2012年9月10日 4​:50
Cc​: perl5-porters@​perl.org; Huang, Mike (Beijing)
Subject​: [perl #87410] win32_open/win32_popen deadlock

On Sat Sep 08 12​:56​:23 2012, bulk88 wrote​:

I got the following idea on howto fix this. The fix is for perl to
acquire lock 11 before calling CRT's dup, this way the lock order is
restored (lock 11/_OSFHND_LOCK then a handle specific lock). Now the
question is whether _lock is exported from all the CRTs that Perl can
be
compiled with.

I tried the lock 11 hack on a VC 2008 X64 5.17 perl on Server 2003 x64 8
core PC I have. The PC hung after a couple minutes before the fix below.
Its now been running 2 hours without a hang before I killed. I am using
the batch file loop thing.
_________________________________________
DllExport int
win32_dup(int fd)
{
  int ret;
  _lock(11);
  ret = dup(fd);
  _unlock(11);
  return ret;
}

DllExport int
win32_dup2(int fd1,int fd2)
{
  int ret;
  _lock(11);
  ret = dup2(fd1,fd2);
  _unlock(11);
  return ret;
}
___________________________________________
So lock 11 hack works to fix this bug. Build log also said
___________________________________________
win32.c(3220) : warning C4013​: '_lock' undefined; assuming extern
returning int
win32.c(3222) : warning C4013​: '_unlock' undefined; assuming extern
returning int
__________________________________________
so that also has to get trivially fixed. The biggest problem is that the
_OSFHND_LOCK isn't the same for each CRT, or even between different
version numbers of the same CRT DLL. 11 is the WinXP and "newer"-ish
value. So yeah, the fix above works, but how do we make turn this from a
alpha hack to RTM for 5.18 or any backports?


via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=87410

@p5pRT
Copy link
Author

p5pRT commented Sep 21, 2012

From @bulk88

On Thu Sep 20 05​:52​:11 2012, Mike.B.Huang@​emc.com wrote​:

The patch works for some of my test programs, but it failed on the
following,
_________________________________________
use threads;
use warnings;
use strict;

sub f
{
while(1) {
my $x =
`dir`;
print "$x\n";
}
}

threads->create(\&f, 0);
threads->create(\&f, 1);
while (1) {
sleep(1);
}
On 5.17 WITHOUT the crude fix I mentioned above, your script hung like
this for me. There are 3 threads.
original interp thread 8840
_____________________________________________________
  ntdll.dll!_KiFastSystemCallRet@​0()
  ntdll.dll!_ZwWaitForMultipleObjects@​20() + 0xc
  kernel32.dll!_WaitForMultipleObjectsEx@​20() - 0x48
  user32.dll!_RealMsgWaitForMultipleObjectsEx@​20() + 0xd9
  user32.dll!_MsgWaitForMultipleObjects@​20() + 0x1f
perl517.dll!win32_msgwait(interpreter * my_perl=0x00343ff0, unsigned
long count=0, void * * handles=0x00000000, unsigned long timeout=1000,
unsigned long * resultp=0x00000000) Line 2183 C
  perl517.dll!win32_sleep(unsigned int t=1) Line 2365 + 0x16 C
  perl517.dll!PerlProcSleep(IPerlProc * piPerl=0x00345e68, unsigned int
s=1) Line 1659 + 0x9 C++
  perl517.dll!Perl_pp_sleep(interpreter * my_perl=0x00343ff0) Line
4606 + 0xb C
  perl517.dll!Perl_runops_standard(interpreter * my_perl=0x00343ff0)
Line 42 + 0x4 C
  perl517.dll!S_run_body(interpreter * my_perl=0x7ffd5000, long
oldscope=1) Line 2392 + 0xa C
  perl517.dll!perl_run(interpreter * my_perl=0x00343ff0) Line 2309 + 0x8 C
  perl517.dll!RunPerl(int argc=2, char * * argv=0x00343f78, char * *
env=0x01342f90) Line 270 + 0x6 C++
  perl.exe!mainCRTStartup() Line 398 + 0xe C
  kernel32.dll!_BaseProcessStart@​4() + 0x23
____________________________________________________
thread 9876
____________________________________________________
  ntdll.dll!_KiFastSystemCallRet@​0()
  ntdll.dll!_ZwWriteFile@​36() + 0xc
  kernel32.dll!_WriteFile@​20() + 0x6f
msvcr71.dll!_write_lk(int fh=3415916, const void * buf=0x00000000,
unsigned int cnt=125216) Line 180 + 0x1d C
  msvcr71.dll!_write(int fh=1, const void * buf=0x00b05df0, unsigned int
cnt=54) Line 79 + 0xc C
  perl517.dll!PerlLIOWrite(IPerlLIO * piPerl=0x008f05d4, int handle=1,
const void * buffer=0x00b05df0, unsigned int count=54) Line 1081 + 0x11 C++
  perl517.dll!PerlIOUnix_write(interpreter * my_perl=0x00966cb0, _PerlIO
* * f=0x0090b8f8, const void * vbuf=0x00b05df0, unsigned int count=54)
Line 2822 + 0x14 C
  perl517.dll!Perl_PerlIO_write(interpreter * my_perl=0x00966cb0,
_PerlIO * * f=0x0090b8f8, const void * vbuf=0x00b05df0, unsigned int
count=54) Line 1695 + 0x2b C
  perl517.dll!PerlIOBuf_flush(interpreter * my_perl=0x00966cb0, _PerlIO
* * f=0x00b05df0) Line 3931 + 0x13 C
  perl517.dll!PerlIOCrlf_flush(interpreter * my_perl=0x00966cb0, _PerlIO
* * f=0x0090b450) Line 4767 + 0xa C
  perl517.dll!Perl_PerlIO_flush(interpreter * my_perl=0x00966cb0,
_PerlIO * * f=0x0090b450) Line 1719 + 0x6 C
  perl517.dll!PerlIOCrlf_write(interpreter * my_perl=0x00966cb0, _PerlIO
* * f=0x00b2232c, const void * vbuf=0x00b19db8, unsigned int
count=34164) Line 4748 + 0x9 C
  perl517.dll!Perl_PerlIO_write(interpreter * my_perl=0x00966cb0,
_PerlIO * * f=0x0090b450, const void * vbuf=0x00b19db8, unsigned int
count=34164) Line 1695 + 0x2b C
  perl517.dll!Perl_do_print(interpreter * my_perl=0x00966cb0, sv *
sv=0x009a4a80, _PerlIO * * fp=0x0090b450) Line 1267 + 0x13 C
  perl517.dll!Perl_pp_print(interpreter * my_perl=0x009b2314) Line
731 + 0xb C
  perl517.dll!Perl_runops_standard(interpreter * my_perl=0x00966cb0)
Line 42 + 0x4 C
  perl517.dll!Perl_call_sv(interpreter * my_perl=0x7478742e, sv *
sv=0x0a0a0d0d, volatile long flags=2004117103) Line 2691 + 0xc C
  threads.dll!S_ithread_run(void * arg=0x009069e0) Line 517 + 0x14 C
  kernel32.dll!_BaseThreadStart@​8() + 0x37
_________________________________________________________
thread 9600
_________________________________________________________
  ntdll.dll!_KiFastSystemCallRet@​0()
  ntdll.dll!_ZwWaitForSingleObject@​12() + 0xc
  ntdll.dll!_RtlpWaitForCriticalSection@​4() + 0x8c
  ntdll.dll!_RtlEnterCriticalSection@​4() + 0x46
msvcr71.dll!_lock_fhandle(int fh=1) Line 453 C
  msvcr71.dll!_dup2(int fh1=5, int fh2=1) Line 94 C
  perl517.dll!win32_popen(const char * command=0x00af12e0, const char *
mode=0x280caf44) Line 2924 + 0xc C
  perl517.dll!PerlProcPopen(IPerlProc * piPerl=0x009974c0, const char *
command=0x00af12e0, const char * mode=0x280caf44) Line 1621 + 0xd C++
  perl517.dll!Perl_pp_backtick(interpreter * my_perl=0x00af12e0) Line
309 + 0xe C
  perl517.dll!Perl_runops_standard(interpreter * my_perl=0x0097a930)
Line 42 + 0x4 C
  perl517.dll!Perl_call_sv(interpreter * my_perl=0x00000005, sv *
sv=0x00000001, volatile long flags=671919940) Line 2691 + 0xc C
  threads.dll!S_ithread_run(void * arg=0x009971e8) Line 517 + 0x14 C
  kernel32.dll!_BaseThreadStart@​8() + 0x37
__________________________________________________________
thread 9600 is waiting on a critical section for fh 1 held by 9876. 9876
doing a synchronous write into fh 1 and holds the CS lock for fh 1.
Process start thread 8840 is waking up every second or so and going
through the win32_msgwait loop and is going back to waiting. I applied
lock 11 fix, no change from above. It still locked. I don't know why
9876 is stuck in a write. Isn't fh 1 stdout to console?

@p5pRT
Copy link
Author

p5pRT commented Sep 21, 2012

From @bulk88

On Thu Sep 20 19​:37​:10 2012, bulk88 wrote​:

I don't know why
9876 is stuck in a write. Isn't fh 1 stdout to console?

fh 1's kernel handle is an anonymous win32 named pipe, I dont think it
is the console.

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