perl fork() how to check if child crashed











up vote
1
down vote

favorite












I have some Perl code that generates a number of child processes. The basic code is as follows:



 my $forked = 0;
my $err = 0;
my $Processes_To_Use_After_Calc=10;
print "Parent ($$) has startedn";
for my $ispawn (1 .. $Processes_To_Use_After_Calc){
my $child_pid = fork();
die "Cannot fork: $!" if !defined $child_pid; # system overload
if(defined $child_pid && $child_pid > 0) {
## Parent
$forked++;
} elsif(defined $child_pid){
#
# Here some calculations are performed
#
print "Child $$ has finished (number $ispawn) n";
}
}
for(1..$forked) {
my $child_pid = wait();
}


All fairly standard stuff. Now, I would like to know if any of the child processes crash (failed to terminate correctly). Clearly if the last statement of each child process is not printed I could assume there was a problem. However I would like another method that would exit the parent program completely and close all child processes that were still open if one of the child processes crashes. Is this possible?










share|improve this question






















  • What are the exit codes of crashing children? wait() returns that exit code, so you can act on that.
    – Corion
    Nov 8 at 11:55










  • wait returns a process id but sets the exit code in $? as a side-effect.
    – mob
    Nov 8 at 14:17










  • "failrly standard stuff" -- note though that the blocking wait waits for one process one at a time. So if something takes longer you won't know about any others before that one's done. (And what if one locks up?) Consider a loop with non-blocking (WNOHANG) waitpid instead. There are examples in waitpid and perlipc
    – zdim
    Nov 8 at 17:59












  • Also, there is no need for defined test in the if-elsif branches since you nicely check right after the fork whether it returned undef.
    – zdim
    Nov 8 at 18:04















up vote
1
down vote

favorite












I have some Perl code that generates a number of child processes. The basic code is as follows:



 my $forked = 0;
my $err = 0;
my $Processes_To_Use_After_Calc=10;
print "Parent ($$) has startedn";
for my $ispawn (1 .. $Processes_To_Use_After_Calc){
my $child_pid = fork();
die "Cannot fork: $!" if !defined $child_pid; # system overload
if(defined $child_pid && $child_pid > 0) {
## Parent
$forked++;
} elsif(defined $child_pid){
#
# Here some calculations are performed
#
print "Child $$ has finished (number $ispawn) n";
}
}
for(1..$forked) {
my $child_pid = wait();
}


All fairly standard stuff. Now, I would like to know if any of the child processes crash (failed to terminate correctly). Clearly if the last statement of each child process is not printed I could assume there was a problem. However I would like another method that would exit the parent program completely and close all child processes that were still open if one of the child processes crashes. Is this possible?










share|improve this question






















  • What are the exit codes of crashing children? wait() returns that exit code, so you can act on that.
    – Corion
    Nov 8 at 11:55










  • wait returns a process id but sets the exit code in $? as a side-effect.
    – mob
    Nov 8 at 14:17










  • "failrly standard stuff" -- note though that the blocking wait waits for one process one at a time. So if something takes longer you won't know about any others before that one's done. (And what if one locks up?) Consider a loop with non-blocking (WNOHANG) waitpid instead. There are examples in waitpid and perlipc
    – zdim
    Nov 8 at 17:59












  • Also, there is no need for defined test in the if-elsif branches since you nicely check right after the fork whether it returned undef.
    – zdim
    Nov 8 at 18:04













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have some Perl code that generates a number of child processes. The basic code is as follows:



 my $forked = 0;
my $err = 0;
my $Processes_To_Use_After_Calc=10;
print "Parent ($$) has startedn";
for my $ispawn (1 .. $Processes_To_Use_After_Calc){
my $child_pid = fork();
die "Cannot fork: $!" if !defined $child_pid; # system overload
if(defined $child_pid && $child_pid > 0) {
## Parent
$forked++;
} elsif(defined $child_pid){
#
# Here some calculations are performed
#
print "Child $$ has finished (number $ispawn) n";
}
}
for(1..$forked) {
my $child_pid = wait();
}


