【问题标题】:JVM: how are exit codes of the java executable defined?JVM:如何定义 java 可执行文件的退出代码?
【发布时间】:2014-12-22 15:31:57
【问题描述】:

我正在寻找java 可执行文件的可能退出代码的定义:

(如何)我如何判断退出代码是执行的 Java 进程还是 VM 本身的退出代码?

示例:在 Windows 上,java -badoption 返回 1java MainMain 是一个有效的类也可能返回 1

我可以使用任何 VM 选项来使退出代码更有意义吗?例如。区分这两种类型的退出代码?

如果我知道退出代码不是来自我的 Java 进程(仅返回 0),非零退出代码是什么意思?

在 Windows 上,我经常看到 -11。由于这些是通过自动错误报告工具报告的,因此我看不到任何错误消息。我只有退出代码,需要解释它。

退出代码是否依赖于平台?

【问题讨论】:

  • System.exit() 有一个 int 参数。只要您可以访问源代码,就可以定义退出代码,例如 System.exit(1040)
  • @PeterMmm ,我不认为这是他的问题。他询问该函数在VM命令返回时的动作。
  • 这可能会有所帮助 - stackoverflow.com/questions/17671234/…

标签: java jvm


【解决方案1】:

退出代码的含义(一般)

ISO/IEC 9899(编程语言:C)、ISO/IEC 9945(IEEE 1003、POSIX)

没有什么是专门为 Java / JVM 定义的。这些退出代码的含义由 ISO/IEC 9899(编程语言:C,例如 7.20.4.3ISO/IEC 9899:TC3exit 函数)、ISO/IEC 9945(IEEE 1003、POSIX)和类似规范定义,以及总是这样:

  • 0 表示成功
  • 任何其他值都意味着失败

shell 环境(shbashcmd.exemake 等)使用它来确定程序是成功退出(0)还是出现错误(不是 0)。

强烈建议只使用 0 表示成功。使用 0 以外的值表示成功的程序会令 shell 脚本、Makefile 等的作者头疼。

由各个程序定义不同失败值的附加语义。但是,我认为-1 并不是一个好主意。最好的办法是使用EXIT_SUCCESSEXIT_FAILURE,但是,<stdlib.h> 中的这些定义在 Java 中没有对应的对应项。 ISO/IEC 9899:2011 没有描述应如何定义 EXIT_FAILUREEXIT_SUCCESS。但是,它将 0 定义为与 EXIT_SUCCESS 具有相同的语义,并且我不知道任何系统会执行以下操作,因此这是 Java 程序员可以假设的最好的事情:

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

因此,如果区分不同类型的失败很重要,我会使用 0 表示成功,使用 1 表示失败,并使用不同于 1 的值。一个很好的例子是grep 命令。从它的手册页(GNU grep):

退出状态 如果找到选定的行,则退出状态为 0,如果未找到,则退出状态为 1。如果发生错误,则退出状态为 2。(注意:POSIX 错误处理代码应检查“2”或更大。)

我不会使用 -1,因为它会设置所有位,并且根据环境的不同,-1 实际上可能会意外生成附加的虚假信息,例如声称发出了信号等。实际上,为了便于移植,退出代码应该在[0..127] 范围内,除非你真的很清楚自己在做什么。 例如,在大多数 POSIX 系统上,退出代码会被截断为 8 位,而 127 以上的退出代码的语义是退出是由信号引起的。

BSD

BSD 已尝试提供更多退出代码,可在/usr/include/sysexits.h (man page) 中找到。他们是这样的:

  • 64:命令行使用错误
  • 65:数据格式错误
  • 66:无法打开输入
  • 67:收件人未知
  • 68:主机名未知
  • 69:服务不可用
  • 70:内部软件错误
  • 71:系统错误(即无法分叉)
  • 72:关键操作系统文件丢失
  • 73:无法创建(用户)输出文件
  • 74:输入/输出错误
  • 75:临时故障;邀请用户重试
  • 76:协议远程错误
  • 77:权限被拒绝
  • 78:配置错误

在没有任何其他有意义的标准的情况下,我认为我们能做的最好的事情就是使用它们。

解释 JVM 生成的退出值

POSIX 上的 JVM

在 UNIX 上,您可以通过从退出值中屏蔽低 7 位(减去 128)来获取信号,在大多数 shell 中可以使用 $? 进行查询。

  • SIGTERM -> 虚拟机:143 SIGTERM
  • SIGSEGV -> VM:134 SIGABRT(因为VM处理SIGSEGV写入hs_err文件,然后调用abort())。

与“正常”程序的比较:

  • SIGSEGV -> 编:139 SIGSEGV

JVM 没有明确指定此行为,它只是 POSIX 环境中程序的正常预期行为。即使是 SIGABRT 而不是 SIGSEGV 也或多或少是意料之中的,因为 JVM 希望自己处理 SIGSEGV,编写比普通核心文件更具体的故障转储。

Windows 上的 JVM

待办事项

【讨论】:

  • 谢谢,虽然这听起来很笼统;正如@maerics 指出的那样,退出代码(stackoverflow.com/questions/17671234)有一些意义,我想知道是否还有更多相关信息。正如我所指出的,我在 Windows 上看到了 -11,我认为这不是随机的;即在特定条件下 JVM 以 -1 退出,而在其他条件下 JVM 以 1 退出。我的问题正是关于这些条件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多