本文介紹如何通過gdb來除錯redis的源**。相對於只是檢視原始碼,通過gdb還能夠在實際場景中觀察**如何執行,記憶體如何變化,這對於理解redis-server的執行機制非常有必要。
在進行redis-server一般命令的執行機制除錯時,不需要你精通c/c++程式設計,只需要知道gdb的一些基本命令就可以了。
通過gdb對redis-server進行除錯時,需要知道一些基本的gdb命令。比如說,如何打斷點,如何列印結構體的內容,如何跟蹤子程序的執行等等。本節介紹一些基本的gdb命令,通過這些命令就可以進入redis的世界了。
$ gdb ./src/redis-server
(gdb)
命令名功能r
執行剛才載入的二進位制程式,可以指定引數
b打斷點,後面的引數可以是函式,或行數
n單步執行,但不進入函式中
s單步執行,進入呼叫函式
bt檢視目前的呼叫堆疊(很有用,可以檢視函式的呼叫棧,和目前執行的位置)
l檢視**,引數可以是函式名,或行數
p列印變數或結構體的值
其他命令可以檢視gdb手冊。
cd redis-4.0.9
make
編譯好的二進位制在src下,還要注意,在redis-4.0.9目錄下有乙個redis.conf檔案,這是執行redis-server時的配置檔案。
編譯完成後,在src下,應該還有幾個其他編譯好的可執行檔案:
redis-server: redis服務的主二進位制**
redis-cli : redis命令列客戶端
redis-benchmark
redis-sentinel
...
本文介紹中,我們要用到的是兩個 redis-server和redis-cli
好了,編譯好**後,我們開始除錯redis-server了
$ gdb src/redis-server
(gdb)
要檢視set命令的執行過程,首先要對執行set命令的函式入口打上斷點。然後進入該處理函式,單步執行。在server.c**中,有乙個命令處理的列表函式,如下:
struct rediscommand rediscommandtable = ,,,
,,
......
從以上**我們看到set命令的實現函式是setcommand,我們可以在該函式的入口處打上斷點:
// 打上斷點
(gdb) b setcommand
// 執行redis-server
(gdb) r ./redis.conf
此時,gdb會阻塞在redis-server的等待連線的地方,因為沒有redis客戶端連線服務端,此時我們需要啟動redis-cli,並傳送set命令。
開乙個新的終端,進入剛才編譯redis的目錄,並啟動redis-cli。
cd redis-4.0.9/src
$ ./redis-cli
127.0.0.1:6379> set k1 "v123"
(gdb) bt
#0 setcommand (c=0x102016000) at t_string.c:102
#10x000000010000cd53 in call (c=0x102016000, flags=15) at server.c:2229
#20x000000010000d61e in processcommand (c=0x102016000) at server.c:2510
#30x000000010001dd76 in processinputbuffer (c=0x5b91a431) at networking.c:1354
#40x00000001000051ee in aeprocessevents (eventloop=0x1005289b0, flags=11) at ae.c:440
#50x000000010000552b in aemain (eventloop=0x5b91a431) at ae.c:498
#60x0000000100010680 in main (argc=1, argv=0x0) at server.c:3894
進入該函式,並單步執行:
(gdb) n
138 c->argv[2] = tryobjectencoding(c->argv[2]); //為了節約記憶體:對string的value進行編碼
若想進入函式內部,直接通過s命令:
(gdb) s
tryobjectencoding (o=0x100306600) at object.c:384
384 serverassertwithinfo(null,o,o->type == obj_string);
列印變數的值:
(gdb) p o
$1 = (robj *) 0x100306600
// o是指標
// 通過以下命令列印指標的內容
(gdb) p *o
$2 =
(gdb) p o->type
若要直到命令處理的全過程,可以processcommand函式打上斷點。然後,和上面介紹的一樣單步執行。
本文描述了如何通過gdb對redis-server進行除錯,並對redis-server的內部執行進行觀察。但本文並沒有介紹更加複雜的gdb的除錯技巧,比如多程序的除錯。
GDB來除錯IPHONE步驟
iphone手機必須越獄 安裝以下外掛程式是必需的 openssh,作為ssh服務端 gnu debugger gdb除錯工具 在這個源中cydia.radare.org,版本為1708,低版本不支援ios4.3 adv cmds ps命令可以檢視程序資訊 darwin cc tools otool...
通過 GDB 除錯理解 GOT PLT
關於 linux 中 elf 檔案格式可參考詳細文件 elf format 本文僅記錄筆者理解got plt的過程。got global offset table 全域性偏移表用於記錄在 elf 檔案中所用到的共享庫中符號的絕對位址。在程式剛開始執行時,got 表項是空的,當符號第一次被呼叫時會動態...
通過GDB除錯理解指標
源 include intmain 編譯上面的 之後進行除錯。在初始化之前,a pon ppon的值各為 可以使用info locals命令進行檢視區域性變數 0x0執行結束退出main之前,a pon ppon的值各為 a 0xapon 0x7ffeefbff94c ppon 0x7ffeefbf...