All fairly standard stuff. Now, I would like to know if any of the child processes crash (failed to terminate correctly). Clearly if the last statement of each child process is not printed I could assume there was a problem. However I would like another method that would exit the parent program completely and close all child processes that were still open if one of the child processes crashes. Is this possible?










share|improve this question













I have some Perl code that generates a number of child processes. The basic code is as follows:



 my $forked = 0;
my $err = 0;
my $Processes_To_Use_After_Calc=10;
print "Parent ($$) has startedn";
for my $ispawn (1 .. $Processes_To_Use_After_Calc){
my $child_pid = fork();
die "Cannot fork: $!" if !defined $child_pid; # system overload
if(defined $child_pid && $child_pid > 0) {
## Parent
$forked++;
} elsif(defined $child_pid){
#
# Here some calculations are performed
#
print "Child $$ has finished (number $ispawn) n";
}
}
for(1..$forked) {
my $child_pid = wait();
}


All fairly standard stuff. Now, I would like to know if any of the child processes crash (failed to terminate correctly). Clearly if the last statement of each child process is not printed I could assume there was a problem. However I would like another method that would exit the parent program completely and close all child processes that were still open if one of the child processes crashes. Is this possible?







perl fork






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 8 at 11:12









Chazg76

305




305












  • What are the exit codes of crashing children? wait() returns that exit code, so you can act on that.
    – Corion
    Nov 8 at 11:55










  • wait returns a process id but sets the exit code in $? as a side-effect.
    – mob
    Nov 8 at 14:17










  • "failrly standard stuff" -- note though that the blocking wait waits for one process one at a time. So if something takes longer you won't know about any others before that one's done. (And what if one locks up?) Consider a loop with non-blocking (WNOHANG) waitpid instead. There are examples in waitpid and perlipc
    – zdim
    Nov 8 at 17:59












  • Also, there is no need for defined test in the if-elsif branches since you nicely check right after the fork whether it returned undef.
    – zdim
    Nov 8 at 18:04


















  • What are the exit codes of crashing children? wait() returns that exit code, so you can act on that.
    – Corion
    Nov 8 at 11:55










  • wait returns a process id but sets the exit code in $? as a side-effect.
    – mob
    Nov 8 at 14:17










  • "failrly standard stuff" -- note though that the blocking wait waits for one process one at a time. So if something takes longer you won't know about any others before that one's done. (And what if one locks up?) Consider a loop with non-blocking (WNOHANG) waitpid instead. There are examples in waitpid and perlipc
    – zdim
    Nov 8 at 17:59












  • Also, there is no need for defined test in the if-elsif branches since you nicely check right after the fork whether it returned undef.
    – zdim
    Nov 8 at 18:04
















What are the exit codes of crashing children? wait() returns that exit code, so you can act on that.
– Corion
Nov 8 at 11:55




What are the exit codes of crashing children? wait() returns that exit code, so you can act on that.
– Corion
Nov 8 at 11:55












wait returns a process id but sets the exit code in $? as a side-effect.
– mob
Nov 8 at 14:17




wait returns a process id but sets the exit code in $? as a side-effect.
– mob
Nov 8 at 14:17












"failrly standard stuff" -- note though that the blocking wait waits for one process one at a time. So if something takes longer you won't know about any others before that one's done. (And what if one locks up?) Consider a loop with non-blocking (WNOHANG) waitpid instead. There are examples in waitpid and perlipc
– zdim
Nov 8 at 17:59






"failrly standard stuff" -- note though that the blocking wait waits for one process one at a time. So if something takes longer you won't know about any others before that one's done. (And what if one locks up?) Consider a loop with non-blocking (WNOHANG) waitpid instead. There are examples in waitpid and perlipc
– zdim
Nov 8 at 17:59














Also, there is no need for defined test in the if-elsif branches since you nicely check right after the fork whether it returned undef.
– zdim
Nov 8 at 18:04




Also, there is no need for defined test in the if-elsif branches since you nicely check right after the fork whether it returned undef.
– zdim
Nov 8 at 18:04












2 Answers
2






active

oldest

votes

















up vote
5
down vote



accepted










wait sets $?




