redlock编译报错分析

背景介绍

在微服务的应用中,多个服务之间有时需要资源共享,这时传统的线程锁不再那么好用,我们希望基于服务于服务之间的互斥锁来实现资源的互访,这时分布式锁应运而生,Redis也提供了分布式锁的功能,我们按照官方推荐的redlock c++版本来进行实践。

首次编译

从git 库上获取源码

git clone https://github.com/jacket-code/redlock-cpp
cd redlock-cpp

由于该项目依赖于hiredis,所以在编译之前需要修改hiredis的依赖路径(库与头文件)

vim Makefile

改动如下:
在这里插入图片描述
改动之后接着进行编译

make

编译报错,报错信息如下:
在这里插入图片描述
错误:multiple definition of ‘sdsnewlen’,查看源码发现该工程中自带了sds.c、sds.h,而libhiredis.a中也有sds.c、sds.h,导致链接出错。

简化问题复杂度

那么为了简化问题的复杂度,我们单独把我们需要的redlock.cpp、redlock.h拷贝出来,脱离出原始工程,抛开自带的Makefile来进行编译
在这里插入图片描述
同时自己写了简单的main.cpp来测试编译报错问题main.cpp的实现如下:
在这里插入图片描述
编译

g++ -o test main.cpp redlock.cpp -I/home/test_platform/plantfrom/include -L/home/test_platform/plantfrom/lib -lhiredis

其中/home/test_platform/plantfrom/include为我的hiredis头文件路径,/home/test_platform/plantfrom/lib为我的libhiredis.a的库文件目录
编译结果如下:
在这里插入图片描述
编译失败,提示找不到sds.h,突然想起来我现在是使用hiredis提供的头文件,所以还需要把sds.h的包含路径修改为hiredis/sds.h,the modified redlock.h like this:
在这里插入图片描述
再次编译
在这里插入图片描述
undefined reference to “sdsnew”的错误,感觉像是链接出现了问题

再次简化编译模型

出现 undefined reference to “sdsnew”的错误,感觉sdsnew的实现没有链接到,为了进一步排查问题原因,我们再次简化问题,将mian.cpp直接包含sds.h,同时main.cpp的内容不包含任何redlock的内容,使编译只依赖一个main.cpp和hiredis的库。main.cpp like this:
在这里插入图片描述
编译测试
在这里插入图片描述
仍然报错,不过我大致知道是什么原因,因为g++编译c库函数需要使用extern “C”括起来,所以在mian.cpp中增加extern “C”
main.cpp as below:
在这里插入图片描述
编译测试
在这里插入图片描述
编译通过,这就告诉我们一个信息,libhiredis.a是存在sds的实现的,所以大方向没问题,与此同时一个问题也被引出,为什么直接包含sds.h就可以编译通过,而使用#include “redlock.h”间接包含sds.h却编译不过,进一步测试,我们将main.cpp包含的头文件仍改为#include “redlock.h”,然后去掉redlock.h无用信息,仅保留#include “hiredis/sds.h”语句,修改如下:
main.cpp as below:
在这里插入图片描述
redlock.h as below:
在这里插入图片描述
编译测试
在这里插入图片描述
还是出现undefined reference to ‘sdsnew(char const*)’,那我们继续排查,把redlock.h中其他的头文件去掉,redlock.h as below:
在这里插入图片描述
编译测试
在这里插入图片描述
编译通过!!!为什么去掉hiredis/hiredis.h就可以编译通过呢?我突然想到hiredis是采用c方式进行编译的,我们运用到c++项目中可能需要加上extern “C”,所以我这样改动继续测试一下是否能成功编译
在这里插入图片描述
编译测试
在这里插入图片描述
仍然可以编译通过,那么我们将main.cpp恢复,将redlock.h屏蔽掉的部分代码恢复,再次验证编译
main.cpp like this:
在这里插入图片描述
redlock.h like this:
在这里插入图片描述
编译测试
在这里插入图片描述
仍然可以编译通过,说明就是因为redlock.h中未将hiredis/hiredis.h纳入到extern “C”中,才导致出现的编译错误

总结

此问题最具有迷惑性的地方在于编译错误提示sds链接失败,所以我一直将很大部分精力投入大sds.h的链接问题上,浪费了很长时间,忽略了hiredis的头文件问题,导致花了好几个小时查找编译原因。有些问题表面上看是A,可能深层次的原因是B导致的,所以解决问题需要发散性思维,多从其他角度考虑一下,或许有不一样的收获

发布了7 篇原创文章 · 获赞 5 · 访问量 847

猜你喜欢

转载自blog.csdn.net/dean_zhang5757/article/details/103693368