尝试在Windows上的Hotspot JVM中处理SIGBREAK时发生IllegalArgumentException

我正在尝试使用sun.misc包中的信号处理类(如此处所述 )来处理Windows上的Hotspot JVM中的SIGBREAK,以便在Ctrl + Break中触发closures,而不仅仅是转储线程。 但是,我遇到了一个情况,它抛出一个IllegalArgumentExceptionexception,说当我试图设置处理程序时,SIGBREAK已经被操作系统或虚拟机处理。 甚至当我运行带有-Xrs标志的JVM时,也会发生这种情况,这标志着禁止处理SIGBREAK信号。

有没有人有任何经验处理信号在Windows上使用sun.misc.Signal? 有没有解决的办法?

这似乎是一个相当混乱的话题。

java启动程序的文档指定:

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

请注意, CTRL_BREAK_EVENT不在列表中。 所以它确实不受这个选项的影响,但奇怪的是,文档声明指定-Xrs暗示“ Ctrl + Break线程转储不可用 ”,当这个特性完全不受影响的时候。

而且,这个含义完全与读者期望的相反。 当JVM不听这些事件时,由于-Xrs选项,它不能将它们转发到Java端处理程序,换句话说,不支持信号处理程序注册它们。 这可以很容易地通过尝试安装信号处理程序来处理受该选项( INT和/或TERM影响的信号,它仅在指定-Xrs时才起作用。

通过查看试图安装信号处理程序的代码 :

 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的问题,整个文档似乎与现实不同步。 就我的测试而言,最后一个JVM(指定-Xrs确实使CTRL + BREAK线程转储不可用)是Java 6.但是,正如上面所解释的,对于本机代码可以使用信号的结果,没有这样的处理者,而不是让sun.misc.Signal可用。 即使在该JVM下,无论是否存在-Xrs选项,都不可能为SIGBREAK安装SignalHandler