Behaves like wait(2) on your system: it waits for a child process to terminate and returns the pid of the deceased process, or -1 if there are no child processes. The status is returned in $? and ${^CHILD_ERROR_NATIVE}.




So,



my $child_pid = wait();

if ( $? == -1 ) { die "wait failed: $!n"; }
elsif ( $? & 0x7F ) { warn "Child $child_pid killed by signal ".( $? & 0x7F )."n"); }
elsif ( $? >> 8 ) { warn "Child $child_pid exited with error ".( $? >> 8 )."n"); }
else { print "Child $child_pid exited successfullyn"; }


If the program truly crashed, you'd get Child killed by signal 11, which is SIGSEGV.



If it threw an uncaught exception, you'd likely get Child exited with error XXX. The exact value will vary by program and could be meaningless. By default, Perl uses $! || ($? >> 8) || 255 for exit value on an uncaught exception.






share|improve this answer























  • Many thanks for all the repsonses...All very useful
    – Chazg76
    Nov 12 at 15:28


















up vote
2
down vote













As per the document for wait:




Behaves like wait(2) on your system: it waits for a child process to
terminate and returns the pid of the deceased process, or "-1" if
there are no child processes. The status is returned in $? and
"${^CHILD_ERROR_NATIVE}". Note that a return value of "-1" could
mean that child processes are being automatically reaped, as
described in perlipc.




If your child was killed by a signal, $? & 0x7F will be true and equal to the number of the signal that killed the child.






share|improve this answer



















  • 1




    The POSIX module has functions for examining the return value to find out why it exited. OP probably needs WIFSIGNALED().
    – Shawn
    Nov 8 at 12:22












  • It's the other way. A normal non-zero exit code will be shifted 8 bits to the right (multiplied by 256) in $?. When $? is greater than 0 but less than 256, it holds the signal number that terminated the child process.
    – mob
    Nov 8 at 14:16










  • @mob, Not quite either. Only the lower 7 bits hold the signal number. The 8th indicates a core dump. Fixed the answer.
    – ikegami
    Nov 8 at 15:07













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53206592%2fperl-fork-how-to-check-if-child-crashed%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
5
down vote



accepted










wait sets $?




Behaves like wait(2) on your system: it waits for a child process to terminate and returns the pid of the deceased process, or -1 if there are no child processes. The status is returned in $? and ${^CHILD_ERROR_NATIVE}.




So,



my $child_pid = wait();

if ( $? == -1 ) { die "wait failed: $!n"; }
elsif ( $? & 0x7F ) { warn "Child $child_pid killed by signal ".( $? & 0x7F )."n"); }
elsif ( $? >> 8 ) { warn "Child $child_pid exited with error ".( $? >> 8 )."n"); }
else { print "Child $child_pid exited successfullyn"; }


If the program truly crashed, you'd get Child killed by signal 11, which is SIGSEGV.



If it threw an uncaught exception, you'd likely get Child exited with error XXX. The exact value will vary by program and could be meaningless. By default, Perl uses $! || ($? >> 8) || 255 for exit value on an uncaught exception.






share|improve this answer























  • Many thanks for all the repsonses...All very useful
    – Chazg76
    Nov 12 at 15:28















up vote
5
down vote



accepted










wait sets $?




Behaves like wait(2) on your system: it waits for a child process to terminate and returns the pid of the deceased process, or -1 if there are no child processes. The status is returned in $? and ${^CHILD_ERROR_NATIVE}.




So,



my $child_pid = wait();

if ( $? == -1 ) { die "wait failed: $!n"; }
elsif ( $? & 0x7F ) { warn "Child $child_pid killed by signal ".( $? & 0x7F )."n"); }
elsif ( $? >> 8 ) { warn "Child $child_pid exited with error ".( $? >> 8 )."n"); }
else { print "Child $child_pid exited successfullyn"; }


If the program truly crashed, you'd get Child killed by signal 11, which is SIGSEGV.



If it threw an uncaught exception, you'd likely get Child exited with error XXX. The exact value will vary by program and could be meaningless. By default, Perl uses $! || ($? >> 8) || 255 for exit value on an uncaught exception.






