翻譯於《Troubleshooting Guide for JavaSE6 with HotSpotVM》
1. 生成位置
-XX:ErrorFile=/fullpath/file,file裏可以包含%p表示進程id。如果沒聲明,默認的名字是hs_err_pid.log,保存在進程的工作目錄。如果因爲權限和空間等問題不能存在工作目錄,會保存在系統的臨時目錄
2. 包含信息
導致fatal error的操作異常或signal
版本和配置信息
導致fatal error的線程和堆棧
正在執行的線程及其狀態
堆的summary
加載的native library
命令行參數
環境變量
操作系統和CPU細節
3. Header
SIGSEGV (0xb) at pc=0x417789d7, pid=21139, tid=1024
| | | | +--- thread id
| | | +------------- process id
| | +--------------------------- program counter
| | (instruction pointer)
| +--------------------------------------- signal number
+---------------------------------------------- signal name
還有可能是internal error等
“EXCEPTION_STACK_OVERFLOW”意味着這是個棧溢出的錯誤。
“EXCEPTION_ACCESS_VIOLATION ”意味着Java應用Crash的時候,正在運行JVM自己的代碼,而不是外部的Java代碼或其他類庫代碼。
導致error的frame
# Problematic frame:
# C [libNativeSEGV.so+0x9d7]
Frame Type Description
C Native C frame
j Interpreted Java frame
V VM frame
v VM generated stub frame
J Other frame types, including compiled Java frame
4. 線程信息
Current thread (0x0805ac88): JavaThread "main " [_thread_in_native, id=21139]
| | | | +-- ID
| | | +------------- state
| | +-------------------------- name
| +------------------------------------ type
+-------------------------------------------------- pointer
線程類型可能有:
JavaThread
VMThread
CompilerThread
GCTaskThread
WatcherThread
ConcurrentMarkSweepThread
線程狀態
Thread State Description
_thread_uninitialized Thread is not created. This occurs only in the case of memorycorruption.
_thread_new Thread has been created but it has not yet started.
_thread_in_native Thread is running native code. The error is probably a bug in nativecode.
_thread_in_vm Thread is running VM code.
_thread_in_Java Thread is running either interpreted or compiled Java code.
_thread_blocked Thread is blocked.
siginfo:
在Solaris OS和Linux signal number ( si_signo ) 和 signal code (si_code)用於標示錯誤信息:
siginfo:si_signo=11, si_errno=0, si_code=1, si_addr=0x00004321
寄存器信息
機器指令
線程堆棧
可能有native和java兩種
兩個例子:
內存回收引起的Crash內存回收引起的Crash有以下的特點:在日誌文件頭一般有“ EXCEPTION_ACCESS _VIOLATION”和“# Problematic frame: # V [jvm.dll+....”的信息
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [jvm.dll+0x15e87e]
VM_Operation (0x063efbac): full generation collection, mode: safepoint, requested by thread 0x040f83f8
可以看到JVM正在做 “full generation collection”。另外還有可能看到,其他的回收行爲:
generation collection for allocation
full generation collection
parallel gc failed allocation
parallel gc failed permanent allocation
parallel gc system gc
棧溢出引起的Crash
Java代碼引起的棧溢出,通常不會引起JVM的Crash,而是拋出一個Java異常:java.lang.StackOverflowError。
但是在Java虛擬機中,Java的代碼和本地C或C++代碼公用相同的Stack。這樣,在執行本地代碼所造成的棧溢出,
就有可能引起JVM的Crash了。
棧溢出引起的Crash會在日誌的文件頭中看到“EXCEPTION_STACK_OVERFLOW”字樣。另外,在當前線程的Stack
信息中也能發現一些信息。例如下面的例子:
-----------------------------------------------------------------------------------
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x10001011, pid=296, tid=2940
#
# Java VM: Java HotSpot(TM) Client VM (1.6-internal mixed mode, sharing)
# Problematic frame:
#
C [App.dll+0x1011]
#
--------------- T H R E A D ---------------
Current thread (0x000367c0): JavaThread "main" [_thread_in_native, id=2940]
:
Stack: [0x00040000,0x00080000), sp=0x00041000, free space=4k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [App.dll+0x1011]
C [App.dll+0x1020]
C [App.dll+0x1020]
:
C [App.dll+0x1020]
C [App.dll+0x1020]
...<more frames>...
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j Test.foo()V+0
j Test.main([Ljava/lang/String;)V+0
v ~StubRoutines::call_stub
--------------------------------------------------------------------------------
在上面的信息中,可以發現這是個棧溢出的錯誤。並且當前棧剩餘的空間已經很小了(free space =4k)。
因此建議將JVM的Stack的尺寸調大,主要設計兩個參數:“-Xss” 和“-XX:StackShadowPages=n”。
但是,將棧的尺寸調大,也意味着在有限的內存資源中,能打開的最大線程數會減少。
5. 進程信息:線程列表和內存使用情況
VMState:虛擬機狀態
General VM State Description
not at a safepoint Normal execution.
at safepoint All threads are blocked in the VM waiting for a special VM operation tocomplete.
synchronizing A special VM operation is required and the VM is waiting for all threads in the VM to block.
堆信息:
虛擬機參數和環境變量
6. 系統信息
操作系統、cpu、內存配置
比較牛逼的錯誤定位:
1. 查看hs_err_pidXXXX.log中的ESP,EBP等信息,以及Top of Stack的信息確定調用堆棧,找到入口地址
2. 查看hs_err_pidXXXX.log中的dll加載信息,確定dll的加載地址,使用入口地址-加載地址可得到函數的偏移
3. 使用objdump或者反彙編工具,用dll的基址+偏移定位dll中的代碼,基本上就可以找到出現問題的位置。