今天遇到的一个tomcat启动过程中jvm退出的问题,不是jvm crash的情况,用户日志配置的不正确导致一些信息没有展现出来,只看到pandora执行了shutdownhook
的信息。这可能是启动时的逻辑有触发System.exit
,或被系统或人为kill
掉了。
根据以往的经验,排除了oom killer或ulimit -t
设置不当导致被内核给kill掉的情况,OS级别的signal通常不留机会给jvm执行shutdownhook的。如此一来singal的范围应该就是SIGTERM
, SIGINT
, SIGHUP
这3种(参考这里)。
虽然singal范围缩小,但依然不能确定是因为代码里调用了System.exit
还是人为(或被其他进程)kill
引起的。直接上大招用systemtap需要安装kernal debuginfo
,没有权限的话,还要找到对应的人去做;如果现象较容易重现的话,可以先通过strace
命令进一步缩小问题的范围,究竟是因为jvm内部执行了System.exit
还是外界的kill
引起的。
这里通过启动一个scala的repl来模拟java进程,通过strace
attach到jvm进程上,然后观察,如果是外界的kill
所致,可以看到下面的信息:
$ sudo strace -p 1947
Process 1947 attached - interrupt to quit
futex(0x7fb7635959d0, FUTEX_WAIT, 1948, NULL) = ? ERESTARTSYS (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
futex(0x7fb762762360, FUTEX_WAKE_PRIVATE, 1) = 1
rt_sigreturn(0x7fb762762360) = 202
futex(0x7fb7635959d0, FUTEX_WAIT, 1948, NULLPANIC: attached pid 1947 exited with 143
<unfinished ... exit status 143>
里面的关键信息是SIGTERM
或exit status 143
(即SIGTERM的code)
如果是kill -2
或ctrl-c终止repl,可以看到有关SIGINT
的信息
$ sudo strace -p 1813
Process 1813 attached - interrupt to quit
futex(0x7fb24d15a9d0, FUTEX_WAIT, 1814, NULL) = ? ERESTARTSYS (To be restarted)
--- SIGINT (Interrupt) @ 0 (0) ---
futex(0x7fb24c327360, FUTEX_WAKE_PRIVATE, 1) = 1
rt_sigreturn(0x7fb24c327360) = 202
futex(0x7fb24d15a9d0, FUTEX_WAIT, 1814, NULLPANIC: attached pid 1813 exited with 130
<unfinished ... exit status 130>
如果是jvm自身执行了System.exit
比如:
scala> System.exit(0)
那么在跟踪的信息里,是看不到signal的:
$ sudo strace -p 2131
Process 2131 attached - interrupt to quit
futex(0x7fc14adb49d0, FUTEX_WAIT, 2132, NULLPANIC: attached pid 2131 exited with 0
<unfinished ... exit status 0>
至此我们可以判断出到底是外部还是内部引起的了,如果是内部就不必麻烦Systemtap了,可以从源码去找。