调试方式
这个教程使用的是远程调试(不是远程桌面),代码在Linux下编译和运行,调试客户端在Windows(或者Mac,以下简称Windows)。这样调试的好处是调试环境与真实环境一致,都在Linux运行。
配置需求
一台Linux主机
Windows 下安装 CLion
常见编译报错
No rule to make target 'lib/libjemalloc.a'.
sh: 1: ./mkreleasehdr.sh: Permission denied
sh: 1: ./mkreleasehdr.sh: not found
/bin/sh: 1: ./configure: Permission denied
/bin/sh^M: bad interpreter
这几个是最常见的报错,很多人都会遇到。在Linux上下载代码、编译、安装都是非常顺利的,但在Windows远程调试就会报错。
原因有2个:换行符和文件权限。文件从Windows上传到Linux后,权限位
x
没了; 换行符变成了\r\n
(正确的应该是\n
)。
具体解决方法看:配置换行符 和 修复权限问题
具体步骤
一、配置换行符
在Windows下,Git的默认配置会把代码中的换行符\n
替换成\r\n
,这个配置会导致代码中的sh脚本无法执行。错误提示:
解决方法:
git config --global core.autocrlf input
二、配置服务器环境
登录到Linux,先安装依赖:
Centos:
yum install git cmake make gcc gcc-c++ gdb libarchive
Ubuntu:
sudo apt update
sudo apt install git cmake make gcc g++ gdb
三、配置Clion
下载代码到Windows:
git clone https://github.com/redis/redis.git
切换Redis代码到你想要调试的版本:
cd redis git checkout 5.0.8
- 启动Clion,点击Open打开
redis
文件夹并勾选Trust Project
。
在菜单栏点击
File
、Settings
打开设置面板。找到Build, Execution, Deployment
>Toolchians
,点击+
号新增一个Remote Host
:点击
Credentials
输入框右边的齿轮图标:然后在弹框中点击
+
号新增一个服务器,填写Linux主机的IP地址、端口、ssh的用户名和密码,然后点击Test Connection
,测试可以连接后保存。保存服务器信息后继续配置
ToolChains
。这时会自动识别服务器上的编译工具的路径,如果不能自动识别,可以手动输入/usr/bin/make
、/usr/bin/gcc
和/usr/bin/g++
,然后点击Apply
保存。
切换到
CMake
,在ToolChains
下拉框选择Remote Host
:- 切换到
Makefile
, 在ToolChains
下拉框中选择"Remote Host": 切换到
Deployment
,再依次点击Remote Host
、Mappings
,然后输入一个目录用来保存和编译redis的代码,然后点击OK
保存并关闭配置窗口。保存后CLion会自动上传代码到服务器、开始编译。等待几分钟,然后很可能会因为权限问题提示编译失败:
四、修复权限问题
- 登录到Linux,进入刚刚在
Deployment
中配置的redis目录。 给全部
.sh
和configura
文件加上执行权限:find . -name "*.sh" |xargs chmod a+x find . -name "configure" |xargs chmod a+x
五、重新编译
- 清空编译缓存:将编译目标下拉框改为
distclean
,并点击左边的锤子🔨图标。 重新编译:将编译目标下拉框改为
all
,并点击左边的锤子🔨图标。大概一两分钟后会提示编译成功:
六、开始调试
在“编译”图标旁边的下拉框选择
Edit Configurations
在弹窗左侧选择
redis-server
,并在Executable
中输入src/redis-server
。这是redis编译后的二进制脚本路径。搜索代码
void getCommand
,找到t_string.c
文件的getCommand()
方法,打上断点:
点击蜘蛛图标,开始调试!
这时候服务器上会运行redis-server,并监听6379端口,你可以通过
netstat -an
命令查看在服务器上使用
telnet 127.0.0.1 6379
连接到redis(或者进入redis的src目录使用redis-cli),然后使用get
命令获取一个key:[root@VM-8-5-centos ~]# telnet 127.0.0.1 6379 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. get hello
这时候程序就会停在刚刚的断点位置。你可以使用F7( step in)、F8( step out)来调试代码了。
常见问题
- 如何找到某个命令的代码位置?
搜索命令+Command
就可以找到对应命令的处理函数,例如setCommand
、getCommand
、delCommand
等。 - 如何调试Redis的启动过程?
redis的启动过程在server.c
的main
函数。打上断点后,再以调试模式运行Redis即可。