Front page | perl.perl5.porters |
Postings from May 2008
[perl #54028] Under win32, there is retry logic to spawn a process again, if the return code is negative, and if errno is set to a couple of specific values.
Thread Next
From:
alistair @ inrevo . com
Date:
May 12, 2008 10:02
Subject:
[perl #54028] Under win32, there is retry logic to spawn a process again, if the return code is negative, and if errno is set to a couple of specific values.
Message ID:
rt-3.6.HEAD-4661-1210598183-383.54028-75-0@perl.org
# New Ticket Created by alistair@inrevo.com
# Please include the string: [perl #54028]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=54028 >
This is a bug report for perl from alistair@inrevo.com,
generated with the help of perlbug 1.36 running under perl 5.10.0.
-----------------------------------------------------------------
[Please enter your report here]
Under win32, there is retry logic to spawn a process again, if the return
code is negative, and if errno is set to a couple of specific values.
This behaves unpredictably. Here's an example:
firstly, write a C/C++ program that returns a negative number
int main(int argc, char* argv[])
{
std::cout<< argv[0] << std::endl;
return -1;
}
secondly, run it via perl:
#!/usr/bin/perl
my $rv = system ("minus1.exe");
print "got '$rv'\n";
print "which if we shift it is ", $rv >>8, "\n";
All is OK. Console output shows that minus1.exe is invoked once.
thirdly, expand the perl to use an innocuous module:
#!/usr/bin/perl
use Cwd;
my $dir = cwd();
my $rv = system ("minus1.exe");
print "got '$rv'\n";
print "which if we shift it is ", $rv >>8, "\n";
Now, when you run this, minus1.exe is executed twice. This is the defect.
It also happens with other modules, such as DBI with DBD:Oracle, but Cwd
is easy to use and appears to be part of the base Perl installation.
Now, I've never delved into the source of Perl before, but I've zeroed in
on this code in win32.c:
int
Perl_do_aspawn(pTHX_ SV *really, SV **mark, SV **sp)
<SNIP>
status = win32_spawnvp(flag,
(const char*)(really ? SvPV_nolen(really) : argv[0]),
(const char* const*)argv);
if (status < 0 && (errno == ENOEXEC || errno == ENOENT)) {
/* possible shell-builtin, invoke with shell */
int sh_items;
sh_items = w32_perlshell_items;
while (--index >= 0)
argv[index+sh_items] = argv[index];
while (--sh_items >= 0)
argv[sh_items] = w32_perlshell_vec[sh_items];
status = win32_spawnvp(flag,
(const char*)(really ? SvPV_nolen(really) : argv[0]),
(const char* const*)argv);
}
It checks errno. But, digging into win32_spawnvp a bit further, it's
CreateProcess that's called, not system(). I reckon that CreateProcess
doesn't manipulate errno at all, so what we're seeing is the old use of
errno, which is being set by code in the Cwd module. The code in
win32_spawnvp only sets errno in *some* conditions, and does not reset it.
Hence the unpredictable behaviour.
[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=medium
---
Site configuration information for perl 5.10.0:
Configured by n1007636 at Fri May 9 09:56:08 2008.
Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
Platform:
osname=MSWin32, osvers=5.2, archname=MSWin32-x64-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=define, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cl', ccflags ='-nologo -GF -W3 -Od -MD -Zi -DDEBUGGING -Wp64
-fp:precise -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DWIN64
-DCONSERVATIVE -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
-DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO',
optimize='-Od -MD -Zi -DDEBUGGING -Wp64 -fp:precise',
cppflags='-DWIN32'
ccversion='14.00.50727.762', gccversion='', gccosandvers=''
intsize=4, longsize=4, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
ivtype='__int64', ivsize=8, nvtype='double', nvsize=8,
Off_t='__int64', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='link', ldflags ='-nologo -nodefaultlib -debug
-libpath:"e:\dev\perl64\lib\CORE" -machine:AMD64'
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 bufferoverflowU.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 bufferoverflowU.lib msvcrt.lib
libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl510.lib
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug
-libpath:"e:\dev\perl64\lib\CORE" -machine:AMD64'
Locally applied patches:
---
@INC for perl 5.10.0:
e:/dev/perl64/lib
e:/dev/perl64/site/lib
.
---
Environment for perl 5.10.0:
HOME=e:\Dev\users\n1007636
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=e:\dev\perl64\bin;C:\Program Files x86\Microsoft Visual Studio
8\VC\BIN\amd64;C:\Program Files x86\Microsoft Visual Studio
8\VC\PlatformSDK\bin\win64\amd64;C:\Program Files x86\Microsoft Visual
Studio
8\VC\PlatformSDK\bin;C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727;C:\Program
Files x86\Microsoft Visual Studio 8\VC\VCPackages;C:\Program Files
x86\Microsoft Visual Studio 8\Common7\IDE;C:\Program Files
x86\Microsoft Visual Studio 8\Common7\Tools;C:\Program Files
x86\Microsoft Visual Studio 8\Common7\Tools\bin;C:\Program Files
x86\Microsoft Visual Studio
8\SDK\v2.0\bin;E:\apache-ant-1.7.0\bin;C:\Program Files
(x86)\Legato\nsr\bin;c:\ruby\bin;E:\paramserver\lib;C:\oracle\product\10.2.0\db_1\bin;C:\oracle\product\10.2.0\db_1\OPatch;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program
Files\Java\jdk1.5.0_12\bin;C:\Program Files\Microsoft Visual Studio
8\VC\bin;C:\Program Files\Microsoft Visual Studio
8\Common7\IDE;C:\bea\jrockit90_150_06\bin;C:\Program Files\Microsoft
Visual Studio 8\VC\bin;C:\Program Files
(x86)\cvsnt;E:\Dev\users\n1007636\RogueWaveBin;
PERL_BADLANG (unset)
SHELL (unset)
--
Alistair McDonald, InRevo Ltd (http://www.inrevo.com)
Author of the SpamAssassin book: (http://www.packtpub.com/spamassassin/)
Tel: 07017 467 396 (Office) / 07812 829 020 (Mobile)
Thread Next
-
[perl #54028] Under win32, there is retry logic to spawn a process again, if the return code is negative, and if errno is set to a couple of specific values.
by alistair @ inrevo . com