原始碼都沒除錯過,怎麼能說熟悉 redis 呢?

一線碼農發表於2020-10-28

一:背景

1. 講故事

記得在很久之前給初學的朋友們錄製 redis 視訊課程,當時結合了不少原始碼進行解讀,自以為講的還算可以,但還是有一個非常核心的點沒被分享到,那就是原始碼級除錯,
對,讀原始碼還遠遠不夠,還得親自實操,為了彌補這個遺憾,這一篇就補起來哈。

二:vscode 和 redis 的部署

1. 平臺和除錯工具

大家都知道 官方版redis 是不支援 windows 的,即使被微軟開源技術社群移植到了 windows 平臺,版本滯後就不說了,無數潛在的 bug 可能會讓你望而卻步,gitbub地址:https://github.com/microsoftarchive/redis 目前最新的版本是 3.0.5, 官方都已經是 6.0.9 啦! ?

扯這麼多的意思就是想說不要指望用 windows + visualstudio 除錯原始碼,更何況這裡還要除錯最新版的 redis6, 只能上 centos + vscode 了哈 ???

2. vscode 在 centos 上的安裝


[root@localhost data]# wget https://vscode.cdn.azure.cn/stable/d0182c3417d225529c6d5ad24b7572815d0de9ac/code-1.23.1-1525968555.el7.x86_64.rpm
--2020-10-27 07:03:08--  https://vscode.cdn.azure.cn/stable/d0182c3417d225529c6d5ad24b7572815d0de9ac/code-1.23.1-1525968555.el7.x86_64.rpm
Resolving vscode.cdn.azure.cn (vscode.cdn.azure.cn)... 119.39.80.117, 14.204.144.133, 153.37.238.225, ...
Connecting to vscode.cdn.azure.cn (vscode.cdn.azure.cn)|119.39.80.117|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 69499838 (66M) [application/x-redhat-package-manager]
Saving to: ‘code-1.23.1-1525968555.el7.x86_64.rpm’

100%[===================================================================================================================>] 69,499,838  3.36MB/s   in 19s    

2020-10-27 07:03:28 (3.40 MB/s) - ‘code-1.23.1-1525968555.el7.x86_64.rpm’ saved [69499838/69499838]


  • 安裝 vscode 的依賴包 libXScrnSaver, nss

[root@localhost code]# yum install libXScrnSaver-devel.x86_64 libXScrnSaver.x86_64 && yum install nss

  • rpm 安裝 vscode

[root@localhost data]# rpm -ivh code-1.23.1-1525968555.el7.x86_64.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:code-1.23.1-1525968555.el7       ################################# [100%]

安裝完後就可以在 centos 上找到 vscode 的啟動圖示了,??‍?。

3. redis6 原始碼下載

這裡有一個坑要提醒一下,如果你編譯 redis6 的話,centos7 的 gcc 預設是 4.8.5,你需要升級一下:


[root@localhost redis-6.0.9]# gcc -v
gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
[root@localhost ~]# yum -y install centos-release-scl
[root@localhost ~]# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
[root@localhost ~]# source /opt/rh/devtoolset-9/enable
[root@localhost redis-6.0.9]# gcc -v
gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)

然後就可以原始碼下載,編譯,啟動,直接參考官方文件來: https://redis.io/download


$ wget https://download.redis.io/releases/redis-6.0.9.tar.gz
$ tar xzf redis-6.0.9.tar.gz
$ cd redis-6.0.9
$ make
$ src/redis-server

沒什麼好說的,執行完後的啟動介面如下:

三: vscode 除錯 redis

1. 使用 vscode 安裝 c/c++ 擴充套件

具體用法和 windows 上的 vscode 差不多,該怎麼裝還怎麼裝。

2. 使用 debug 生成 launch.json 啟動檔案

選單欄 "Debug" -> "Starting Debug",然後選擇 "C++ (GDB/LLDB)",如下圖:

再配置一下啟動檔案 .vscode/launch.json,將 ${workspaceFolder}/src/redis-server 程式的路徑配置在 program 節點下,如下程式碼所示:


{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/src/redis-server",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

3. 生成編譯指令檔案 tasks.json

在 .vscode 目錄下新建 tasks.json,使用 make 命令編譯 redis 原始碼,最後由 launch.json 讀取生成好的 可執行檔案 redis-server,程式碼如下:


{
	"version": "2.0.0",
	"tasks": [{
		"label": "Build",
		"type": "shell",
		"command": "make",
		"args": [
			"CFLAGS=\"-g -O0\""
		]
	}]
}

4. 除錯執行

在 server.c 中找到 main 啟動函式,下一個斷點過去,按 F5 執行,如下圖可以看到斷點已命中。

為了更加逼真一點,我在 string.c 中的 setCommand 處設定斷點,保證 redis-cli 在執行 set username jack 時斷點命中。

  • client 端

[root@localhost src]# ./redis-cli
127.0.0.1:6379> set username jack


  • server 端

怎麼樣,圖中左側皮膚中的 區域性變數視窗,監控視窗,呼叫堆疊視窗,一目瞭然。。。

四:總結

總的來說,整個搭建過程有一定的繁瑣度,但學啥又簡單呢? 再說原始碼都沒除錯過,怎麼能說熟悉 redis 呢?最後祝大家有一個開心的 redis 除錯之旅!

更多高質量乾貨:參見我的 GitHub: dotnetfly

圖片名稱

相關文章