当前位置:C++技术网 > 资讯 > 分析并解决curl库的link-time和compile-time问题

分析并解决curl库的link-time和compile-time问题

更新时间:2018-04-18 13:54:25浏览次数:1+次

    昨天在安装完libcurl之后,导致了python在导入pycurl模块时报错,报错为libcurl link-time ssl backend (nss) is different from compile-time ssl backend (openssl)。通过一晚上的研究分析,终于找到问题所在,并解决了。通过问题回顾-问题推测-搜寻资料-尝试解决方法-问题解决方法分析-最后总结,充分将问题保留,展示解决问题的过程,彻底解决问题,同时在这个过程中让自己得到锻炼,而不是被问题打败!

问题回顾:
    昨天在开发Linux下的C++程序时,需要用C++来请求http接口。然后我选择了libcurl库,这个库使用的很广泛。要使用必然要先安装,所以就安装了一个最新版curl-7.59.0,pycurl版本为7.43.0。然后C++这边的http接口调用编写好后,测试也没有问题了。然后不料发现Web系统出问题了,所有接口都在报错,报错提示如下:
libcurl link-time ssl backend (nss) is different from compile-time ssl backend (openssl)

        这是一个新错误,看的一脸懵逼。看错误提示是与curl有关。大概看提示的意思是libcurl的链接时间和编译时间不一样。然后报错是在python代码里导入pycurl时发生的。C++和python唯一在这里相关的就是curl库。那么现在问题就是,curl库有问题。

    

问题推测:
1.C++安装的libcurl和python的pycurl的版本不一致
2.C++安装的libcurl是编译安装的,可能我的安装方法不对
3.链接的库不对,可能安装时没有配置好

搜寻的资料:
1.用C++重新编译安装curl :https://blog.csdn.net/u011299686/article/details/42247905
2.重装pycurl: https://blog.csdn.net/jacsice/article/details/21404741
3.重装pycurl:https://blog.csdn.net/androidstar_cn/article/details/53048816
    看资料显示的解决办法,似乎重装就OK了。然而都是治标不治本,因为不同的系统配置以及个人的安装方式都有差异,博主是解决了,但是却不能有复制性,别人如果环境类似,可能走狗屎运碰到了,也解决了。如果没有这么好的运气,那就根本无法解决。而且,这些文章并没有真正找到问题的原因,也只是碰巧解决了。说不定是重新安装的时候,安装目录换了或者配置变了,或者版本不一样默认的安装行为变了等等,都会碰巧解决了。

        然而,我总是一个运气不好的人,所以没法蒙混过关。昨晚一直找问题到快0点,最后找到了问题。感谢两个小伙伴一起帮我分析,最终被我找到了问题所在。先来说说解决的过程。

    

尝试解决方法:
1.卸载C++安装的libcurl。Linux编译安装的,没有配置安装目录,所有安装的东西都是默认位置,都分布在系统的目录。查到的卸载方法,很复杂,而且不敢动。因为公司系统是在运行的,不能随便动,万一把底层库搞死了,那服务器就瘫痪了。非常危险的操作,看看就不敢动。之前解决问题,导致重装系统N次,那是测试时候。现在不能冲动了。这个方法放弃了!
2.用C++安装与pycurl同样版本的7.43.0。安装了,一切顺利完成,但是报错没有任何不同,失败!
3.重装pycurl7.43.0。重新安装pycurl,需要先卸载pycurl,结果提示要卸载与python2.6目录下的pycurl,估计之前是安装到python2.6的目录下的。第一次有点怕,因为之前卸载python2.6把系统搞挂了,重装了系统。有点阴影,不过确实还是要小心。仔细看过了之后,只是卸载了pycurl,反正现在curl出了问题,还是要大胆试一下。然后卸载了,重新安装了。安装一切顺利。测试,问题依旧!!
4.重新用C++编译安装的libcurl。重新编译安装,一切顺利。问题依旧!!
5.先配置:./configure --without-ssl --with-nss,再重新用C++编译安装的libcurl。可能是安装方法不对,可能是没有配置好,按照网上的说法,配置一下,再编译安装。过程一切顺利,问题依旧!!!
6.直接配置(./configure --without-ssl --with-nss)不安装。在安装完之后再直接配置一下,其实只是瞎试,不过能怎么样呢。
    网上的方法,除了重装还是重装!!哎,真心是难受。感觉是要通宵解决问题了。关键是,还是有点没有头绪,不知道问题所在。
