调试方式

这个教程使用的是远程调试(不是远程桌面),代码在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

参考:自定义 Git - 配置 Git

二、配置服务器环境

登录到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

  1. 下载代码到Windows:

     git clone https://github.com/redis/redis.git
  2. 切换Redis代码到你想要调试的版本:

     cd redis
     git checkout 5.0.8
  3. 启动Clion,点击Open打开redis文件夹并勾选Trust Project
  1. 在菜单栏点击FileSettings打开设置面板。找到Build, Execution, Deployment > Toolchians,点击+号新增一个Remote Host

  2. 点击Credentials输入框右边的齿轮图标:

  3. 然后在弹框中点击+号新增一个服务器,填写Linux主机的IP地址、端口、ssh的用户名和密码,然后点击Test Connection,测试可以连接后保存。

  4. 保存服务器信息后继续配置ToolChains。这时会自动识别服务器上的编译工具的路径,如果不能自动识别,可以手动输入/usr/bin/make/usr/bin/gcc/usr/bin/g++,然后点击Apply保存。

  1. 切换到CMake,在ToolChains下拉框选择Remote Host

  2. 切换到Makefile, 在ToolChains下拉框中选择"Remote Host":
  3. 切换到 Deployment,再依次点击Remote HostMappings,然后输入一个目录用来保存和编译redis的代码,然后点击OK保存并关闭配置窗口。

  4. 保存后CLion会自动上传代码到服务器、开始编译。等待几分钟,然后很可能会因为权限问题提示编译失败:

四、修复权限问题

  1. 登录到Linux,进入刚刚在Deployment中配置的redis目录。
  2. 给全部.shconfigura文件加上执行权限:

    find . -name "*.sh" |xargs chmod a+x
    find . -name "configure" |xargs chmod a+x

五、重新编译

  1. 清空编译缓存:将编译目标下拉框改为distclean,并点击左边的锤子🔨图标。
  2. 重新编译:将编译目标下拉框改为all,并点击左边的锤子🔨图标。大概一两分钟后会提示编译成功:

六、开始调试

  1. 在“编译”图标旁边的下拉框选择Edit Configurations

  2. 在弹窗左侧选择redis-server,并在Executable中输入src/redis-server。这是redis编译后的二进制脚本路径。

  3. 搜索代码void getCommand,找到t_string.c文件的getCommand()方法,打上断点:

  1. 点击蜘蛛图标,开始调试!

    这时候服务器上会运行redis-server,并监听6379端口,你可以通过netstat -an命令查看

  2. 在服务器上使用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
    
  3. 这时候程序就会停在刚刚的断点位置。你可以使用F7( step in)、F8( step out)来调试代码了。

常见问题

  • 如何找到某个命令的代码位置?
    搜索命令+Command就可以找到对应命令的处理函数,例如setCommandgetCommanddelCommand等。
  • 如何调试Redis的启动过程?
    redis的启动过程在server.cmain函数。打上断点后,再以调试模式运行Redis即可。
03-05 22:39