Redis崩潰除錯

2021-09-23 17:41:36 字數 4431 閱讀 9501

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...