1.core dump介紹
程式異常退出(crash)時會自動產生一個core檔案,包含了程式運行時的記憶體,寄存器狀態,堆棧指標,記憶體管理等資訊,也就是把程式當時工作的狀態儲存成一個檔案。不僅僅是在出錯的時候會產生core dump檔案,在系統卡住或者cpu使用率很高的時候也可以手動觸發產生core dump檔案(當然這種情況也可以直接通過jmap和jstack dump出記憶體和線程堆棧,但JDK1.6以前,這2個命令經常執行不成功),這樣就可以很好的分析了。
2.產生core dump檔案
core dump檔案產生開關其實是通過對產生的檔案大小進行控制達到的,預設大小是0,也就是說預設是不產生core dump檔案的,可以通過命令ulimit -c進行查看。將此參數修改成unlimited就可以產生core dump檔案了,但值得注意的一點是,每個應用進程都會讀取自己的一套系統參數,可以查看進程對應的記憶體檔案/proc/<pid>/limits中的資訊來判斷修改後的參數值是否對此應用進程生效了,limits檔案中的資訊如下:
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 10485760 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 20480 20480 processes
Max open files 204800 204800 files
Max locked memory 32768 32768 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 1024 1024 signals
Max msgqueue size 819200 819200 bytes
上述資訊中的對應的參數值為unlimited,代表此應用進程的core dump開關是開著的。ulimit -c unlimited這個命令可以在很多地方修改,比如用root在命令列執行,在/etc/profile中增加(/etc/profile檔案中已經有defaultulimit -S -c 0 > /dev/null 2>&1,可以直接修改0為unlimited),在使用者的.bash_profile中增加..這些方式執行後的影響範圍還是挺複雜的,到現在也沒弄清楚。當時通過root使用者命令列修改後,在shell裡查詢ulimit -c是生效了,以為應用程式也生效了,覺得不用應用都不需要重啟就生效了挺好,等到下一次crash的時候發現還是沒有產生core dump檔案,於是到檔案/proc/<pid>/limits中檢查此參數值才發現應用程式所讀取的值還是0。後來採用一種比較簡單直接的方式,用root使用者修改/etc/profile檔案中的ulimit -c的值,然後重新登入,重啟應用,再檢查/proc/<pid>/limits中的值,確保參數已經生效,後來應用再crash時core dump檔案也如期而至,心裡暗爽,終於可以開始分析堆棧了。
core dump檔案產生的預設路徑在使用者的工作目錄(啟動指令碼目錄),可以通過設定參數/proc/sys/kernel/core_pattern的值改變core dump檔案的最終產生路徑及檔案名稱格式。core dump檔案成功後,在jboss控制台錯誤記錄檔中的日誌也多了core dumped關鍵字,如下:
/opt/.../jboss/bin/run.sh: line 181: 9176 段錯誤 (core dumped) "$JAVA" $JAVA_OPTS -Djava.endorsed.dirs="$JBOSS_ENDORSED_DIRS" -classpath "$JBOSS_CLASSPATH" org.jboss.Main "$@"
3.core dump分析
參考:http://blog.csdn.net/cpzhong/article/details/7191811