(本文仅作为记录,还有待完善的地方)
问题点:Clion 使用了 cmake 来管理项目,所以我们需要在 Redis 源码根目录下为它创建好 CMakeLists.txt 才能进行构建。
尝试调试最新版Redis报错排查
刚开始参考 mac + CLion + redis5 本地调试/运行 进行调试,过程中遇到了一些新的问题,记录如下:
deps/hiredis/CMakeLists.txt
CMake Error at deps/hiredis/CMakeLists.txt:168 (add_library):
add_library cannot create target "hiredis" because another target with the
same name already exists. The existing target is a shared library created
in source directory "/Users/cfq/CLionProjects/redis/deps/hiredis". See
documentation for policy CMP0002 for more details.
-- Configuring incomplete, errors occurred!
See also "/Users/cfq/CLionProjects/redis/CMakeFiles/CMakeOutput.log".
应该是因为新版本的代码,作者已经在 deps/hiredis/
目录下加了 CMakeLists.txt
文件,照着这个文章里的步骤三会有重复添加,所以把刚才添加的删了就好。
再次执行cmake .
,结果如下:
$ cmake .
Detected version: 1.0.0
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/cfq/CLionProjects/redis
说明 cmake
操作已经好了。
ae_kqueue.c
之后执行 make
命令,出现了ae_kqueue.h
文件的错误,因为mac和linux的异步机制用到的库不一样,所以需要修改;
在ae_kqueue.c文件中添加下面两行即可。
#include "ae.h"
#include "zmalloc.h"
修改后,再次make
,又报如下错误:
[ 34%] Building C object CMakeFiles/redis-server.dir/src/ae_kqueue.c.o
/Users/cfq/CLionProjects/redis/src/ae_kqueue.c:59:5: error: implicit declaration of
function 'anetCloexec' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
anetCloexec(state->kqfd);
^
/Users/cfq/CLionProjects/redis/src/ae_kqueue.c:136:32: error: use of undeclared
identifier 'errno'
} else if (retval == -1 && errno != EINTR) {
^
...
/Users/cfq/CLionProjects/redis/src/ae_kqueue.c:137:49: error: use of undeclared
identifier 'errno'
panic("aeApiPoll: kevent, %s", strerror(errno));
^
6 errors generated.
make[2]: *** [CMakeFiles/redis-server.dir/src/ae_kqueue.c.o] Error 1
make[1]: *** [CMakeFiles/redis-server.dir/all] Error 2
make: *** [all] Error 2
分析后,发现是因为ae_kqueue.c
文件中没有定义anetCloexec
,。
猜想anetxxx
应该是anet.c
文件中定义的,(anet.c
对内核提供的网络接口做了封装,从而能够以更加简单的方式使用 POSIX 网络接口),于是在 ae_kqueue.c
文件中加入了#include "anet.c"
,之后再 make
就没有刚才的报错了。
‘panic’ is invalid
新的报错如下:
/Users/cfq/CLionProjects/redis/src/ae_kqueue.c:139:9: error: implicit declaration of
function 'panic' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
panic("aeApiPoll: kevent, %s", strerror(errno));
^
考虑到这个暂时没用,就把这行错误处理换成输出错误了:
printf("panic");
// panic("aeApiPoll: kevent, %s", strerror(errno));
‘release.h’ file not found
之后又报错如下:
/Users/cfq/CLionProjects/redis/src/release.c:37:10: fatal error: 'release.h' file not
found
#include "release.h"
^~~~~~~~~~~
1 error generated.
make[2]: *** [CMakeFiles/redis-server.dir/src/release.c.o] Error 1
make[1]: *** [CMakeFiles/redis-server.dir/all] Error 2
make: *** [all] Error 2
需要执行bash src/mkreleasehdr.sh
才能生成releases.h
文件,而不是sh src/mkreleasehdr.sh
ld: symbol(s) not found for architecture x86_64
再次执行 make
操作,报错如下:
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [src/redis-server] Error 1
make[1]: *** [CMakeFiles/redis-server.dir/all] Error 2
make: *** [all] Error 2
因为对c语言不太熟,所以在网上找看了很多资料,但是都不是太懂,没有解决问题,知道看到了这个项目,里面有介绍为何Redis项目使用cmake了,以及如何使用,其中比较重要的一段如下:
export REDIS_SOURCE_CODE_PATH="/Users/cfq/CLionProjects/redis"
cmake -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - Unix Makefiles" ${REDIS_SOURCE_CODE_PATH}
cmake --build ${REDIS_SOURCE_CODE_PATH}/cmake-build-debug --target redis-server -- -j 12
# This step lead to an error :ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
# so We should play a trick to the linker
echo "set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -c")" >> ${REDIS_SOURCE_CODE_PATH}/CMakeLists.txt
# Then try again
cmake --build ${REDIS_SOURCE_CODE_PATH}/cmake-build-debug --target redis-server -- -j 12
于是,在 shell 终端,输入如下命令:
export REDIS_SOURCE_CODE_PATH="/Users/cfq/CLionProjects/redis"
echo "set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -c")" >> ${REDIS_SOURCE_CODE_PATH}/CMakeLists.txt
之后再运行 make
命令,就可以顺利的编译完了:
...
[100%] Linking C shared li brary helloworld.so
[100%] Built target helloworld
redis-server file not found
但是当准备运行redis-server
的时候,却报错说找不到src/redis-server
这个文件;尝试运行redis-cli
也是同样的报错。
再看最后 make
的输出情况,发现有大量如下的报错:
clang: warning: -Wl,-search_paths_first: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: -Wl,-headerpad_max_install_names: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: CMakeFiles/redis-server.dir/src/server.c.o: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: CMakeFiles/redis-server.dir/src/crcspeed.c.o: 'linker' input unused [-Wunused-command-line-argument]
...
不知道这些waring会不会影响 redis-server
文件的生成。。。
尝试了很多种办法,都没有成功(应该是什么地方的配置有些问题),然后暂时放弃了,,
等之后c语言以及编译相关的知识上来之后,应该就可以解决这个问题了。
调试 4.0.12 版
有了前面的摸索和实践,再参考这个文章的CMakeLists.txt
文件,比较顺利的完成了。
总结步骤如下:
- 参照这个文章,在之前下载好的redis-4.0.12版本的代码里配置好
CMakeLists.txt
文件; - 把之前的CLion删了,重新下载 Version 2020.2.5的CLion,因为这个版本才有
New CMake Project from Sources
这个选项,,,(可能是新版本的默认使用CMake了) - 使用
New CMake Project from Sources
这种方法打开配置好````CMakeLists.txt```文件的Redis源码 - 调试运行
redis-server
文件,出现Redis启动成功输出,就表示能成功运行。
报错排查
在运行redis-server
文件时,会报如下错误:
error: implicit declaration of function ‘redisAssert’ is invalid
/Users/cfq/Desktop/github/DamanChen/redis-4.0.12_annotation/src/rio.c:357:5: error: implicit declaration of function 'redisAssert' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
redisAssert(r->read == rioFileIO.read);
^
1 error generated.
解决如下:
void rioSetAutoSync(rio *r, off_t bytes) {
serverAssert(r->read == rioFileIO.read);
// redisAssert(r->read == rioFileIO.read);
r->io.file.autosync = bytes;
}
把redisAssert
方法 换成serverAssert
这个方法。
成功记录
运行成功如下:
如何在mac系统下使用clion调试redis源码 https://www.jiyik.com/tm/xwzj/sjk_273.html
https://github.com/LHRchina/redis
redis debug环境搭建,使用clion,达到和调试java一样的效果 https://www.cnblogs.com/grey-wolf/p/12637730.html
CMake与Make最简单直接的区别 https://blog.csdn.net/weixin_42491857/article/details/80741060
mac + CLion + redis5 本地调试/运行 https://www.jianshu.com/p/904b44911ab9