7.后来在小伙伴的建议下,说用安装时候的库去替换新安装的库。依然还是一样的错误提示。
8.既然这样,我就直接将python2.7里的site-packages目录下的pycurl.so和pycurl-7.43.0-py2.7.egg-info删掉。结果再测试,提示模块导入时找不到模块。这让我知道一个信息,python导入的库文件确实是site-packages目录下的。否则的话不会提示找不到模块。
    不过安装回去之后,报错还是一样的。到这里似乎有点苗头了。至少可以确定python导入的库是在哪里的,是没有问题的。
    然后再多看了各个目录几眼,发现在python2.7目录所在的目录也有libcurl.so文件(/usr/local/lib/下)。突然意识到这两个库似乎有点不妥。因为两个地方都有。

    9.然后我就尝试将/usr/local/lib/下的和curl有关的文件都改了名字,让这个库无法使用。简直有点讨厌这个curl了,把相关的文件名字都改掉了。然后再试,惊喜发生了!!!导入没有报错了。然后把之前改掉的业务代码恢复成原来的,功能正常了!!!太开心了,终于找到问题了。

    

问题总结分析:
    终于找到问题了,当然不能只是为了解决问题而解决问题,一定要找到根本问题,所以一定要分析,确定每一个问题现象都可以解决的办法是一致的,方可确认问题根本解决了,否则心里不踏实。
    错误提示是全局的,因为导入这个模块的文件是公共库文件,所以一出错,很多地方受影响。然后是在导入pycurl时报错,错误提示是链接时间和编译时间不一致。而我是用C++新编译安装了一个高版本的curl,python的curl是低版本的,是以前安装的。那么提示的链接时间和编译时间不一致,那么可以确定是新编译安装的curl和python安装的curl的冲突。
    问题是为什么会有这样的提示?python安装的curl是编译好的,直接安装的。而我新装的这个是编译安装的,所以我们不难理解错误提示链接的时间和编译安装时间不一致了。这个好确定产生问题的场景,可以大致确定范围在这个库。

        那么链接是链接的哪个版本,编译又是哪个版本,为什么这些信息会混在一起来报错呢?前面我试了在python2.7里的site-packages目录下删除pycurl.so和pycurl-7.43.0-py2.7.egg-info,确定了python2.7导入的curl是在site-packages目录下的。也就是说,导入的版本的curl是python安装的编译好的curl。编译时间很早。而我新编译的curl的编译时间自然是现在。python导入的是以前安装的curl,而真正在执行链接的时候,查询到的curl库,却是新安装的curl,所以才产生了链接时间和编译时间不一致的问题。当然我这么翻译错误提示是不准确的,提示里还有一个ssl backend(openssl)。大概知道这个错误的意思,知道问题所在,就行了。

    

问题解决方法分析:

        所以既然python2.7这边的库没有动过,自然这边是不必做什么的。那么要处理的就是新编译安装的curl这边的事情。我们要知道安装到哪里去了。因为我没有指定安装的位置,所以一般默认安装到了/usr/local/lib/ (32位和64位系统) 或/usr/local/lib64/(64位系统) 下。只要让新编译安装下的目录的库和python2.7里的site-packages目录下的pycurl.so是一致的就行了。当然,如果保持只有一份也可以,因为这样的话,python在搜索curl库的时候就不会搜索到多份,自然也不会出现时间不一致的问题。其实时间不一致,也大致说明库的代码版本是不一样的。

    

解决方法:
1.删除或重命名 /usr/local/lib/ (32位和64位系统) 或/usr/local/lib64/(64位系统) 下的curl库
2.将python安装时带的版本替换掉系统lib目录下的curl库文件
3.将新编译后的的curl替换掉python里的curl库
    反正只要让两者的库是同一个,就没有问题了。那么我选择了最简单的一个办法,就是将lib目录下的curl库重命名了,避开了冲突。问题就瞬间解决了。虽然现在来看,解决这个问题似乎很简单,但是在排查问题的时候,却花了一个晚上,还有一些细节的尝试就没有记录进来了。考验的是耐心、细心和心理承受力。

        另外要说的一个就是,因为一直以为自己对Linux不熟,然后一遇到安装卸载之类的,就有一种心理阴影,下意识去往这方面去想了,结果走偏了。链接问题无非就是目录不对,版本不对,做个软链之类的,其实这些命令或者安装方法,也不是不知道,只是在没有完全洞悉Linux机制的情况下,心里有点不踏实,总以为是自己不会的地方出问题,往往出问题都是在自己的眼皮底下,都是一些很常见的问题而已。

    

最后总结一下:
    遇到问题需要冷静,需要有较大的心理承受能力,始终要淡定,理性的分析问题的来龙去脉,就和本文从头到尾叙述的寻找分析解决问题一样,自然问题就迎刃而解了。这方面就我自己也需要再锻炼,在心理承受能力和冷静淡定方面,显然比以前都好很多了,临危不乱还是做得比较可以的,冷静分析也是可以的,阴影的影响比较多,这方面心态没有调整好。
    所以,通过这次的问题排查,分析过程中自己的解决问题的心理情况,然后现在客观的分析,增强自己的心理素质。因为以后还有很多未知的问题,只有一颗强大的心才足以抵抗!!而这个过程,也希望给读者一个很好的引导,希望你不要仅仅为了解决问题而解决问题,一定要知道问题所在,这样你才可以真正的学到技术。