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

Hi Monks,

This question is somewhat related to Capturing stdout and segfault of a program.

In general, I am trying to use a perl script to execute and detect whether a program segfaults or not. The interesting thing is shown in the code snippet below:

#!/usr/bin/perl -w $command = $ARGV[0]; my $execOne = "$command"; my $execTwo = "$command &> log "; # Executing ExecOne eval { system($execOne); }; if ($? & 127) { $segval = $? & 127; print "ExecOne Seg: $segval\n"; } else { print "ExecOne: No fault\n"; } # Executing ExecTwo eval { system($execTwo); }; if ($? & 127) { $segval = $? & 127; print "ExecTwo Seg: $segval\n"; } else { print "ExecTwo: No fault\n"; }

Executing the above script with a known program that segfaults gives the following output

ExecOne Seg: 11 ExecTwo: No fault
Does anyone else find this strange?

So my question boils down to why does redirecting the output change the $? value to the extent that the seg fault can no longer be detected?

Is there simply something wrong in my code?

If anyone could shed some light on the matter, it will be greatly appreciated.

Thanks in advance Monks.

Replies are listed 'Best First'.
Re: Different values when using $? to detect seg faults
by VSarkiss (Monsignor) on Mar 08, 2005 at 01:27 UTC
      This line is subtly wrong:
      my $execTwo = "$command &> log ";

      Well, that might depend on what type of shell we're talking about. In bash, the ampersand followed immediately by ">" is the "preferred" way to redirect both stdout and stderr to the named output file, while in a C-shell, you have to use the angle-bracket followed by the ampersand (and bash also supports this order -- who knows why bash doesn't "prefer" it...)

      Anyway, another confounding factor is that the shell invoked by perl's "system()" call might not be the same as the user's login shell, so things that the user can do on the command line might not work in the system() call.

      So, the idea that the command is being backgrounded as well as having stdout redirected is certainly plausible, maybe even likely; but it's also quite understandable that the OP thought he was doing things the right way. The point is: be very careful about system calls that use shell-dependent syntax, and avoid such things as much as possible.

      That's correct. '&' invokes a subshell and *always* returns 0. It can't get the return value of the subshell or the shell's command because it doesn't wait for the subshell to finish.
      --
      jpg
Re: Different values when using $? to detect seg faults
by Zaxo (Archbishop) on Mar 08, 2005 at 04:21 UTC

    In ExecOne there are no shell metacharacters in the single argument to system, so the shell is not invoked and your script is parent to the system call.

    In ExecTwo there are metacharacters in the single argument, so the shell is invoked to run the command, and that shell is the parent. You are seeing the exit status of that shell process.

    After Compline,
    Zaxo