redis的**質量一直被業內人士稱讚,在極高的業務壓力下也能有很好的穩定性。但是極端情況下,redis也是有可能會crash的。有時候因為種種原因,系統配置問題,磁碟空間寫滿了,程序許可權不夠等等,我們可能不會運氣那麼好,有乙個core
檔案可以拿去除錯。這個時候,redis提供了幾種異常崩潰情況下的crash report
,很多時候我們基於crash report,再加上一定的分析就可以直接定位問題了。
在異常崩潰時,redis會通過設定的signal handler
來生成crash report,目前redis為生成crash report捕獲的異常訊號主要有以下幾種:
這4種訊號應該能包含大部分程式異常崩潰情況了,最常見的就是sigse**段錯誤了,除0異常sigfpe有時候也會遇到。
當redis收到上面4種訊號之一時,會在設定的sigse**handler()
函式中生成crash report,如下,
=== redis bug report start: cut & paste starting from here ===
[19179] 12 apr 18:47:42.599 # redis 2.8.19 crashed by signal: 11
[19179] 12 apr 18:47:42.599 # failed assertion: (:0)
[19179] 12 apr 18:47:42.599 # --- stack trace
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(logstacktrace+0x4a)[0x7f5be2d6895a]
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(debugcommand+0x1b0)[0x7f5be2d69ad0]
/lib64/libpthread.so.0(+0xf500)[0x7f5be3c1a500]
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(debugcommand+0x1b0)[0x7f5be2d69ad0]
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(call+0x8a)[0x7f5be2d2f12a]
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(processcommand+0x5dd)[0x7f5be2d3017d]
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(processinputbuffer+0x4d)[0x7f5be2d3b86d]
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(readqueryfromclient+0xf0)[0x7f5be2d3cb70]
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(aeprocessevents+0x13d)[0x7f5be2d2804d]
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(aemain+0x2b)[0x7f5be2d2833b]
/home/dejun.xdj/kvs-kernel/src/libredis-server.so(runredis+0x4f)[0x7f5be2d31eaf]
/home/dejun.xdj/kvs-kernel/src/redis-server /home/dejun.xdj/local/redis/conf/redis_7071.conf *:1071(main+0x180)[0x405db0]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x3d4ac1ecdd]
/home/dejun.xdj/kvs-kernel/src/redis-server /home/dejun.xdj/local/redis/conf/redis_7071.conf *:1071[0x4055e9]
[19179] 12 apr 18:47:42.599 # --- info output
......
[19179] 12 apr 18:47:42.599 # --- client list output
[19179] 12 apr 18:47:42.599 # id=2 addr=127.0.0.1:30494 fd=5 name= age=0 idle=0 flags=n db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=debug read=0 write=0 type=admin next_opid=-1
[19179] 12 apr 18:47:42.599 # --- current client info
[19179] 12 apr 18:47:42.599 # client: id=2 addr=127.0.0.1:30494 fd=5 name= age=0 idle=0 flags=n db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=debug read=0 write=0 type=admin next_opid=-1
[19179] 12 apr 18:47:42.600 # ar**[0]: 'debug'
[19179] 12 apr 18:47:42.600 # ar**[1]: 'segfault'
[19179] 12 apr 18:47:42.600 # --- registers
......
=== redis bug report end. make sure to include from start to end. ===
please report the crash by opening an issue on github:
suspect ram error? use redis-server --test-memory to verify it.
crash report主要包括4部分,
其中對於除錯最有幫助的就是stack trace
資訊了,我們直接以上面的crash report來說明一下如何除錯。
redis提供了debug segfault
命令用於除錯,我們直接給redis傳送這個命令,就可以在日誌中生成類似於上面的崩潰報告(請不要在生產環境使用這個命令!!!)。
實際除錯之前先說明一下,如果編譯時沒有加上-g
選項,可執行檔案中沒有除錯符號資訊,是無法進行後面的除錯的,考慮到效能的影響很小,redis預設編譯是帶有-g選項的。
上面的stack trace資訊直接告訴我們了,出core的點在libredis-server.so
中,簡單分析可以知道是在執行debugcommand
時出現段錯誤,函式後面的+
號帶的位址是函式內的**偏移,我們只要知道函式的起始位址就可以獲取出core的函式內**位址了,進而可以通過addr2line
獲取位址對應的具體的源檔名和行號。
通過nm工具獲取函式起始位址,
$nm -l /home/dejun.xdj/kvs-kernel/src/libredis-server.so | grep debugcommand
000000000006d920 t debugcommand /home/dejun.xdj/kvs-kernel/src/debug.c:255
000000000007f3f0 t pfdebugcommand /home/dejun.xdj/kvs-kernel/src/hyperloglog.c:1455
我們可以看到debugcommand的起始位址是0x6d920
(十六進製制),加上偏移0x1b0
,可以知道出core的具體位址是0x6dad0
,那麼我們就可以很方便的獲取到具體的行號了,
$addr2line -e /home/dejun.xdj/kvs-kernel/src/libredis-server.so 0x6dad0
/home/dejun.xdj/kvs-kernel/src/debug.c:304
*((char*)-1) = 'x';
以上只是為了說明除錯流程,舉的乙個簡單例子,有時候定位了出core的點,可能還需要更為細緻的分析,結合info輸出和client輸出。在沒有core檔案的場景下,crash report確實能夠提供很大的幫助,上面的流程,有興趣的同學可以直接做成乙個指令碼,直接分析日誌,自動化的獲取出core點的資訊。
參考:
Xcode崩潰除錯
xcode還是比較好用的,搜尋方便,只有充分的摸索各個視窗能找到各種資訊。可以在下面console臺輸入命令列檢視 thread info 可以檢視當前斷點執行緒的資訊,如果再加上乙個數字引數表示檢視某個執行緒號的資訊 thread backtrace 可以檢視呼叫棧 exec bad access...
JNI崩潰除錯
jni崩潰了,系統日誌會列印堆疊資訊,所以第一步就是取日誌 adb shell logcat v threadtime d log.txt 然後找到日誌裡面的關鍵字backtrace例如我的日誌是這樣的 12 04 06 14 38.362 3773 3773 f debug backtrace 1...
WinDbg除錯 崩潰程式
目的 學習和記錄windbg的一些使用。版本不是最新的,如果需要最新的可以自己在網上搜尋一下,當然還有很多漢化版的 我個人喜好原版 1.1關於配置 這個主要就是symbol的問題了,網上一般都會推薦 設定環境變數例如 我的電腦 右鍵選單 屬性 高階選項卡 環境變數 系統變數 新建 變數名 nt sy...