http://qs321.pair.com?node_id=513089

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

I have a script "SCRIPT1" use a system() function call to another perl script "SCRIPT2" that uses DBI. It appears that SCRIPT1 finishes prior to SCRIPT2. HOW COULD THIS BE???\n

I haven't been able to re-create the failure with test code, and I cannot post production code, but $? >> 8 = 16777215 for SCRIPT1 while SCRIPT2 is still running.

The following line of code were executed immediately after the system() and produced the out put below:

Oh, did I mention that it does not fail everytime!!

The following code was added and return the results stated below:

if ($? == -1) { print "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; } else { printf "child exited with value %d\n", $? >> 8; } $exit_value = $? >> 8; $signal_num = $? & 127; $dumped_core = $? & 128; print "$?\n"; print "$exit_value\n"; print "$signal_num\n"; print "$dumped_core\n"; print "$!\n";

failed to execute: Illegal seek
16777215
127
128
child exited with value 127

Problem Solved

The suggestion made by bluto that SCRIPT1 may be getting signaled got me thinking and testing along that path.

What I found is that SCRIPT2 wasn't sending a signal, but SCRIPT1 had an alarm set that would trigger the updating of a timestamp in a logfile.

If that alarm tripped while SCRIPT1 was waiting for a return from the system() call, control would come back to SCRIPT1 prior to SCRIPT2 completing, thus causing our failure condition.

Once, I identified the problem I have been able to re-create this senario in test.

The resolution was to turn the alarm off "alarm(0);" prior to performing the system() call.

Thanks, to all who responded. cbolcato

Replies are listed 'Best First'.
Re: system() does not wait
by ikegami (Patriarch) on Nov 30, 2005 at 20:42 UTC
    system normally waits for the child process to finish, but there are exceptions.
    • If you do system "... &" on unix, system will return without waiting for the child process to finish.
    • If you do system -1, ... on Windows, system will return without waiting for the child process to finish.
    • Some application launch another application and exit immediately (like the Windows command start), so system would return immediately too.
    • Running a windowed (as opposed to console) application in Windows will also cause system to return immediately (IIRC).
      I'm running on a Linux machine and there is no "..&"
Re: system() does not wait
by GrandFather (Saint) on Nov 30, 2005 at 20:45 UTC

    Show us some code. See I know what I mean. Why don't you? for specific hints about posting code for this sort of problem (use a script generated csv if you really need a DB for example).

    Make sure your code demonstrates the problem and only contains pertinent code.


    DWIM is Perl's answer to Gödel
      I haven't been able to re-create with test code, and I cannot post production code, but $? >> 8 = 16777215 for SCRIPT1 while SCRIPT2 is still running.

        Start with your production code and delete a section at a time until you find the sensitive chunk, then focus on that. It is very unlikely that you require the full code for both scripts to reproduce the problem. ikegami's suggestion that you are in some fashion launching a shim that launches something else to do the real work then exits is the best answer so far without any further information, but doesn't sound likely in your case where you are launching another Perl script.

        At the very least post the three or four pertinent lines around the system call.


        DWIM is Perl's answer to Gödel
Re: system() does not wait
by fizbin (Chaplain) on Dec 01, 2005 at 01:23 UTC

    I don't think that SCRIPT2 is ever getting invoked. The reason I think that is that I strongly suspect that $? is -1 inside SCRIPT1. (please post the actual $? value, not $?>>8)

    I strongly urge you to put the following code, taken from the perlfunc manpage where it talks about the system call, after your call to system:

    if ($? == -1) { print "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; } else { printf "child exited with value %d\n", $? >> 8; }
    I suspect that you'll see the "failed to execute" message.
    --
    @/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/; map{y/X_/\n /;print}map{pop@$_}@/for@/
Re: system() does not wait
by Roy Johnson (Monsignor) on Nov 30, 2005 at 20:54 UTC
    If you take care of any global variables, you don't need to use system to call another perl script. You can set up @ARGV and use do.

    Caution: Contents may have been coded under pressure.
Re: system() does not wait
by bluto (Curate) on Nov 30, 2005 at 22:41 UTC
    Is script1 getting signaled (i.e. is the shell's value for ($? & 127) for script1 a non-zero value)? If so, what is the value? system() blocks SIGINT and SIGQUIT, but it's possible another signal is hitting it. I've seen wierd cases where a child spawned a vendor's utility that stupidly signaled the process group (e.g. something like SIGHUP). The child was ready and caught the signal, but the parent was blissfully ignorant of what signals might indirectly be thrown (and died). If this is the case, one way to get around this is to ignore the signal in the parent during the system() call...

    { local $SIG{'HUP'} = 'IGNORE'; # put your signal here system(...); }
    You may get away with just ignoring all of the signals, but that depends on your code.
      The following line of code were executed immediately after the system() and produced the out put below: #CODE $exit_value = $? >> 8; $signal_num = $? & 127; $dumped_core = $? & 128; print "$?\n"; print "$exit_value\n"; print "$signal_num\n"; print "$dumped_core\n";
        sorry the following is the output: #OUTPUT -1 16777215 127 128
Re: system() does not wait
by fizbin (Chaplain) on Dec 01, 2005 at 20:52 UTC

    First off, thank you for adding markup to your post.

    Secondly, I suspect that what's really happening here is that something's preventing SCRIPT2 from launching, but only sometimes - unfortunately, I don't know what that error message means in this context.

    One suggestion is to add a ";" to the end of the string you're passing to system - this will force perl to use /bin/sh to invoke the script, which may be better at telling you the real reason stuff isn't working than perl is. Of course, if you already have a | character in your system call, that isn't going to help.

    I'm very puzzled by the idea that this happens only occasionally.

    --
    @/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/; map{y/X_/\n /;print}map{pop@$_}@/for@/
      I can assure you that SCRIPT2 is executing every time. The script writes messages to a log file that prove it is running.

      Remember from my original post that SCRIPT2 is using DBI/DBD::Oracle is it possible the DBI or DBD may be throwing a signal.

A reply falls below the community's threshold of quality. You may see it by logging in.