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

unexpected exit in open3() on win32 #9214

Open
p5pRT opened this issue Jan 29, 2008 · 9 comments
Open

unexpected exit in open3() on win32 #9214

p5pRT opened this issue Jan 29, 2008 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 29, 2008

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

Searchable as RT50374$

@p5pRT
Copy link
Author

p5pRT commented Jan 29, 2008

From adavies@ptc.com

Created by adavies@ptc.com

IPC​::Open3​::open3() appears to exit on Win32 when STDOUT is redirected
_and_ it is called via the associated perl. It works as expected
if only one of the above conditions is met.
Here's a walk thro'​:

  D​:\>cat open3_testcase.pl

require IPC::Open3;
require IO::File;
my $cmd = "find.exe ."; # a random command to run
*CMD_ERR = IO::File->new_tmpfile;
print "start $^X\n";
my $pid = eval {
IPC::Open3::open3(undef, \*CMD_OUT, ">&CMD_ERR", $cmd);
};

$@ and die "failed to run $cmd\n$@";
print "end $pid\n";
D:\>open3_testcase.pl
start C:\perl3\bin\perl5.8.7.exe
end 812

D:\>C:\perl3\bin\perl5.8.7.exe open3_testcase.pl
start C:\perl3\bin\perl5.8.7.exe
end 2816

D:\>C:\perl3\bin\perl5.8.7.exe open3_testcase.pl > output

D:\>cat output
start C:\perl3\bin\perl5.8.7.exe
end 1880

D:\>open3_testcase.pl > output

D:\>cat output
start C:\perl3\bin\perl5.8.7.exe

D:\>

By placing print statements into IPC::Open3, it appears to be exiting
during the call to:

# line 323 VERSION 1.0106
$fd->{handle}->fdopen($saved{fileno $fd->{open_as}} ||
$fd->{open_as},
$fd->{mode});

Any idea what's happening here? Is it a bug?

Cheers, alex.

Perl Info

Flags:
    category=library
    severity=low

Site configuration information for perl v5.8.7:

Configured by adavies at Thu Aug 11 14:02:10 2005.

Summary of my perl5 (revision 5 version 8 subversion 7) configuration:
  Platform:
    osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    usethreads=define use5005threads=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 -MD -DNDEBUG -O1 -DWIN32
-D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT  -DPERL_IMPLICIT_CONTEXT
-DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX',
    optimize='-MD -DNDEBUG -O1',
    cppflags='-DWIN32'
    ccversion='12.00.8804', gccversion='', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
    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 -release
-libpath:"c:\perl3\lib\CORE"  -machine:x86'
    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 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 msvcrt.lib
    libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib
    gnulibc_version='undef'
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release
-libpath:"c:\perl3\lib\CORE"  -machine:x86'

Locally applied patches:
    


@INC for perl v5.8.7:
    C:/perl3/lib
    C:/perl3/site/lib
    .


Environment for perl v5.8.7:
    HOME=C:\alex
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=C:\Program
Files\Tcl-8.4.8.0\bin;C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;
C:\perl3\bin;D:\alex\bin;C:\cygwin\bin;C:\Program
Files\Perforce;C:\Program Files\Microsoft Visual
Studio\VC98\Bin;C:\Program Files\Microsoft Visual
Studio\Common\MSDev98\Bin;C:\Program Files\Microsoft Visual
Studio\VC98\MFC\Lib;C:\Program
Files\Tcl-8.5.0.0_singlethreaded\bin;D:\data\ruby-1.85-21\bin;C:\Program
Files\Tcl-8.5.0.0b5\bin;C:\Program Files\QuickTime\QTSystem\;C:\Program
Files\Microsoft SQL Server\90\Tools\binn\
    PERL_BADLANG (unset)
    SHELL (unset)


@p5pRT
Copy link
Author

p5pRT commented Aug 13, 2012

From @jkeenan

Is there anyone on a supported version of Win32 who could take a look at
this problem and report whether it persists on a supported version of
Perl (5.14 or 5.16)?

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Aug 13, 2012

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

@p5pRT
Copy link
Author

p5pRT commented Mar 11, 2014