share|improve this answer























  • Many thanks for all the repsonses...All very useful
    – Chazg76
    Nov 12 at 15:28













up vote
5
down vote



accepted







up vote
5
down vote



accepted






wait sets $?




Behaves like wait(2) on your system: it waits for a child process to terminate and returns the pid of the deceased process, or -1 if there are no child processes. The status is returned in $? and ${^CHILD_ERROR_NATIVE}.




So,



my $child_pid = wait();

if ( $? == -1 ) { die "wait failed: $!n"; }
elsif ( $? & 0x7F ) { warn "Child $child_pid killed by signal ".( $? & 0x7F )."n"); }
elsif ( $? >> 8 ) { warn "Child $child_pid exited with error ".( $? >> 8 )."n"); }
else { print "Child $child_pid exited successfullyn"; }


If the program truly crashed, you'd get Child killed by signal 11, which is SIGSEGV.



If it threw an uncaught exception, you'd likely get Child exited with error XXX. The exact value will vary by program and could be meaningless. By default, Perl uses $! || ($? >> 8) || 255 for exit value on an uncaught exception.






share|improve this answer














wait sets $?




Behaves like wait(2) on your system: it waits for a child process to terminate and returns the pid of the deceased process, or -1 if there are no child processes. The status is returned in $? and ${^CHILD_ERROR_NATIVE}.




So,



my $child_pid = wait();

if ( $? == -1 ) { die "wait failed: $!n"; }
elsif ( $? & 0x7F ) { warn "Child $child_pid killed by signal ".( $? & 0x7F )."n"); }
elsif ( $? >> 8 ) { warn "Child $child_pid exited with error ".( $? >> 8 )."n"); }
else { print "Child $child_pid exited successfullyn"; }


If the program truly crashed, you'd get Child killed by signal 11, which is SIGSEGV.



If it threw an uncaught exception, you'd likely get Child exited with error XXX. The exact value will vary by program and could be meaningless. By default, Perl uses $! || ($? >> 8) || 255 for exit value on an uncaught exception.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 8 at 15:17

























answered Nov 8 at 15:02









ikegami

259k11172392




259k11172392












  • Many thanks for all the repsonses...All very useful
    – Chazg76
    Nov 12 at 15:28


















  • Many thanks for all the repsonses...All very useful
    – Chazg76
    Nov 12 at 15:28
















Many thanks for all the repsonses...All very useful
– Chazg76
Nov 12 at 15:28




Many thanks for all the repsonses...All very useful
– Chazg76
Nov 12 at 15:28












up vote
2
down vote













As per the document for wait:




Behaves like wait(2) on your system: it waits for a child process to
terminate and returns the pid of the deceased process, or "-1" if
there are no child processes. The status is returned in $? and
"${^CHILD_ERROR_NATIVE}". Note that a return value of "-1" could
mean that child processes are being automatically reaped, as
described in perlipc.




If your child was killed by a signal, $? & 0x7F will be true and equal to the number of the signal that killed the child.






share|improve this answer



















  • 1




    The POSIX module has functions for examining the return value to find out why it exited. OP probably needs WIFSIGNALED().
    – Shawn
    Nov 8 at 12:22












  • It's the other way. A normal non-zero exit code will be shifted 8 bits to the right (multiplied by 256) in $?. When $? is greater than 0 but less than 256, it holds the signal number that terminated the child process.
    – mob
    Nov 8 at 14:16










  • @mob, Not quite either. Only the lower 7 bits hold the signal number. The 8th indicates a core dump. Fixed the answer.
    – ikegami
    Nov 8 at 15:07

















up vote
2
down vote













As per the document for wait:




Behaves like wait(2) on your system: it waits for a child process to
terminate and returns the pid of the deceased process, or "-1" if
there are no child processes. The status is returned in $? and
"${^CHILD_ERROR_NATIVE}". Note that a return value of "-1" could
mean that child processes are being automatically reaped, as
described in perlipc.




If your child was killed by a signal, $? & 0x7F will be true and equal to the number of the signal that killed the child.






