java fatal error log

翻譯於《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中的代碼,基本上就可以找到出現問題的位置。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章