前言
问题来自于文章 shell脚本 后台启动 程序1 + “tail -f log“, ctrl +c 导致程序1中断 中的测试用例 Test07Signal2ParentProcess, 可以看到 我当时标记了一个 "todo, not work in hostpostVM9"
然后 问题是这样的, 我同一台机器, 然后 jdk8 带上 SIGINFO 去执行 Test07Signal2ParentProcess 没有问题, 但是 jdk9 带上 SIGINFO 去执行 Test07Signal2ParentProcess 报错如下
然后 jdk9 执行报错如下
Exception in thread "main" java.lang.IllegalArgumentException: Unknown signal: INFO
at java.base/jdk.internal.misc.Signal.<init>(Signal.java:148)
at jdk.unsupported/sun.misc.Signal.<init>(Signal.java:139)
at com.hx.test13.Test07Signal2ParentProcess.main(Test07Signal2ParentProcess.java:50)
这个就很奇怪了,信号支持哪些 不是和操作系统有关系嘛? 为什么 和 jdk 也有关系
我们这里会大致剖析一些东西, 在 mac 上面造成上面这个问题的原因
kill -l 所支持的信号列表是怎么来的?
操作系统支持 的信号列表?
jdk8/jdk9 对于 Signal.findSignal 的处理
首先看一下 jdk9, jdk9 这里几种类unix操作系统是走的统一处理
是从 g_signal_info 中遍历匹配给定的信号名称, 如果找不到 返回 -1, 否则返回对应的 索引
g_signal_info 是取自于这里, 根据 signal.h 中是否支持给定的信号, 创建的信号映射数组
mac 上面是支持 SIGINFO 信号, 但是 g_signal_info 中没有 SIGINFO 的处理, 因此 最终 jdk9 中不支持 SIGINFO
最终没有找到 SIGINFO 的信号, 然后 外层 jdk 抛出异常
最终由 Signal 的构造方法抛出 "Unknown signal: INFO" 的异常
再来看一下 jdk8, jdk8 这里不同的操作系统是走的不同的处理
signaltable 是根据操作系统, 配置死的
jdk8 支持的 信号列表
HUP
INT
QUIT
ILL
TRAP
ABRT
EMT
FPE
KILL
BUS
SEGV
SYS
PIPE
ALRM
TERM
URG
STOP
TSTP
CONT
CHLD
TTIN
TTOU
IO
XCPU
XFSZ
VTALRM
PROF
WINCH
INFO
USR1
USR2
jdk9 支持的信号列表
ABRT
ALRM
BUS
CHLD
CONT
EMT
FPE
HUP
ILL
INT
IO
KILL
PIPE
PROF
QUIT
SEGV
STOP
SYS
TERM
TRAP
TSTP
TTIN
TTOU
URG
USR1
USR2
VTALRM
WINCH
XCPU
XFSZ
mac 支持的信号列表
HUP
INT
QUIT
ILL
TRAP
ABRT
POLL
IOT
EMT
FPE
KILL
BUS
SEGV
SYS
PIPE
ALRM
TERM
URG
STOP
TSTP
CONT
CHLD
TTIN
TTOU
IO
XCPU
XFSZ
VTALRM
PROF
WINCH
INFO
USR1
USR2
参照对比一下 jdk8 比 jdk9 多支持一个 SIGINFO
mac本身 比 jdk8 多支持 POLL, IOT
所以在 jdk8 中支持的 信号是由 jvm 决定的, 在 jdk9 中支持的信号是由 jvm + 操作系统来决定的
kill -l 所支持的信号列表是怎么来的?
查看一下 coreutils 的 kill 的代码
将 名称 转换为索引
名称列表来自于 kill 程序, 信号是否支持 来自于 操作系统的 signal.h
signal.h
所以 kill 中支持的信号是由 kill + 操作系统来决定的
操作系统支持 的信号列表?
mac 支持如下信号列表
大部分的 x86 的其他 linux 支持如下的信号列表
完