From @bulk88

Reproduced with 5.12.2 and some blead of 5.19.4


C​:\Documents and Settings\Administrator\Desktop>perl n1.pl
Name "main​::CMD_ERR" used only once​: possible typo at n1.pl line 68.
Name "main​::CMD_OUT" used only once​: possible typo at n1.pl line 71.
start C​:\Perl\bin\perl.exe
end 3040

C​:\Documents and Settings\Administrator\Desktop>n1.pl > t.txt
Name "main​::CMD_ERR" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 68.
Name "main​::CMD_OUT" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 71.

C​:\Documents and Settings\Administrator\Desktop>type t.txt
start C​:\Perl\bin\perl.exe

C​:\Documents and Settings\Administrator\Desktop>perl n1.pl > t.txt
Name "main​::CMD_ERR" used only once​: possible typo at n1.pl line 68.
Name "main​::CMD_OUT" used only once​: possible typo at n1.pl line 71.

C​:\Documents and Settings\Administrator\Desktop>type t.txt
start C​:\Perl\bin\perl.exe
end 2484

C​:\Documents and Settings\Administrator\Desktop>perl 0v
Can't open perl script "0v"​: No such file or directory

C​:\Documents and Settings\Administrator\Desktop>perl -v

This is perl 5, version 12, subversion 3 (v5.12.3) built for MSWin32-x86-multi-t
hread
(with 9 registered patches, see perl -V for more detail)

Copyright 1987-2010, Larry Wall

Binary build 1204 [294330] provided by ActiveState http​://www.ActiveState.com
Built Feb 9 2011 14​:38​:22

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http​://www.perl.org/, the Perl Home Page.

C​:\Documents and Settings\Administrator\Desktop>


C​:\Documents and Settings\Administrator\Desktop>perl n1.pl
Name "main​::CMD_ERR" used only once​: possible typo at n1.pl line 68.
Name "main​::CMD_OUT" used only once​: possible typo at n1.pl line 71.
start C​:\p519\bin\perl.exe
end 536

C​:\Documents and Settings\Administrator\Desktop>n1.pl
Name "main​::CMD_OUT" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 71.
Name "main​::CMD_ERR" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 68.
start C​:\p519\bin\perl.exe
end 1704

