欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

jvm crash的崩潰日志詳細(xì)分析及注意點(diǎn)

 更新時(shí)間:2017年04月02日 18:44:45   作者:raintungli  
本篇文章主要介紹了jvm crash的崩潰日志詳細(xì)分析及注意點(diǎn)。具有很好的參考價(jià)值,下面跟著小編一起來看下吧

生成

1. 生成error 文件的路徑:你可以通過參數(shù)設(shè)置-XX:ErrorFile=/path/hs_error%p.log, 默認(rèn)是在Java運(yùn)行的當(dāng)前目錄 [default: ./hs_err_pid%p.log]

2. 參數(shù)-XX:OnError  可以在crash退出的時(shí)候執(zhí)行命令,格式是-XX:OnError=“string”,  <string> 可以是命令的集合,用分號做分隔符, 可以用"%p"來取到當(dāng)前進(jìn)程的ID.

例如:

// -XX:OnError="pmap %p"  // show memory map
// -XX:OnError="gcore %p; dbx - %p" // dump core and launch debugger

在Linux中系統(tǒng)會fork出一個(gè)子進(jìn)程去執(zhí)行shell的命令,因?yàn)槭怯胒ork可能會內(nèi)存不夠的情況,注意修改你的 /proc/sys/vm/overcommit_memory 參數(shù),不清楚為什么這里不使用vfork

3. -XX:+ShowMessageBoxOnError 參數(shù),當(dāng)jvm crash的時(shí)候在linux里會啟動gdb 去分析和調(diào)式,適合在測試環(huán)境中使用。

什么情況下不會生成error文件

linux 內(nèi)核在發(fā)生OOM的時(shí)候會強(qiáng)制kill一些進(jìn)程, 可以在/var/logs/messages中查找

Error crash 文件的幾個(gè)重要部分

a.  錯誤信息概要

# A fatal error has been detected by the Java Runtime Environment: 
# 
# SIGSEGV (0xb) at pc=0x0000000000043566, pid=32046, tid=1121192256 
# 
# JRE version: 6.0_17-b04 
# Java VM: Java HotSpot(TM) 64-Bit Server VM (14.3-b01 mixed mode linux-amd64 ) 
# Problematic frame: 
# C 0x0000000000043566 
# 
# If you would like to submit a bug report, please visit: 
# http://java.sun.com/webapps/bugreport/crash.jsp 
# The crash happened outside the Java Virtual Machine in native code. 
# See problematic frame for where to report the bug. 

SIGSEGV 錯誤的信號類型

pc 就是IP/PC寄存器值也就是執(zhí)行指令的代碼地址

pid 就是進(jìn)程id

# Problematic frame:
# V  [libjvm.so+0x593045]

就是導(dǎo)致問題的動態(tài)鏈接庫函數(shù)的地址

pc 和 +0x593045 指的是同一個(gè)地址,只是一個(gè)是動態(tài)的偏移地址,一個(gè)是運(yùn)行的虛擬地址

b.信號信息

Java中在linux 中注冊的信號處理函數(shù),中間有2個(gè)參數(shù)info, ucvoid

static void crash_handler(int sig, siginfo_t* info, void* ucVoid) { 
 // unmask current signal 
 sigset_t newset; 
 sigemptyset(&newset); 
 sigaddset(&newset, sig); 
 sigprocmask(SIG_UNBLOCK, &newset, NULL); 
 
 VMError err(NULL, sig, NULL, info, ucVoid); 
 err.report_and_die(); 
} 

在crash report中的信號錯誤提示

siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x0000000000043566 

信號的詳細(xì)信息和si_addr 出錯誤的內(nèi)存,都保存在siginfo_t的結(jié)構(gòu)體中,也就是信號注冊函數(shù)crash_handler里的參數(shù)info,內(nèi)核會保存導(dǎo)致錯誤的內(nèi)存地址在用戶空間的信號結(jié)構(gòu)體中siginfo_t,這樣在進(jìn)程在注冊的信號處理函數(shù)中可以取得導(dǎo)致錯誤的地址。

c.寄存器信息

