stevieb has asked for the wisdom of the Perl Monks concerning the following question:

Update: see Re^2: Debug background Perl procs started with compiled C# code (breaks only on AWS) for what I believe is a much simpler way to attempt to reproduce the issue. I can't say for sure what's happening, but the result is the same effect.

Hey fellow Monks,

I have a Perl issue, that's more an OS issue dealing with a Windows sub-cmd calling a Perl application while in the background. I'm hoping one of the Windows Monks might be able to help guide in how I can further troubleshoot (before I open an AWS ticket).

I can only repro the problem on an Amazon Web Services Windows Server. I can not reproduce the issue on a Windows box locally, or anywhere else. I believe the issue is being caused by one of the AWS default installed software applications.

I would greatly appreciate anyone who develops on Windows to test this out and provide feedback, and for those who can debug exe apps and can spare some time, I'll spin you up an AWS instance for testing (/msg, or steveb at cpan email).

Here is my process flow:

This works fine on *nix/Perlbrew, even on AWS systems. I believe it is because the sub-cmd controlling the perl cpanm run is held open by the OS (or other software), and just can't return (in fact, it doesn't appear to start cpanm).

The problem ONLY happens when running the tester on Amazon Web Services Windows servers.

My software works fine on all Windows systems other than AWS, and I have confirmed this repeatedly.

To repro:

Download and install Git for Windows: git, then:

mkdir c:\repos cd c:\repos git clone https://github.com/stevieb9/berrybrew cd berrybrew bin\berrybrew config # type 'y' exit # open new cmd window berrybrew install 5.24.0_64 berrybrew switch 5.24.0_64 exit # open new cmd window cd c:\repos cpanm Test::BrewBuild bbtester start # you can use your own CPAN module below, so long as # it has a git repo; Test::BrewBuild will take care of # the details. A small module repro's quicker git clone https://github.com/stevieb9/file-edit-portable cd file-edit-portable bbdispatch -t localhost

It'll hang here. On a non-AWS system it doesn't.

NOTE: it works perfectly fine when running bbtester in the foreground (ie: bbtester --fg).

Although this condition can not be easily reproduced, I'll still show some code, as this after all, is PerlMonks.

if ($^O =~ /MSWin/){ $log->_6("on Windows, using work dir $work_dir"); my $t; for (split /;/, $ENV{PATH}){ if (-x "$_/perl.exe"){ $perl = "$_/perl.exe"; last; } } for (split /;/, $ENV{PATH}){ if (-e "$_/bbtester"){ $t = "$_/bbtester"; last; } } $log->_6("using command: $perl $t --fg"); @args = ($t, '--fg'); } ... my $bg; if ($^O =~ /MSWin/){ $bg = Proc::Background->new($perl, @args); } else { $bg = Proc::Background->new(@args); }

Full source of this part of the app can be found at here. Entire distribution, Test::BrewBuild.

Here's a snip of the C# berrybrew code. Process is a System.Diagnostic class.

internal static void Exec(StrawberryPerl perl, string command, string +path_env) { Console.WriteLine("Perl-" + perl.Name + "\n=============="); process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Hidden; System.Environment.SetEnvironmentVariable( "PATH", String.Join(";", perl.PerlPath, path_env) ); startInfo.FileName = "cmd.exe"; startInfo.Arguments = "/c " + perl.PerlPath + @"\" + command; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.UseShellExecute = false; process.Start(); Console.WriteLine(process.StandardOutput.ReadToEnd()); Console.WriteLine(process.StandardError.ReadToEnd()); process.WaitForExit(); }

The rest of the code for the Windows berrybrew binary, here.

Again, I know this is a stretch, but if any Monks know how to debug Windows executables properly, I'd be willing to spin you up an AWS instance for troubleshooting.

-stevieb

Replies are listed 'Best First'.
Re: Debug background Perl procs started with compiled C# code (breaks only on AWS)
by BrowserUk (Patriarch) on Aug 01, 2016 at 00:45 UTC

    What happens if you substitute system 1, $perl, @args; for Proc::Background?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.

      I *believe* I have created a much simpler method of reproducing the issue without all of my software necessary. It appears as though on AWS Windows 2012 servers, a ENTER keystroke is required on the server part of the setup before the cpanm gets executed. This is not required on my local win2k8R2 servers.

      If it runs through without having to hit ENTER on the server.pl cmd window, that's what I see on my local boxes.

      To repro:

      - copy below code to client.pl and server.pl respectively - start the server in the background: -- perl server.pl bg - run the client (different cmd window): -- perl client.pl

      On my local servers, the server returns to the client properly without any interaction. On my AWS systems, it hangs exactly like my original problem. Hitting ENTER in the server cmd window causes things to go through.

      NOTE: there's no method in this test code to stop the server.pl background proc. It has to be killed via Task Manager.

      client.pl

      use warnings; use strict; use IO::Socket::INET; use Storable; my $mod = 'IO::Socket::INET'; my $sock = new IO::Socket::INET ( PeerHost => 'localhost', PeerPort => 7800, Proto => 'tcp', ); die "can't create socket\n" unless $sock; $sock->send("cpanm $mod"); my $recv = Storable::fd_retrieve($sock); print $$recv;

      server.pl

      use warnings; use strict; use IO::Socket::INET; use Proc::Background; use Storable; if (@ARGV && $ARGV[0] eq 'bg'){ Proc::Background->new('perl', $0, 'run'); } if (@ARGV && $ARGV[0] eq 'run'){ my $sock = new IO::Socket::INET ( LocalHost => '0.0.0.0', LocalPort => 7800, Proto => 'tcp', Listen => 5, Reuse => 1, ); die "cannot create socket $!\n" unless $sock; while (1){ my $conn = $sock->accept; my $cmd; $conn->recv($cmd, 1024); print "executing: $cmd\n"; my $ret = `$cmd`; print "return: $ret\n"; Storable::nstore_fd(\$ret, $conn); shutdown($conn, 1); } $sock->close; }

      Thanks for the suggestion BrowserUK, but unfortunately, the effects are the same... with system 1, ..., the tester proc goes into the background, and when accessed, the ensuing perl process that calls cpanm hangs like it does with Proc::Background.

      I've never seen system used with the 1 before. Without it (ie. system $perl ...) it works fine, but the process doesn't go into the background (the system call waits). Where is this documented? Unless I'm missing it, I don't see it in system or exec.

      Anyway, I'll keep at this issue for a bit longer, then I'll open an AWS ticket to see if they'll actually help me debug this problem. Perhaps they already know about forking issues...

        I've never seen system used with the 1 before. Without it (ie. system $perl ...) it works fine, but the process doesn't go into the background (the system call waits). Where is this documented?

        Sorry, I'm not sure I've ever seen it documented anywhere. I learned it here 10 o r11 years ago -- probably from Tye -- and used it ever since.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.