C​:\Documents and Settings\Administrator\Desktop>n1.pl > t.txt
Name "main​::CMD_OUT" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 71.
Name "main​::CMD_ERR" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 68.
Use of uninitialized value $fd in pattern match (m//) at C​:/p519/lib/IO/Handle.p
m line 374.
Use of uninitialized value $fd in concatenation (.) or string at C​:/p519/lib/IO/
Handle.pm line 379.

C​:\Documents and Settings\Administrator\Desktop>type t.txt
start C​:\p519\bin\perl.exe

C​:\Documents and Settings\Administrator\Desktop>perl -v

This is perl 5, version 19, subversion 4 (v5.19.4) built for MSWin32-x86-multi-t
hread
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-2013, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http​://www.perl.org/, the Perl Home Page.

C​:\Documents and Settings\Administrator\Desktop>
C​:\Documents and Settings\Administrator\Desktop>perl n1.pl > t.txt
Name "main​::CMD_ERR" used only once​: possible typo at n1.pl line 68.
Name "main​::CMD_OUT" used only once​: possible typo at n1.pl line 71.

C​:\Documents and Settings\Administrator\Desktop>type t.txt
start C​:\p519\bin\perl.exe
end 1000

C​:\Documents and Settings\Administrator\Desktop>


C​:/p519/lib/IO/Handle.pm


sub fdopen {
  @​_ == 3 or croak 'usage​: $io->fdopen(FD, MODE)';
  my ($io, $fd, $mode) = @​_;
  local(*GLOB);

  if (ref($fd) && "".$fd =~ /GLOB\(/o) {
  # It's a glob reference; Alias it as we cannot get name of anon GLOBs
  my $n = qualify(*GLOB);
  *GLOB = *{*$fd};
  $fd = $n;
  } elsif ($fd =~ m#^\d+$#) {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<LINE 374
  # It's an FD number; prefix with "=".
  $fd = "=$fd";
  }

  open($io, _open_mode_string($mode) . '&' . $fd)<<<<<<<<<<<<<<<<<LINE 379
  ? $io : undef;
}


some debugging output, i edited the file assoc in registry to include -d to make the below


main​::(C​:\Documents and Settings\Administrator\Desktop\n1.pl​:74)​:
74​: print "start $^X\n";
  DB<1> n
main​::(C​:\Documents and Settings\Administrator\Desktop\n1.pl​:75)​:
75​: my $pid = eval {
  DB<1> n
main​::(C​:\Documents and Settings\Administrator\Desktop\n1.pl​:76)​:
76​: IPC​::Open3​::open3(undef, \*CMD_OUT, ">&CMD_ERR", $cmd);
  DB<1> n
Use of uninitialized value $fd in pattern match (m//) at C​:/p519/lib/IO/Handle.p
m line 369.
at C​:/p519/lib/IO/Handle.pm line 369.
  IO​::Handle​::fdopen(IO​::Handle=GLOB(0x1c4c14c), undef, ">") called at C​:/
p519/lib/IPC/Open3.pm line 416
  IPC​::Open3​::spawn_with_handles(ARRAY(0x243e714), ARRAY(0x24512ec), "find
.exe .") called at C​:/p519/lib/IPC/Open3.pm line 335
  eval {...} called at C​:/p519/lib/IPC/Open3.pm line 334
  IPC​::Open3​::_open3(undef, undef, undef, undef, "find.exe .") called at C
:/p519/lib/IPC/Open3.pm line 358
  IPC​::Open3​::open3(undef, GLOB(0x2175c1c), ">&CMD_ERR", "find.exe .") cal
led at C​:\Documents and Settings\Administrator\Desktop\n1.pl line 76
  eval {...} called at C​:\Documents and Settings\Administrator\Desktop\n1.
pl line 75
Use of uninitialized value $fd in concatenation (.) or string at C​:/p519/lib/IO/
Handle.pm line 379.
at C​:/p519/lib/IO/Handle.pm line 379.
  IO​::Handle​::fdopen(IO​::Handle=GLOB(0x1c4c14c), undef, ">") called at C​:/
p519/lib/IPC/Open3.pm line 416
  IPC​::Open3​::spawn_with_handles(ARRAY(0x243e714), ARRAY(0x24512ec), "find
.exe .") called at C​:/p519/lib/IPC/Open3.pm line 335
  eval {...} called at C​:/p519/lib/IPC/Open3.pm line 334
  IPC​::Open3​::_open3(undef, undef, undef, undef, "find.exe .") called at C
:/p519/lib/IPC/Open3.pm line 358
  IPC​::Open3​::open3(undef, GLOB(0x2175c1c), ">&CMD_ERR", "find.exe .") cal
led at C​:\Documents and Settings\Administrator\Desktop\n1.pl line 76
  eval {...} called at C​:\Documents and Settings\Administrator\Desktop\n1.
pl line 75
main​::(C​:\Documents and Settings\Administrator\Desktop\n1.pl​:78)​:
78​: $@​ and die "failed to run $cmd\n$@​";
  DB<1> n
main​::(C​:\Documents and Settings\Administrator\Desktop\n1.pl​:79)​:
79​: print "end $pid\n";
  DB<1> n
Debugged program terminated. Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.
  DB<1> q

C​:\Documents and Settings\Administrator\Desktop>type t.txt
start C​:\p519\bin\perl.exe

C​:\Documents and Settings\Administrator\Desktop>


Changing the last print to a warn does print to console, so the "unexpected exit" conclusion is a confused ticket reporter. Instead redirecting or handle closure is happening in the print call. IDK which, stdio and this whole ticket beyond my knowledge but I'm replying because there is nobody else to investigate it.


use Devel​::Peek 'Dump';
use feature qw(say);
use Win32API​::File;
$DB​::single = 1;
  require IPC​::Open3;
  require IO​::File;
  my $cmd = "find.exe ."; # a random command to run
  *CMD_ERR = IO​::File->new_tmpfile;
  Dump(*CMD_ERR{IO}, 100);
  warn(Win32API​::File​::GetOsFHandle(*CMD_ERR{IO})."\n");
  print "start $^X\n";
  my $pid = eval {
  IPC​::Open3​::open3(undef, \*CMD_OUT, ">&CMD_ERR", $cmd);
  };
  $@​ and die "failed to run $cmd\n$@​";
  $ret = print("end $pid\n");
  warn $ret;


C​:\Documents and Settings\Administrator\Desktop>n1.pl > t.txt
Name "main​::CMD_OUT" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 76.
Name "DB​::single" used only once​: possible typo at C​:\Documents and Settings\Adm
inistrator\Desktop\n1.pl line 67.
SV = IV(0x1c29d28) at 0x1c29d2c
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x1c4d1e4
  SV = PVIO(0x1c4ef04) at 0x1c4d1e4
  REFCNT = 2
  FLAGS = (OBJECT)
  STASH = 0x1c4d194 "IO​::File"
  IFP = 0x1c45d24
  OFP = 0x1c45d24
  DIRP = 0x0
  LINES = 0
  PAGE = 0
  PAGE_LEN = 60
  LINES_LEFT = 0
  TOP_GV = 0x0
  FMT_GV = 0x0
  BOTTOM_GV = 0x0
  TYPE = '+'
  FLAGS = 0x0
160
Use of uninitialized value $fd in pattern match (m//) at C​:/p519/lib/IO/Handle.p
m line 374.
Use of uninitialized value $fd in concatenation (.) or string at C​:/p519/lib/IO/
Handle.pm line 379.
1 at C​:\Documents and Settings\Administrator\Desktop\n1.pl line 80.

C​:\Documents and Settings\Administrator\Desktop>type t.txt
start C​:\p519\bin\perl.exe

C​:\Documents and Settings\Administrator\Desktop>


This is all I figured so far.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Mar 11, 2014

From @bulk88

On Tue Mar 11 00​:36​:40 2014, bulk88 wrote​:

This is all I figured so far.

hacking up fdopen in IO​::Handle


sub fdopen {
  @​_ == 3 or croak 'usage​: $io->fdopen(FD, MODE)';
  my ($io, $fd, $mode) = @​_;
  $DB​::single = 1;
  local(*GLOB);

  if (ref($fd) && "".$fd =~ /GLOB\(/o) {
  # It's a glob reference; Alias it as we cannot get name of anon GLOBs
  my $n = qualify(*GLOB);
  *GLOB = *{*$fd};
  $fd = $n;
  } elsif ($fd =~ m#^\d+$#) {
  # It's an FD number; prefix with "=".
  $fd = "=$fd";
  }
use Devel​::Peek;
  #Dump($io,100);
  my $omode = _open_mode_string($mode) . '&' . $fd;
  #warn "om $omode";
  my $ret = open($io, $omode);
  warn "ret '$ret' err '$!' oserr ".Win32​::GetLastError()." omode '$omode'" if ! defined $ret, 1;
  return $ret ? $io : undef;
}


On no redirect run.


C​:\Documents and Settings\Administrator\Desktop>n1.pl
Useless use of not in void context at C​:/p519/lib/IO/Handle.pm line 384.
Name "main​::CMD_OUT" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 76.
Name "main​::CMD_ERR" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 71.
start C​:\p519\bin\perl.exe
ret '1' err 'Bad file descriptor' oserr 6 omode '<&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
ret '1' err 'Bad file descriptor' oserr 6 omode '>&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
ret '1' err 'Bad file descriptor' oserr 6 omode '>&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
ret '1' err 'Inappropriate I/O control operation' oserr 6 omode '<&*IO​::Handle​::
GLOB' at C​:/p519/lib/IO/Handle.pm line 384.
ret '1' err 'Inappropriate I/O control operation' oserr 5 omode '>&*IO​::Handle​::
GLOB' at C​:/p519/lib/IO/Handle.pm line 384.
ret '1' err 'Bad file descriptor' oserr 6 omode '>&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
ret '1' err 'Bad file descriptor' oserr 6 omode '>&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
ret '1' err 'Bad file descriptor' oserr 6 omode '<&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
end 2684
1 at C​:\Documents and Settings\Administrator\Desktop\n1.pl line 80.

C​:\Documents and Settings\Administrator\Desktop>


With redirect.


C​:\Documents and Settings\Administrator\Desktop>n1.pl > t.txt
Useless use of not in void context at C​:/p519/lib/IO/Handle.pm line 384.
Name "main​::CMD_ERR" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 71.
Name "main​::CMD_OUT" used only once​: possible typo at C​:\Documents and Settings\
Administrator\Desktop\n1.pl line 76.
ret '1' err 'Bad file descriptor' oserr 6 omode '<&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
Use of uninitialized value $ret in concatenation (.) or string at C​:/p519/lib/IO
/Handle.pm line 384.
ret '' err 'Permission denied' oserr 5 omode '>&*IO​::Handle​::GLOB' at C​:/p519/li
b/IO/Handle.pm line 384.
tmp copy fail at C​:/p519/lib/IPC/Open3.pm line 368.
ret '1' err 'Bad file descriptor' oserr 6 omode '>&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
ret '1' err 'Inappropriate I/O control operation' oserr 6 omode '<&*IO​::Handle​::
GLOB' at C​:/p519/lib/IO/Handle.pm line 384.
ret '1' err 'Inappropriate I/O control operation' oserr 5 omode '>&*IO​::Handle​::
GLOB' at C​:/p519/lib/IO/Handle.pm line 384.
ret '1' err 'Bad file descriptor' oserr 6 omode '>&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
Use of uninitialized value $fd in pattern match (m//) at C​:/p519/lib/IO/Handle.p
m line 375.
Use of uninitialized value $fd in concatenation (.) or string at C​:/p519/lib/IO/
Handle.pm line 381.
Use of uninitialized value $ret in concatenation (.) or string at C​:/p519/lib/IO
/Handle.pm line 384.
ret '' err 'Invalid argument' oserr 6 omode '>&' at C​:/p519/lib/IO/Handle.pm lin
e 384.
ret '1' err 'Bad file descriptor' oserr 6 omode '<&*IO​::Handle​::GLOB' at C​:/p519
/lib/IO/Handle.pm line 384.
1 at C​:\Documents and Settings\Administrator\Desktop\n1.pl line 80.


oserr 5 is "ERROR_ACCESS_DENIED 5 (0x5) Access is denied."

It came from the following C call stack


  /* use the file handle to get all the info about the file
  */
  if ( !GetFileInformationByHandle((HANDLE)_osfhnd(fildes), &bhfi) ) {<<<<<<<<<<<<<<<<<<<<<<<<<<
  _dosmaperr(GetLastError());
  retval = -1;
  goto done;
  }


msvcr90.dll!_fstat64(int fildes=9, _stat64 * buf=0x785bd6a0) Line 182 C
  perl519.dll!PerlLIOFileStat(IPerlLIO * piPerl=0x01c272c4, int handle=9, _stat64 * buffer=0x01c244c4) Line 971 + 0xd bytes C++
  perl519.dll!Perl_do_openn(interpreter * my_perl=0x00000002, gv * gv=0x0204f5bc, const char * oname=0x02122894, long len=19, int as_raw=0, int rawmode=0, int rawperm=0, _PerlIO * * supplied_fp=0x00000000, sv * * svp=0x021a654c, long num_svs=0) Line 575 + 0x14 bytes C
  perl519.dll!Perl_pp_open(interpreter * my_perl=0x0204f5bc) Line 641 C
  perl519.dll!Perl_runops_standard(interpreter * my_perl=0x01c243e4) Line 42 + 0x4 bytes C
  perl519.dll!S_run_body(interpreter * my_perl=0x00000000, long oldscope=1) Line 2500 + 0xa bytes C
  perl519.dll!perl_run(interpreter * my_perl=0x01c243e4) Line 2416 + 0x8 bytes C
  perl519.dll!RunPerl(int argc=2, char * * argv=0x01c231f0, char * * env=0x01c235d0) Line 270 + 0x6 bytes C++
  perl.exe!main(int argc=2, char * * argv=0x01c231f0, char * * env=0x01c235d0) Line 23 + 0x12 bytes C
  perl.exe!__tmainCRTStartup() Line 582 + 0x17 bytes C
  kernel32.dll!_BaseProcessStart@​4() + 0x28 bytes


Which tickles down to pp_open, which returns undef in PP land.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Mar 11, 2014

From @bulk88

Broke issue down to, there are no crashes DebugBreak() hits below


C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS>perl n1.pl
0 6 11 at n1.pl line 4.

C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS>n1.pl
0 6 11 at C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS\n1.pl lin
e 4.

C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS>n1.pl > t.txt
0 5 4 at C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS\n1.pl line
4.

C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS>perl n1.pl > t.txt

C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS>


void
pipetest()
PPCODE​:
  HANDLE read;
  HANDLE write;
  BY_HANDLE_FILE_INFORMATION FileInformation;
  if(!CreatePipe(&read, &write, NULL, 1024))
  DebugBreak();
  if(!GetFileInformationByHandle(read, &FileInformation))
  DebugBreak();
  if(!GetFileInformationByHandle(_get_osfhandle(1), &FileInformation))
  warn("%i %i %i", 0, GetLastError(), _get_osfhandle(1)),
// DebugBreak();


#this is n1.pl for THIS POST ONLY
#!/usr/bin/perl -w
use strict;
use Local​::XS;
Local​::XS​::pipetest();


--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Mar 12, 2014

From @bulk88

To debug further, I ask how does cmd.exe start "n1.pl > t.txt"?


  shell32.dll!_ShellExecuteExW@​4()
  cmd.exe!_ExecPgm@​28() + 0x112e2 bytes
  cmd.exe!_ECWork@​12() + 0x6e bytes
  cmd.exe!_ExtCom@​4() + 0x43 bytes
  cmd.exe!_FindFixAndRun@​4() + 0x72d7 bytes
  cmd.exe!_Dispatch@​8() + 0x76 bytes
  cmd.exe!_main() + 0x5701 bytes
  cmd.exe!_mainCRTStartup() + 0x116 bytes
  kernel32.dll!_BaseProcessStart@​4() + 0x28 bytes


Notice this isn't CreateProcess but a "you cant specify child handles" derivative. What was passed To ShellExecuteEx?

SHELLEXECUTEINFO struct

0x002CFB00 0000003c <...size
0x002CFB04 00088140 @​...mask
0x002CFB08 00000000 ....hwnd
0x002CFB0C 00000000 ....verb
0x002CFB10 002d48e8 èH-.file
0x002CFB14 002edf00 .ß..param
0x002CFB18 4ad34460 `DÓJdirectory
0x002CFB1C 00000001 ....show
0x002CFB20 00000000 ....
0x002CFB24 00000000 ....
0x002CFB28 00000000 ....
0x002CFB2C 00000000 ....
0x002CFB30 00000000 ....
0x002CFB34 00000000 ....
0x002CFB38 00000000 ....

(wchar_t *)0x002D48E8
0x002d48e8 "C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS\n1.pl"

(wchar_t *)0x002edf00
0x002edf00 " "

(wchar_t *)0x4ad34460
0x4ad34460 "C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS"

break up the bitfield
0x002CFB04 00088140 @​...mask

SEE_MASK_NOCLOSEPROCESS (0x00000040)
SEE_MASK_NOASYNC (0x00000100)
SEE_MASK_NO_CONSOLE (0x00008000)

flag 0x00080000 is undocumented

http​://www.reactos.org/archives/public/ros-diffs/2013-March/048151.html

http​://doxygen.reactos.org/df/dd3/shellapi_8h_source.html#l00050

0x00040000 is the last documented undocumented flag

section "Pass arbitrary data to a child process!" in http​://www.catch22.net/tuts/undocumented-createprocess#undoc might be relevent somehow to this bug (a WAG)

lets see where ShellExecuteExW takes us

kernel32.dll!_CreateProcessW@​40()
  shell32.dll!_SHCreateProcess() + 0x131 bytes
  shell32.dll!CShellExecute​::_DoExecCommand() + 0xb4 bytes
  shell32.dll!CShellExecute​::_TryInvokeApplication() + 0x44 bytes
  shell32.dll!CShellExecute​::ExecuteNormal() + 0xb4 bytes
  shell32.dll!_ShellExecuteNormal@​4() + 0x30 bytes
  shell32.dll!_ShellExecuteExW@​4() + 0x68 bytes
  cmd.exe!_ExecPgm@​28() + 0x112e2 bytes
  cmd.exe!_ECWork@​12() + 0x6e bytes
  cmd.exe!_ExtCom@​4() + 0x43 bytes
  cmd.exe!_FindFixAndRun@​4() + 0x72d7 bytes
  cmd.exe!_Dispatch@​8() + 0x76 bytes
  cmd.exe!_main() + 0x5701 bytes
  cmd.exe!_mainCRTStartup() + 0x116 bytes
  kernel32.dll!_BaseProcessStart@​4() + 0x28 bytes

to be continued

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Mar 14, 2014

From @bulk88

On Tue Mar 11 19​:09​:27 2014, bulk88 wrote​:

to be continued

lets see where ShellExecuteExW takes us

  kernel32.dll!_CreateProcessW@​40()
  shell32.dll!_SHCreateProcess() + 0x131 bytes
  shell32.dll!CShellExecute​::_DoExecCommand() + 0xb4 bytes
  shell32.dll!CShellExecute​::_TryInvokeApplication() + 0x44 bytes
  shell32.dll!CShellExecute​::ExecuteNormal() + 0xb4 bytes
  shell32.dll!_ShellExecuteNormal@​4() + 0x30 bytes
  shell32.dll!_ShellExecuteExW@​4() + 0x68 bytes
  cmd.exe!_ExecPgm@​28() + 0x112e2 bytes
  cmd.exe!_ECWork@​12() + 0x6e bytes
  cmd.exe!_ExtCom@​4() + 0x43 bytes
  cmd.exe!_FindFixAndRun@​4() + 0x72d7 bytes
  cmd.exe!_Dispatch@​8() + 0x76 bytes
  cmd.exe!_main() + 0x5701 bytes
  cmd.exe!_mainCRTStartup() + 0x116 bytes
  kernel32.dll!_BaseProcessStart@​4() + 0x28 bytes

0x002CEFC8 002f46e4 äF/.lpApplicationName,
0x002CEFCC 002f244c L$/.lpCommandLine,
0x002CEFD0 00000000 ....
0x002CEFD4 00000000 ....
0x002CEFD8 00000000 ....BOOL bInheritHandles,
0x002CEFDC 04000400 .... DWORD dwCreationFlags,
0x002CEFE0 00000000 ....
0x002CEFE4 002f2244 D"/.lpCurrentDirectory
0x002CEFE8 002f5d48 H]/.lpStartupInfo,
0x002CEFEC 002f5d94 ”]/.

0x002f46e4 "C​:\p519\bin\perl.exe"
(wchar_t *)0x002f244c
0x002f244c ""C​:\p519\bin\perl.exe" "C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS\n1.pl" "
(wchar_t *)0x002f2244
0x002f2244 "C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS"

0x002CEFDC 04000400 .... DWORD dwCreationFlags,

CREATE_DEFAULT_ERROR_MODE
0x04000000
CREATE_UNICODE_ENVIRONMENT
0x00000400

lpStartupInfo

0x002F5D48 00000044 D...
0x002F5D4C 00000000 ....
0x002F5D50 00000000 ....
0x002F5D54 00000000 ....
0x002F5D58 00000000 ....
0x002F5D5C 00000000 ....
0x002F5D60 00000000 ....
0x002F5D64 00000000 ....
0x002F5D68 00000000 ....
0x002F5D6C 00000000 ....
0x002F5D70 00000000 ....
0x002F5D74 00000001 ....
0x002F5D78 00000001 ....
0x002F5D7C 00000000 ....
0x002F5D80 00000000 .... the 3 handles are last 3 members
0x002F5D84 00000000 ....
0x002F5D88 00000000 ....

ShellExecuteExW returns 1 success.

command line file assoc launched and redirect perl is

"C​:\p519\bin\perl.exe" "C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS\n1.pl"

important thing is no > t.txt in there

So lets research the handle types. I used some crude code to do it.

n1.pl


#!/usr/bin/perl -w
use strict;
use Local​::XS;
#system 'pause';
Local​::XS​::pipetest();


void
pipetest()
PPCODE​:
  HANDLE read;
  HANDLE write;
  HANDLE stdouth = _get_osfhandle(1);
  HANDLE stdouth2;
  BY_HANDLE_FILE_INFORMATION FileInformation;
DWORD devicetype;
  NTSTATUS Status;
  {
  FILE_FS_DEVICE_INFORMATION DeviceInfo;
  IO_STATUS_BLOCK StatusBlock;
  HANDLE hFile = stdouth;
  HANDLE ntdll = LoadLibrary("ntdll");
 

  sNtQueryVolumeInformationFile NtQueryVolumeInformationFile = GetProcAddress(ntdll, "NtQueryVolumeInformationFile");

  if(!DuplicateHandle(
GetCurrentProcess(),
stdouth,
GetCurrentProcess(),
&stdouth2,
  0,
  FALSE,
  DUPLICATE_SAME_ACCESS
)) DebugBreak();
  stdouth = stdouth2;

  Status = NtQueryVolumeInformationFile(hFile,
  &StatusBlock,
  &DeviceInfo,
  sizeof(FILE_FS_DEVICE_INFORMATION),
  FileFsDeviceInformation);
  devicetype = DeviceInfo.DeviceType;
  //DebugBreak();
  }

  if(!CreatePipe(&read, &write, NULL, 1024))
  DebugBreak();
  if(!GetFileInformationByHandle(read, &FileInformation))
  DebugBreak();
  {
  bool GFIBH = !!GetFileInformationByHandle(stdouth, &FileInformation);
  DWORD glr = GetLastError();
  warn("GFIBH ret %i GLR %i HND %i Type %i NtQVIF %x NTType %i"
  , GFIBH, glr , stdouth, GetFileType(stdouth), Status, devicetype);
  }


C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS>n1.pl
GFIBH ret 0 GLR 6 HND 7 Type 2 NtQVIF c0000024 NTType 671836069 at C​:\Documents
and Settings\Administrator\Desktop\lxs\Local-XS\n1.pl line 5.

C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS>n1.pl > t.txt
GFIBH ret 0 GLR 5 HND 160 Type 1 NtQVIF 0 NTType 7 at C​:\Documents and Settings\
Administrator\Desktop\lxs\Local-XS\n1.pl line 5.

C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS>perl n1.pl
GFIBH ret 0 GLR 6 HND 7 Type 2 NtQVIF c0000008 NTType 671836069 at n1.pl line 5.

C​:\Documents and Settings\Administrator\Desktop\lxs\Local-XS>perl n1.pl > t.txt
GFIBH ret 1 GLR 0 HND 876 Type 1 NtQVIF 0 NTType 7 at n1.pl line 5.


GLR
ERROR_SUCCESS
  0 (0x0)
  The operation completed successfully.
ERROR_ACCESS_DENIED
  5 (0x5)
  Access is denied.
ERROR_INVALID_HANDLE
  6 (0x6)
  The handle is invalid.

Type
FILE_TYPE_CHAR
0x0002
The specified file is a character file, typically an LPT device or a console.

FILE_TYPE_DISK
0x0001
The specified file is a disk file.

NtQVIF
0xC0000024
STATUS_OBJECT_TYPE_MISMATCH
{Wrong Type} There is a mismatch between the type of object that is required by the requested operation and the type of object that is specified in the request.

0xC0000008
STATUS_INVALID_HANDLE
An invalid HANDLE was specified.

0x00000000
STATUS_SUCCESS
The operation completed successfully.

NTType
#define FILE_DEVICE_DISK 0x00000007
others are uninitialized memory of failed calls

--
bulk88 ~ bulk88 at hotmail.com

@toddr
Copy link
Member

toddr commented Feb 12, 2020

@bulk88 what did we learn? You left us on a cliff hanger!

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