jvm与系统信号(2)

core dump 与 thread stack dump

进程处理信号的行为参考这里,很多信号都将导致core dump,比如SIGILL, SIGSEGV等。

比如我们对一个java进程发送SIGILL会让进程退出,并产生core dump:

$ kill -s ILL `pidof java`

在java进程的错误输出流会产生如下信息,并且在home下产生core dump文件:hs_err_pid8385.log

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGILL (0x4) at pc=0x00007fff89d1ba1a, pid=8385, tid=1287
#
# JRE version: Java(TM) SE Runtime Environment (7.0_60-b15) (build 1.7.0_60-ea-b15)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.60-b09 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [libsystem_kernel.dylib+0x11a1a]  mach_msg_trap+0xa
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/hongjiang/hs_err_pid8385.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#
/data/tools/scala/bin/scala: line 21:  8385 Abort trap: 6           "$@"

对于SIGQUIT(kill -3),jvm会捕获该信号并dump线程栈到标准错误流,不会产生core-dump文件;这个信号的处理方式是系统保留用户无法修改:

scala> import sun.misc._

scala>  Signal.handle(
 |          new Signal("QUIT"),
 |          new SignalHandler(){ 
 |              def handle(sig:Signal){ println("down") }
 |          }
 |      )
java.lang.IllegalArgumentException: Signal already used by VM or OS: SIGQUIT
at sun.misc.Signal.handle(Signal.java:166)
... 38 elided

$ kill -s QUIT `pidof java`

会看到repl输出线程堆栈信息以及heap信息,java进程并不退出。

可被用户设定的singals

对于SIGSEGV(kill -11), SIGFPE(kill -8),SIGILL(kill -4), SIGUSR1(kill -10) 等信号,无法被用户设置:

scala> Signal.handle(new Signal("USR1"), 
 |              new SignalHandler(){ def handle(sig:Signal){ println("down") }}
 |      )

java.lang.IllegalArgumentException: Signal already used by VM or OS: SIGUSR1
    at sun.misc.Signal.handle(Signal.java:166)
    ... 32 elided

对于SIGINT(kill -2),SIGTERM(kill -15),SIGUSR2(kill -12),SIGBUS(kill -7),SIGPIPE(kill -13), 可以被用户设置:

scala> Signal.handle(new Signal("INT"), 
 |              new SignalHandler(){ def handle(sig:Signal){ println("down") }}
 |      )

$ kill -s INT `pidof java`

scala> down // 被捕获,进程不会退出

触发shutdown hook的singals

SIGTERM(kill), SIGINT(kill -2), SIGHUP(kill -1) 会触发shutdown hook的执行。

scala>  Runtime.getRuntime().addShutdownHook(
            new Thread() { override def run() { println("ok") } })

$ kill -s INT `pidof java`

scala> ok 

发表评论

电子邮件地址不会被公开。 必填项已用*标注