《Redis官方文档》Redis调试指南
原文鏈接? ? ? 譯者:Adeline
Redis開發過程中十分注重其穩定性:我們盡一切努力來保證每一個版本的穩定,不出現突然崩潰等情況。但是即使在我們百分百的努力下,仍然沒辦法保證百分百的無bug。
Redis出現崩潰時,會生成一個詳細的報告來描述當時的情景,但是有時候只看報告還不夠,而且Redis的核心開發團隊可能也沒辦法獨立重現你出現崩潰時候的場景:在這種情況下,我們需要用戶能夠重現這個情景來幫助我們。
這個指南講解了如何使用GDB來獲得Redis開發者可能用到的信息。
GDB是什么?
GDB是一款GNU調試器:一個可以查看到其他程序內部狀態的程序。通常來講,跟蹤和修正bug其實就是一個收集更多的bug出現時的信息的過程,所以GDB是一個極為有用的工具。
GDB有以下兩種使用模式:
- 可以連接到一個運行的程序上來觀察程序正在運行時候的狀態
- 可以觀察已經結束運行的程序的狀態,使用程序運行時候的內存鏡像,叫做核心文件(core file)來實現。
從調試Redis的bug的角度來看,我們需要用到GDB的這兩種模式:用戶可以通過把GDB連接到Redis實例上來重現bug出現時候的場景,當崩潰發生時,用戶可以創建core file來給Redis開發人員,開發人員可以用它來查看崩潰發生時Redis的內部運行狀態。
這種方法使得開發人員可以獨立在自己的電腦上進行模擬和跟蹤,不需要用戶的配合,也就不需要用戶在生產環境中為了配合調試來進行Redis的重啟了。
不使用優化選項編譯Redis
默認情況下,Redis是使用 -O2選項編譯的(譯者注:-O2是gcc編譯時的優化選項),這表示編譯器優化是啟動的。這使得Redis運行更快,但同時也使得Redis(與其他程序一樣)更難被GDB觀測。
使用GDB連接時,最好使用make noopt命令來編譯Redis,使其不進行編譯優化(而不是僅僅使用make)。但是如果你已經在生產環境中使用了Redis,而且重新編譯可能會帶來一些問題和麻煩的話,就沒有必要重新編譯了。盡管是會有一些限制,但是對于使用優化選項編譯的程序,GDB也是可以用的。
如果你能在第一次出現崩潰后就把Redis不使用優化的重新編譯一下,那是極好的,因為下次出現問題的時候就很好跟蹤了。
你不用擔心不使用優化編譯對性能的影響,因為Redis并非計算密集型(CPU-bound)軟件(更偏向I/O密集型),這點小的影響很難在你的環境中構成問題。
把GDB連接到一個運行的進程上
如果你有一個運行中的Redis 服務器,你可以把GDB連接到上面,如果Redis崩潰你既可以查看內部運行狀態也可以創建一個core dump文件。
把GDB連接到Redis進程上不會對Redis的運行性能有影響,所以這不是一件危險的事,可以放心去做。
為了把GDB連接上去,首先要知道Redis實例的進程ID(進行的pid)。你可以使用?redis-cli輕松獲取到:
上面的例子中,進程ID是58414 。
- 登錄到Redis服務器上
- (非強制但建議的步驟)使用screen? 或者tmux?終端來保證ssh連接超時后GDB會話不會被關閉。如果不知道screen是什么,可以閱讀這篇文章
- 使用如下命令將GDB連接到Redis服務器:
-
gdb <path-to-redis-executable> <pid> 例如:gdb /usr/local/bin/redis-server 58414
GDB會啟動并連接到運行的服務器上,打印信息大致如下:
- 這時候GDB已經連接上了,但是Redis實例現在被GDB阻塞了。為了使Redis實例繼續運行,只需要在GDB提示界面中輸入continue,然后回車即可。
- 完成!現在你的Redis服務器已經連接了GDB,你可以等著下次崩潰啦:)
- 如果你是使用screen/tmux運行GDB的話,現在是時候把GDB的運行和screen/tmux會話分離開了(譯者理解就是關閉會話不會影響程序運行的意思),使用Ctrl-a a?即可。
崩潰發生后
Redis的DEBUG SEGFAULT命令可以模擬段故障(也就是一個嚴重的意外崩潰(當然不要在真正的生產系統中這個命令哈),現在我要用這個命令來使Redis崩潰,看看GDB中都做了什么:
(gdb) continue
Continuing.
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xffffffffffffffff
debugCommand (c=0x7ffc32005000) at debug.c:220
220???????? *((char*)-1) = ‘x';
如你所見,GDB檢測到了Redis的崩潰,甚至顯示除了出錯的文件名和行號。這已經比Redis的崩潰跟蹤報告要詳細了(報告只包括函數名和二進制偏移)
獲取堆棧跟蹤
第一件事兒就是使用GDB獲得全棧跟蹤信息。這非常簡單,使用bt?命令就可以(bt是backtrace的簡寫)
請一定在bug報告中包括這兩種信息。
獲得核心文件(core file)
下一步就是生成core dump,這是運行的Redis 進程的內存鏡像。使用gcore?命令來完成:
有一點很重要,你需要知道這包含Redis實例崩潰時其中包含的所有數據:Redis開發者可以保證不會泄露這些數據,并且在調試結束后第一時間刪除,但你還是需要知道發送的core file中包含你的數據。
如果你的數據中包含比較敏感的信息,我們建議您把dump文件直接發給Salvatore Sanfilippo(就是這個文檔的作者),郵箱地址是antirez at gmail dot com
需要給開發人員發送的信息
現在你可以把所有的信息發送給Redis核心團隊了,這些包括:
- 你正在使用的Redis可執行文件
- 使用bt命令導出的堆棧跟蹤和寄存器dump
- 使用GDB生成的核心文件(core file)
- 操作系統信息,GCC版本,Redis版本
感謝
您的幫助對我們來說非常重要!有許多的問題只能用這種方式來跟蹤,非常感謝!而且幫助我們進行調試你有可能獲得摩卡咖啡壺的獎勵哦(Redis Moka Award).?
總結
以上是生活随笔為你收集整理的《Redis官方文档》Redis调试指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lxml学习【未完成】
- 下一篇: linux命名详解及其软件安装实例