Registers: 
RAX=0x00002aacb5ae5de2, RBX=0x00002aaaaf46aa48, RCX=0x0000000000000219, RDX=0x00002aaaaf46b920 
RSP=0x0000000042d3f968, RBP=0x0000000042d3f9c8, RSI=0x0000000042d3f9e8, RDI=0x0000000045aef9b8 
R8 =0x0000000000000f80, R9 =0x00002aaab3d30ce8, R10=0x00002aaaab138ea1, R11=0x00002b017ae65110 
R12=0x0000000042d3f6f0, R13=0x00002aaaaf46aa48, R14=0x0000000042d3f9e8, R15=0x0000000045aef800 
RIP=0x0000000000043566, EFL=0x0000000000010202, CSGSFS=0x0000000000000033, ERR=0x0000000000000014 
 TRAPNO=0x000000000000000e 

寄存器的信息就保存在b部分的信號處理函數(shù)參數(shù) (ucontext_t*)usVoid中

在X86架構(gòu)下:

void os::print_context(outputStream *st, void *context) { 
 if (context == NULL) return; 
 
 ucontext_t *uc = (ucontext_t*)context; 
 st->print_cr("Registers:"); 
#ifdef AMD64 
 st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); 
 st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); 
 st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]); 
 st->print(", RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]); 
 st->cr(); 
 st->print( "RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]); 
 st->print(", RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]); 
 st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]); 
 st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]); 
 st->cr(); 
 st->print( "R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]); 
 st->print(", R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]); 
 st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]); 
 st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]); 
 st->cr(); 
 st->print( "R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]); 
 st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]); 
 st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]); 
 st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]); 
 st->cr(); 
 st->print( "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]); 
 st->print(", EFL=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]); 
 st->print(", CSGSFS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_CSGSFS]); 
 st->print(", ERR=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ERR]); 
 st->cr(); 
 st->print(" TRAPNO=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_TRAPNO]); 
#else 
 st->print( "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]); 
 st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]); 
 st->print(", ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ECX]); 
 st->print(", EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDX]); 
 st->cr(); 
 st->print( "ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_UESP]); 
 st->print(", EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBP]); 
 st->print(", ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESI]); 
 st->print(", EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDI]); 
 st->cr(); 
 st->print( "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EIP]); 
 st->print(", CR2=" INTPTR_FORMAT, uc->uc_mcontext.cr2); 
 st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]); 
#endif // AMD64 
 st->cr(); 
 st->cr(); 
 
 intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc); 
 st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); 
 print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t)); 
 st->cr(); 
 
 // Note: it may be unsafe to inspect memory near pc. For example, pc may 
 // point to garbage if entry point in an nmethod is corrupted. Leave 
 // this at the end, and hope for the best. 
 address pc = os::Linux::ucontext_get_pc(uc); 
 st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); 
 print_hex_dump(st, pc - 16, pc + 16, sizeof(char)); 
} 

寄存器的信息在分析出錯的時(shí)候是非常重要的

打印出執(zhí)行附近的部分機(jī)器碼

Instructions: (pc=0x00007f48f14ef51a) 
0x00007f48f14ef4fa: 90 90 55 48 89 e5 48 81 ec 98 9f 00 00 48 89 bd 
0x00007f48f14ef50a: f8 5f ff ff 48 89 b5 f0 5f ff ff b8 00 00 00 00 
0x00007f48f14ef51a: c7 00 01 00 00 00 c6 85 00 60 ff ff ff c9 c3 90 
0x00007f48f14ef52a: 90 90 90 90 90 90 55 48 89 e5 53 48 8d 1d 94 00 

在instruction 部分中會打印出部分的機(jī)器碼
格式是

地址:機(jī)器碼 

第一種使用udis庫里帶的udcli工具來反匯編

命令:

echo '90 90 55 48 89 e5 48 81 ec 98 9f 00 00 48 89 bd' | udcli -intel -x -64 -o 0x00007f48f14ef4fa 

顯示出對應(yīng)的匯編

第二種可以用

objectdump -d -C libjvm.so >> jvmsodisass.dump  

查找偏移地址  0x593045, 就是當(dāng)時(shí)的執(zhí)行的匯編,然后結(jié)合上下文,源碼推測出問題的語句。

d.寄存器對應(yīng)的內(nèi)存的值

RAX=0x0000000000000000 is an unknown value 
RBX=0x000000041a07d1e8 is an oop 
{method} 
 - klass: {other class} 
RCX=0x0000000000000000 is an unknown value 
RDX=0x0000000040111800 is a thread 
RSP=0x0000000041261b88 is pointing into the stack for thread: 0x0000000040111800 
RBP=0x000000004126bb20 is pointing into the stack for thread: 0x0000000040111800 
RSI=0x000000004126bb80 is pointing into the stack for thread: 0x0000000040111800 
RDI=0x00000000401119d0 is an unknown value 
R8 =0x0000000040111c40 is an unknown value 
R9 =0x00007f48fcc8b550: <offset 0xa85550> in /usr/java/jdk1.6.0_30/jre/lib/amd64/server/libjvm.so at 0x00007f48fc206000 
R10=0x00007f48f8ca7d41 is an Interpreter codelet 
method entry point (kind = native) [0x00007f48f8ca7ae0, 0x00007f48f8ca8320] 2112 bytes 
R11=0x00007f48fc98f270: <offset 0x789270> in /usr/java/jdk1.6.0_30/jre/lib/amd64/server/libjvm.so at 0x00007f48fc206000 
R12=0x0000000000000000 is an unknown value 
R13=0x000000041a07d1e8 is an oop 
{method} 
 - klass: {other class} 
R14=0x000000004126bb88 is pointing into the stack for thread: 0x0000000040111800 
R15=0x0000000040111800 is a thread 

jvm 會通過寄存器的值對找對應(yīng)的對象,也是一個(gè)比較好的參考

e. 其他的信息

error 里面還有一些線程信息,還有當(dāng)時(shí)內(nèi)存映像信息,這些都可以作為分析的部分參考

crash 報(bào)告可以大概的反應(yīng)出一個(gè)當(dāng)時(shí)的情況,特別是在沒有core dump的時(shí)候,是比較有助于幫助分析的,但如果有core dump的話,最終還是core dump能快速準(zhǔn)確的發(fā)現(xiàn)問題原因。

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

  • java使用Abobe Acrobat DC生成模板

    java使用Abobe Acrobat DC生成模板

    這篇文章主要介紹了java使用Abobe Acrobat DC生成模板,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • java中計(jì)算集合的交差并集示例代碼

    java中計(jì)算集合的交差并集示例代碼

    今天突然想Java如何計(jì)算集合的交差并集,主要是看Python語言的時(shí)候想起來的。下面這篇文章主要給大家介紹了關(guān)于java中計(jì)算集合的交差并集的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08
  • SpringAop實(shí)現(xiàn)操作日志記錄

    SpringAop實(shí)現(xiàn)操作日志記錄

    這篇文章主要介紹了SpringAop實(shí)現(xiàn)操作日志記錄的方法,幫助大家更好的理解和使用SpringAop,感興趣的朋友可以了解下
    2020-12-12
  • mybatis如何在一個(gè)update標(biāo)簽中寫多條update語句

    mybatis如何在一個(gè)update標(biāo)簽中寫多條update語句

    這篇文章主要介紹了mybatis如何在一個(gè)update標(biāo)簽中寫多條update語句問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • java基本教程之join方法詳解 java多線程教程

    java基本教程之join方法詳解 java多線程教程

    本文對java Thread中join()方法進(jìn)行介紹,join()的作用是讓“主線程”等待“子線程”結(jié)束之后才能繼續(xù)運(yùn)行,大家參考使用吧
    2014-01-01
  • 詳解Java 自動裝箱與自動拆箱

    詳解Java 自動裝箱與自動拆箱

    這篇文章主要介紹了Java 自動裝箱與自動拆箱的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-09-09
  • 詳解Java如何實(shí)現(xiàn)在PDF中插入,替換或刪除圖像

    詳解Java如何實(shí)現(xiàn)在PDF中插入,替換或刪除圖像

    圖文并茂的內(nèi)容往往讓人看起來更加舒服,如果只是文字內(nèi)容的累加,往往會使讀者產(chǎn)生視覺疲勞。搭配精美的文章配圖則會使文章內(nèi)容更加豐富。那我們要如何在PDF中插入、替換或刪除圖像呢?別擔(dān)心,今天為大家介紹一種高效便捷的方法
    2023-01-01
  • java可變參數(shù)使用示例

    java可變參數(shù)使用示例

    這篇文章主要介紹了java可變參數(shù)使用示例,需要的朋友可以參考下
    2014-04-04
  • Java實(shí)現(xiàn)手寫線程池實(shí)例并測試詳解

    Java實(shí)現(xiàn)手寫線程池實(shí)例并測試詳解

    這篇文章主要來模擬一下線程池和工作隊(duì)列的流程,以及編寫代碼和測試類進(jìn)行測試。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-02-02
  • Java線程中賣火車票問題的深入講解

    Java線程中賣火車票問題的深入講解

    這篇文章主要給大家介紹了關(guān)于Java線程中賣火車票問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評論