尝试在Windows上的Hotspot JVM中处理SIGBREAK时出现IllegalArgumentException

时间:2016-10-25 16:16:04

标签: java windows signals jvm-hotspot

我试图在sun.misc包中使用信号处理类(如文档here)来处理Windows上的Hotspot JVM中的SIGBREAK,这样我就可以在Ctrl + Break上触发关闭而不仅仅是倾销线程。但是,当我尝试设置处理程序时,我遇到了IllegalArgumentException表示已经由操作系统或VM处理SIGBREAK的情况。即使我运行带有-Xrs标志的JVM也会发生这种情况,该标志可能会禁止处理SIGBREAK信号。

有没有人在Windows上使用sun.misc.Signal处理信号的经验?有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

这似乎是一个令人困惑的话题。

documentation of the java launcher指定:

  

当使用-Xrs选项时,JVM不会安装控制台控制处理程序,这意味着它不会监视或处理CTRL_C_EVENTCTRL_CLOSE_EVENTCTRL_LOGOFF_EVENT ,或CTRL_SHUTDOWN_EVENT

请注意,CTRL_BREAK_EVENT不在列表中。所以它确实不受此选项的影响,但奇怪的是,文档声称指定-Xrs将暗示“ Ctrl + Break线程转储不可用”,此功能完全是不受影响。

此外,其含义完全与读者所期望的相反。当JVM没有监听这些事件时,由于-Xrs选项,它无法将它们转发到Java端处理程序,换句话说,支持信号处理程序是为他们注册。这可以通过尝试为受该选项INT和/或TERM影响的信号安装信号处理程序来轻松测试,仅当-Xrs 不指定。

查看the code that tries to install a signal handler

long oldH = handle0(sig.number, newH);
if (oldH == -1) {
    throw new IllegalArgumentException
        ("Signal already used by VM or OS: " + sig);
}

我们看到所有类型失败的通用答案都是-1,因此我们应该采用异常消息“已经被VM或OS使用过的信号”。在这个地方,没有空间报告不同的原因,例如“无法安装处理程序,因为JVM将不会因-Xrs选项而安装此类处理程序”。

据我所知,-Xrs选项应该允许本机代码为较低级别的信号安装处理程序,而不会使JVM干扰,不会使信号可用用于Java端sun.misc.Signal处理。

关于SIGTERM的问题,整个文档似乎与现实不同步。从我的测试开始,指定-Xrs的最后一个JVM确实使 CTRL + BREAK 线程转储不可用,这是Java 6.但是,如上所述,结果是信号可用于本机代码,导致在没有此类处理程序的情况下中止,而不是使sun.misc.Signal可用。即使在该JVM下,也无法为SignalHandler安装SIGBREAK,无论是否存在-Xrs选项。