Meaning of Exit Codes (in general)
ISO/IEC 9899 (Programming Languages: C), ISO/IEC 9945 (IEEE 1003, POSIX)
There is nothing which is specifically defined for Java / JVM. The meaning of these exit codes is defined by ISO/IEC 9899 (Programming Languages: C, for example 7.20.4.3 The exit
function of ISO/IEC 9899:TC3), ISO/IEC 9945 (IEEE 1003, POSIX) and similar specifications, and it's always like this:
- 0 means success
- Any other value means failure
This is used by shell environments (sh
, bash
, cmd.exe
, make
etc. etc.) to determine whether a program exited successfully (0) or there was an error (not 0).
It is strongly recommended to use only 0 for success. Programs which use values other than 0 for success cause headache to the authors of shell scripts, Makefiles and alike.
It's up to the individual program to define additional semantics of different failure values. However, I think -1
is not such a good idea. The best thing would be to use EXIT_SUCCESS
and EXIT_FAILURE
, however, these definitions from <stdlib.h>
have no corresponding counterparts in Java. ISO/IEC 9899:2011 does not describe how EXIT_FAILURE
and EXIT_SUCCESS
should be defined. However, it defines 0 as having the same semantics as EXIT_SUCCESS
, and I do not know of any system which does something else than the following, which therefore is the best thing a Java programmer can assume:
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
So, I'd use 0 for success, 1 for failure, and values distinct from 1 if it is important to differentiate between different types of failure. A good example is the grep
command. From its man page (GNU grep):
EXIT STATUS
The exit status is 0 if selected lines are found, and 1 if not found. If an error occurred the exit status is 2. (Note: POSIX error handling code should check for '2' or greater.)
I'd not use -1 because it sets all bits, and depending on the environment, -1 might actually accidentally generate additonal bogus information, like claiming that signals were raised and alike. Actually, to be portable, the exit code should be within the range [0..127]
, unless you really really really know what you're doing.
For example, on most POSIX systems, the exit code will be truncated to 8 bits, and the semantics of an exit code above 127 is that the exit was caused by a signal.
BSD
BSD has tried to supply a few more exit codes, which are available in /usr/include/sysexits.h
(man page). They are like this:
- 64: command line usage error
- 65: data format error
- 66: cannot open input
- 67: addressee unknown
- 68: host name unknown
- 69: service unavailable
- 70: internal software error
- 71: system error (i.e. can't fork)
- 72: critical OS file missing
- 73: can't create (user) output file
- 74: input/output error
- 75: temp failure; user is invited to retry
- 76: remote error in protocol
- 77: permission denied
- 78: configuration error
In the absence of any other meaningful standard, I think the best thing we can do is use them.
Interpretation of JVM-generated exit values
JVM on POSIX
On UNIX, you can obtain the signal by masking out the lower 7 bits (subtract 128) from the exit value, which in most shells can be queried using $?
.
SIGTERM
-> VM: 143
SIGTERM
SIGSEGV
-> VM: 134
SIGABRT
(because the VM handles SIGSEGV to write the hs_err file and then calls abort()
).
Comparison to "normal" programs:
SIGSEGV
-> prog: 139
SIGSEGV
This behavior is not explicitly specified for the JVM, it is just the normal expected behavior of programs in a POSIX environment. Even the SIGABRT
instead of SIGSEGV
is more or less expected, given that the JVM wants to handle SIGSEGV
on its own, writing a more specific crash dump than a normal core file.
JVM on Windows
TODO