In perl, how do we detect a segmentation error in an external command

Below is the C code that is meant to fail:

#include<stdio.h> #include<stdlib.h> int main() { char *p = NULL; printf("Value at P: %c\n", *p); return 0; } 

When I compile and run it (RH4 machine with gcc 4.5.2), it predictably gives a segmentation error:

 % ./a.out Segmentation fault % echo $status 139 

If I run it with Perl v5.8.5, this will happen:

 % perl -e 'system("./a.out") and die "Status: $?"' Status: 11 at -e line 1. 

Perlvar documentation for $? says that

So the output value of the subprocess is really ($?>> 8 ) , and $? & 127 $? & 127 indicates which signal, if any, has passed away, and $? & 128 $? & 128 reports whether there was a core dump.

11 >> 8 0 , and 11 & 127 - 11 .

Why different exit statuses? If we cannot depend on the exit status, what should be the way to detect a segmentation error in an external command?

+7
perl
source share
2 answers

Reading the documentation for system may answer your question:

 system('a.out'); 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; } 

Output:

 child died with signal 11, without coredump 

The shell simply encodes the signal in status differently: 139 - 128 = 11. For example, man bash says:

The return value of a simple command is the exit state or 128 + n if the command is completed with signal n.

+13
source share

OS always sees the same ... that is returned by the wait (2) family of functions. system (3), et. all call wait (2). The way it regards you is what makes the difference. The shell and programs do different things and communicate different ways. The need to shift right 8 to get the most general exit status will be very annoying in shell programs and confuse less experienced users.

While the very first UNIX systems I used (genuine Unix) had the same results, I always wondered if the pre-release versions were different and the signal return, and core / dump is a later addition.

My preferred reporting of exit status tends to cause the computer to break my bits for me.

  my $ x = $ ?;  #save status
    print ("Exit status:% d.% d% s \ n",
               $ x >> 8, $ x & 127, ($ x & 128)? "*": ""); 
+3
source share

All Articles