share|improve this answer



















  • 1




    The POSIX module has functions for examining the return value to find out why it exited. OP probably needs WIFSIGNALED().
    – Shawn
    Nov 8 at 12:22












  • It's the other way. A normal non-zero exit code will be shifted 8 bits to the right (multiplied by 256) in $?. When $? is greater than 0 but less than 256, it holds the signal number that terminated the child process.
    – mob
    Nov 8 at 14:16










  • @mob, Not quite either. Only the lower 7 bits hold the signal number. The 8th indicates a core dump. Fixed the answer.
    – ikegami
    Nov 8 at 15:07















up vote
2
down vote










up vote
2
down vote









As per the document for wait:




Behaves like wait(2) on your system: it waits for a child process to
terminate and returns the pid of the deceased process, or "-1" if
there are no child processes. The status is returned in $? and
"${^CHILD_ERROR_NATIVE}". Note that a return value of "-1" could
mean that child processes are being automatically reaped, as
described in perlipc.




If your child was killed by a signal, $? & 0x7F will be true and equal to the number of the signal that killed the child.






share|improve this answer














As per the document for wait:




Behaves like wait(2) on your system: it waits for a child process to
terminate and returns the pid of the deceased process, or "-1" if
there are no child processes. The status is returned in $? and
"${^CHILD_ERROR_NATIVE}". Note that a return value of "-1" could
mean that child processes are being automatically reaped, as
described in perlipc.




If your child was killed by a signal, $? & 0x7F will be true and equal to the number of the signal that killed the child.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 8 at 15:10









ikegami

259k11172392




259k11172392










answered Nov 8 at 12:04









Chris Turner

6,1091917




6,1091917








  • 1




    The POSIX module has functions for examining the return value to find out why it exited. OP probably needs WIFSIGNALED().
    – Shawn
    Nov 8 at 12:22












  • It's the other way. A normal non-zero exit code will be shifted 8 bits to the right (multiplied by 256) in $?. When $? is greater than 0 but less than 256, it holds the signal number that terminated the child process.
    – mob
    Nov 8 at 14:16










  • @mob, Not quite either. Only the lower 7 bits hold the signal number. The 8th indicates a core dump. Fixed the answer.
    – ikegami
    Nov 8 at 15:07
















  • 1




    The POSIX module has functions for examining the return value to find out why it exited. OP probably needs WIFSIGNALED().
    – Shawn
    Nov 8 at 12:22












  • It's the other way. A normal non-zero exit code will be shifted 8 bits to the right (multiplied by 256) in $?. When $? is greater than 0 but less than 256, it holds the signal number that terminated the child process.
    – mob
    Nov 8 at 14:16










  • @mob, Not quite either. Only the lower 7 bits hold the signal number. The 8th indicates a core dump. Fixed the answer.
    – ikegami
    Nov 8 at 15:07










1




1




The POSIX module has functions for examining the return value to find out why it exited. OP probably needs WIFSIGNALED().
– Shawn
Nov 8 at 12:22






The POSIX module has functions for examining the return value to find out why it exited. OP probably needs WIFSIGNALED().
– Shawn
Nov 8 at 12:22














It's the other way. A normal non-zero exit code will be shifted 8 bits to the right (multiplied by 256) in $?. When $? is greater than 0 but less than 256, it holds the signal number that terminated the child process.
– mob
Nov 8 at 14:16




It's the other way. A normal non-zero exit code will be shifted 8 bits to the right (multiplied by 256) in $?. When $? is greater than 0 but less than 256, it holds the signal number that terminated the child process.
– mob
Nov 8 at 14:16












@mob, Not quite either. Only the lower 7 bits hold the signal number. The 8th indicates a core dump. Fixed the answer.
– ikegami
Nov 8 at 15:07






@mob, Not quite either. Only the lower 7 bits hold the signal number. The 8th indicates a core dump. Fixed the answer.
– ikegami
Nov 8 at 15:07




















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53206592%2fperl-fork-how-to-check-if-child-crashed%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Guess what letter conforming each word

Port of Spain

Run scheduled task as local user group (not BUILTIN)