Can a Perl system() call ever die?
Asked Answered
H

4

8

Can a system() call can ever die in Perl 5?

(in other words, in order to 100% crash-proof a program that does a system() call, does it need to be wrapped into an eval block, or is that wholly totally unnecessary?)


I haven't found a single mention to that possibility in perldoc system, but didn't quite find the precise "this call never dies" either.

NOTE: the question is about basic CORE Perl here, no autodie or any other custom module that would have similar effect. Also, assume no ALRM signal was set, or any other custom signal handler for that matter.

I'm assuming that all versions of Perl 5.* behave the same, but if not, an answer pertaining to 5.8 would be appreciated.

Hecate answered 5/11, 2012 at 15:10 Comment(3)
I haven't gone and looked at the source, so I'm not posting this as an answer, but I'd be surprised if there was no way for system to run out of memory.Temekatemerity
@Gilles - would "Out of memory" cause Perl to issue a "die" instead of coredump/crash? I would assume the later, but nor certainHecate
@Gilles - if only we had a place where we can ask programming questions.... Let's see what the SO wisdom finds out.Hecate
P
7

Unless my interpretation of the source is incorrect, this looks like a possibility:

Source: Perl 5.16.2 (checked 5.8.8 too), file: pp_sys.c, line: 4224 within the PP(pp_system) code block:

if (n != sizeof(int))
  DIE(aTHX_ "panic: kid popen errno read, n=%u", n);

DIE is Perl_die(pTHX_ const* pat, ...) declared in util.c

According to the documentation, "panic: kid popen errno read" means "forked child returned an incomprehensible message about its errno".

Explanation of panic messages in Perl:

The convention is that when the interpreter dies with an internal error, the message starts "panic: ". Historically, many panic messages had been terse fixed strings, which means that the out-of-range values that triggered the panic are lost. Now we try to report these values, as such panics may not be repeatable, and the original error message may be the only diagnostic we get when we try to find the cause.

Papoose answered 5/11, 2012 at 17:12 Comment(1)
from my reading of the source this will only happen if 1) the exec() performed by the child fails and 2) the child is unable to send 4 (maybe 8) bytes back to the parent via the pipe.Laveralavergne
L
2

You can call system() with the expectation that it will not throw an exception. There is no need to wrap it in an eval block.

Laveralavergne answered 5/11, 2012 at 15:50 Comment(2)
"with the expectation" - is there a technical basis for this? If you look at j.w.r.'s answer, your statement seems totally wrong.Hecate
I would be interested in seeing how many CPAN modules try to catch an exception thrown by system. The point is not that it can't happen but rather that you usually can use system() with the expectation that it won't throw an exception.Laveralavergne
J
1

system returns the exit status of the program. It means, if the program crashes, the calling Perl script continues (see system).

Nevertheless, the program itself can still kill the calling script or even crash the computer. For example, in Linux:

system 'killall', 'perl';
print "Alive\n";
Judicial answered 5/11, 2012 at 15:42 Comment(1)
Please see my comment to Brian Agnew. This is not what I was asking about.Hecate
C
0

I assume that you're talking about the implementation of the system function itself as opposed to whatever is invoked via the call. (Obviously, a child process can't call die in the parent's context, and even that assumes that the call is to Perl code.)

A definitive answer would require knowledge of the internals but given that attempting to invoke a non-existent program doesn't die, I can't imagine that anything else ever would, either:

system('abcd');      # 'abcd' is not recognized... [Win32 message]
say "I'm not dead."; # always prints
Chatelaine answered 5/11, 2012 at 16:5 Comment(1)
"I assume that you're talking about the implementation of the system function itself as opposed to whatever is invoked via the call." - correctHecate

© 2022 - 2024 — McMap. All rights reserved.