曹工说Redis源码(1)-- redis debug环境搭建,使用clion,达到和调试java一样的效果
概要#
最近写了 spring 系列,这个系列还在进行中,然后有些同学开始叫我大神,然后以为我各方面都比较厉害,当然了,我是有自知之明的,大佬大神什么的,当作一个称呼就好,如果真的以为自己就是大神,那可能就走偏了。
其实我不少方面都比较薄弱,比如 redis、mysql、jvm 这些 c 语言写的东西,很多书,我也看过多次,看的那段时间,你可能懂了,也可以在面试的时候,侃侃而谈,但是,过一阵再问你,你可能部分细节已经记不住了。
我现在本科毕业快 7 年,虽然这些年一直也在学,但是记忆这东西,好像是有些退化,记个东西,感觉确实越来越容易忘;尤其,是这些平时光看不练的东西。
所以,打算在实践中,来掌握这些东西。
比如,你说 redis 的字符串的底层实现,很多人可能都能答上来,是 sds,但是只是看,只是记,这种简单的还好,复杂一点的,两个月肯定忘。
所以,我们就希望,能够把 redis 的源码拉下来看,看的过程,你可以自己在源文件里加注释;同时,也要支持 debug,来观察程序的运行过程,来看看,一个请求进来,是怎样编解码,怎么样被处理的,怎么样返回结果的,网络通信怎么做的,这之类的。
我们选择的代码,是 Redis 畅销书,Redis 设计与实现(第二版)里配套的代码,作者已经加了很多注释,我们可以结合代码、书一起来学习,合适的情况下,我们也要能写一个小 demo,实践实践。
所以,第一步的环境搭建尤为重要,而且,redis 看懂了,相信以后看 mysql,也不会问题特别大。当然,需要一些 c 语言基础,我也会在文章里讲一些,我自己也是半斤八两,边看边学呗,还能怎么样呢?
这个系列,估计会更新比较慢,因为我的 c 语言基础,也不是很好。
好了,我们开始吧。
环境搭建的大体思路#
windows 下安装 linux 工具链#
大家记得在 linux 上,怎么安装 redis 那些的吧,是不是有个 configure,make,make install 啥的,为啥 java 程序不需要这么弄呢?因为 java 有 jvm,我们的 java 文件是编译成 class,在 jvm 上运行的,而 c 语言程序,是直接依赖于操作系统的,同样的 c 语言程序,比如你要实现网络功能,在 windows 上和在 linux 上,要调用的 api,是不一样的,总之呢,就是 c 语言程序,是严重依赖于底层的操作系统。
切回正题,在 linux 下我们是用gcc
来编译 c 语言程序的,比如,针对以下这个简单的 helloWorld:
#include <stdio.h>
int main(void) {
printf("hahha");
return 0;
}
要像下面这样,用gcc
编译为二进制,才能继续执行:
gcc、make 这些都是 linux 下的工具,在 windows 下怎么办呢?这个不用担心,早有人帮我们弄好了,前辈们将这些 linux 下的工具,移植到了 windows 下,现在有两种主流方案,一种是 MinGW,另一种是 cygwin。
我们只需要安装这两种软件中的一种,就可以在 windows 下使用本来在 linux 下才能使用的工具了,上面那个图,就是我在 windows 下截的。
至于 MinGW 和 cygwin 的差别,大家自行去查询,因为我找了些答案,感觉都有些冲突。我们的需求比较简单,两种都可以满足,我这边选择了 cygwin,建议大家和我这边保持一致。
cygwin 呢,在安装过程中,会让我们选择要安装的工具,比如 gcc、g++(c++ 时候使用)、make、cmake 等,我们可以按需选择。
什么是 make 和 cmake#
大家参考这个链接:CMake 与 Make 最简单直接的区别
看完这个之后,我再简单说说,我的理解是,一个程序,在 linux 下运行,你要写一份 makefile;如果要弄到其他平台,这个 makefile 就用不了了,要再写一份。
所以,为了跨平台,出现了 cmake,cmake 是让程序员用统一的语法来写 cmake 文件,然后 cmake 会帮助我们生成对应的平台下的 makefile。
果然是,没有什么是加一个中间层不能解决的。
对于 java 的同学,可理解为:cmake 就像 jvm 一样,帮助我们跨平台。
cmake 呢,也是通过前面的 cygwin 来安装的。
安装 c 语言开发的 ide#
这个呢,我咨询了两位朋友,做 c 的,然后他们都是用的 visual studio,我一开始也是下载这个,但是比较大,我下载的 visual studio 2012(应该是比较老的版本了),都要 1.5g,下载花了就比较久,安装又是半个小时,然后装完还不怎么会用;
在上面的 vs 下载的过程中,我在网上找了下,也有很多使用 jetbrains 公司出的 clion
。这个呢,我目前就是用的这款,最大的好处是,它和 idea、pycharm 这些一样,同一个公司出的,所以,操作界面、操作习惯、包括快捷键,几乎都是差不多的,可以无缝切换。
一开始,我安装的是 clion 2018.3 版本,然后遇到个问题,也不知道怎么解决,就又下了 clion 2019.1 版本,问题还是没解决,最后换了 clion 2019.3 版本,问题还是在,不过虽然问题一直在,但其实也无关大局,就忍一忍算了。
期间,visual studio 2012 终于下载完了,装了半个小时多,发现用着还是不太习惯,而且,好像不太支持导入 cmake 工程,干脆就卸了,结果,卸载又花了半天,因为它给我的电脑,装了近 20 个软件。。。我他么。。。
所以,最终我这边的 ide 是 clion 2019.3,下载链接:clion 2019.3 链接
具体安装步骤#
cygwin 安装#
安装前,先下载,下载链接:cygwin 官网,在这里,目前下载下来的版本,是 3.1.4.1,为什么要强调版本,因为 clion,不同的clion
版本,支持的 cygwin
版本不一样,我看网上都没人提过。
clion 为啥要依赖 cygwin,因为 clion 只是个 ide,具体的代码编译之类的,还是要 gcc、cmake 这些来做的,我给大家看下,我一开始下载的 2018.3 版本,配置了我的 cygwin 之后,提示如下:
这也是为什么后来,遇到问题我要升级版本的原因,因为我总感觉,有可能是这里的问题,虽然升级了版本,问题也还在。
建议大家还是和我版本保持一致。
- cygwin:3.1.4.1
- clion:2019.3
大概的安装步骤,可以看这个:
https://blog.csdn.net/testcs_dn/article/details/78866994
https://blog.csdn.net/shouwangzhelv/article/details/54919235
注意的是,下面这个路径要记住,后面会用:
然后,在设置镜像网站时,我是用的阿里云:http://mirrors.aliyun.com/cygwin/
接下来,就是让我们选择要安装的东西,网上一般给的就是如下几个:
gcc-core、gcc-g++、make、gdb、binutils ,我建议大家把 vim 也装上,方便操作。
然后就是等它安装完成,完成后,桌面上会有如下图标:
然后,双击打开,可以依次执行以下命令:
- cygcheck -c cygwin , 查看安装的 cygwin 版本信息
- gcc --version , 查看安装的 gcc 版本信息,这个是编译 c 的
- g++ --version, 查看安装的 g++ 版本信息,这个是编译 c++ 的
- gdb --version, 查看 gdb 版本信息,这个是 debug 用的,非常出名
如果都没啥问题的话,那基本就安装好了。
然后,大家还记得前面安装时,选择的路径吗?把那个路径的 bin 目录,加到 path 这个环境变量,然后我们就可以在 cmd 里用上面那些命令了。
clion 安装及插件安装#
下载链接:clion 2019.3 链接
这个的安装,和 idea 的安装,没啥差别,不过大家不要选太多插件,很多毕竟用不上,按需选择吧。比如什么 cvs、svn 那些,装了干啥呢,对吧。
然后我自己直接用的试用 30 天,等到后续真需要破解再说。
安装过程中,可能就会让大家配置 tool chains,直接输入前面的 cygwin 的目录即可。
从上面可以看到,我们这里,用的 cmake,就是 cygwin 下的,gdb 也是的。
然后,我们可以再安装两个插件(Cmake Sinple highlighter 和 CMake Plus),如下:
其中一个要付费,不过可以先试用。
克隆 redis 代码#
地址:https://gitee.com/ckl111/redis-3.0-annotated-cmake-in-clion
这里感谢前辈博客:https://blog.csdn.net/u013656184/article/details/88812572
我这里基于他的博客,对 cmake 文件,做了少许的修改。
大家把代码克隆到本地后,然后在 clion 中,打开工程即可。
打开工程后,大家要注意上面的 CMakeList.txt,其中,已经默认给我们配置了几个 target:
其中,库应该是不能独立运行的,我们可以运行下面的三个,其中:
- redis-cli,redis 客户端
- redis-server,服务端
- redis-example,这个是我自己加的,主要是希望:可以像在 java 中那样,启动一个 main 方法,去测试一些工具类啊或者啥的,不然的话,就得写到 redis-server 的代码中,然后用 redis-cli 去访问,去触发我们的测试代码。主要是类似于一个测试用的入口。
redis-example,我还多说一点,仔细看 CmakeList.txt,可能就理解了:
如何调试#
拿 redis-example 举例:
不过这里的 debug,有一点问题,就是会开一个单独的 cmd 窗口,而不是直接在 Console 中输出;printf 也有点问题。
但是,使用 run 方式运行,则没有任何问题。
如何调试 redis-server#
方法和上面一样,其实大家更关心断点打在哪儿吧,可以打在下面这个地方:
redis.c
文件的processCommand
,这里我还加了一行注释给大家:
int processCommand(redisClient *c) {
/* The QUIT command is handled separately. Normal command procs will
* go through checking for replication and QUIT will cause trouble
* when FORCE_REPLICATION is enabled and would be implemented in
* a regular command proc. */
// 特别处理 quit 命令
void *commandName = c->argv[0]->ptr;
redisLog(REDIS_NOTICE, "The server is now processing %s", commandName);
调试如下:
redis-cli,我们可以就用工程给我们生成的那个,版本是配套的:
可以看到,断点已经生效了,且,客户端的请求已经到达。
总结#
万事开头难,希望大家和我一起,开始这次的 redis 之旅。