Navigation Menu

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

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. #9323

Open
p5pRT opened this issue May 12, 2008 · 3 comments

Comments

@p5pRT
Copy link

p5pRT commented May 12, 2008

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

Searchable as RT54028$

@p5pRT
Copy link
Author

p5pRT commented May 12, 2008

From alistair@inrevo.com

Created by alistair@inrevo.com

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.

Perl Info

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)


@p5pRT
Copy link
Author

p5pRT commented May 13, 2008

From @sisyphus

----- Original Message -----
From​: "alistair@​inrevo.com (via RT)" <perlbug-followup@​perl.org>
To​: <bugs-bitbucket@​netlabs.develooper.com>
.
.

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.

Even at this stage, I find that minus1.exe is invoked *twice* on most of my
builds of Windows perl - 5.8.8, 5.10.0 (including a 64-bit build of AS
perl-5.10.0), and 5.11.0. Perl 5.6.2 gets it right.

I guess "unpredictably" is the key adverb.

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented May 13, 2008

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