需求描述:业务提供一个鉴权的静态库,我只需要从url 和 参数中提取相应的参数传给业务的静态库,将静态库的处理结果直接返回给业务(return < 0, 直接返回403)。
创新互联建站专注为客户提供全方位的互联网综合服务,包含不限于成都做网站、成都网站制作、成都外贸网站建设、白塔网络推广、微信小程序开发、白塔网络营销、白塔企业策划、白塔品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们大的嘉奖;创新互联建站为所有大学生创业者提供白塔建站搭建服务,24小时服务热线:028-86922220,官方网址:www.cdcxhl.com但是最近业务反馈,请求部分url直接返回Error:-1015错误,不符合预期。
业务刚开始反馈问题,我的第一反应:怎么可能是我的问题,我就仅仅写了一个so(暂时命名1.so),直接调用了你们静态库,这个-1015不就是你们库返回的结果。 有问题也是业务提供的库有问题。 或者就是业务配置不正确。
我临时解决方案:
最后还是走到方案3,业务说printf的结果不符合预期,经业务提醒,突然意识到是不是调用链接到其他库的xx_func?
因为项目比较大, 涉及的库比较多,我用nm认真检查了编译时加载的库,竟然还真找到一模一样的接口xx_func
nm ./lib/liba.a | grep xx_func
编译代码的时候,赶紧去掉了同名函数库(因为在makefile文件编译的时候某些公共库默认都会编译进去)。重新编译版本。
没有想到,去掉同名函数库,还是存在问题,为什么呢?到底是哪里的问题?
随手直接 nm *.so | grep xx_func
,结果在另外一个so(暂时命名2.so)中,发现了同名函数xx_func。 看了一下配置,程序启动的时候首先加载了2.so动态库, 1.so是在2.so后面加载的. 因为优先加载哪个库,就使用哪个库的同名函数,并不会覆盖的情况(自己现网测试 + 测试代码)
到这里问题的原因也算是找到了,下面接着就是如何解决问题?
因为业务本身提供的静态库,用nm
查看函数也不多,为了安全起见,修改每个函数的名称(增加一些业务私有的东西)。 批量修改函数名可直接使用sed
现在C/C++这一块有几十年的历史,该踩的坑大家都应该踩过去了。gcc编译器就直接提供-fvisibility=hidden
编译选项,直接让库函数global可见变成local可见, 使用__attribute__((visibility("default")))
直接将需要的函数暴漏在外面就行
-fvisibility=[default|internal|hidden|protected]
Set the default ELF image symbol visibility to the specified option---all symbols are marked with this unless overridden within the code. Using this feature can very substantially improve linking and load times of shared object libraries, produce more optimized code, provide near-perfect API export and prevent symbol clashes. It is strongly recommended that you use this in any shared objects you distribute.
A good explanation of the benefits offered by ensuring ELF symbols have the correct visibility is given by "How To Write Shared Libraries" by Ulrich Drepper (which can be found at <http://www.akkadia.org/drepper/>)---however a superior solution made possible by this option to marking things hidden when the default is public is to make the default hidden and mark things public.将默认ELF符号可见性设置为指定选项---除非在代码中覆盖,否则所有符号都标记为此。 使用此功能可以极大地改善共享对象库的链接和加载时间,生成更优化的代码,提供近乎完美的API导出并防止符号冲突。 强烈建议您在分发的任何共享对象中使用它
Ulrich Drepper的“如何编写共享库”(可在<http://www.akkadia.org/drepper/>上找到)中给出了确保ELF符号具有正确可见性所带来的好处的一个很好的解释 - - 当默认为公共时,通过此选项可以标记隐藏的内容的优秀解决方案是隐藏默认值并将事物标记为公共
.
├── libqqmusic.c
├── libtmemusic.c
├── main
├── main.c
├── makefile
└── README.md
//libqqmusic.c
#include<stdio.h>
int get_music_id()
{
return 1111;
}
void qqmusic_print()
{
printf("qqmusic id: %d\n", get_music_id());
return;
}
//libtmemusic.c
#include<stdio.h>
int get_music_id()
{
return 2222;
}
void tmemusic_print()
{
printf("tmemusic id: %d\n", get_music_id());
return;
}
//main.c
#include<stdio.h>
int main(int argc, char *argv[])
{
printf("start\n");
tmemusic_print();
qqmusic_print();
tmemusic_print();
printf("end\n");
return 0;
}
# 1. create /etc/ld.so.conf.d/vaynedu-test.conf
# /usr/lib64/vaynedu
# 2. mkdir /usr/lib64/vaynedu
#
# 3. \cp *.so /usr/lib64/vaynedu
all:
gcc -g -fpic -c -o libqqmusic.o libqqmusic.c
gcc -g -shared -o libqqmusic.so libqqmusic.o
gcc -g -fpic -c -o libtmemusic.o libtmemusic.c
gcc -g -shared -o libtmemusic.so libtmemusic.o
\cp *.so /usr/lib64/vaynedu
@ldconfig
#gcc -g -o main main.c -L. -lqqmusic -ltmemusic
gcc -g -o main main.c -L. -ltmemusic -lqqmusic
@echo -e "\n\ncompile complete\n\n"
clean:
rm -fr *.so *.o
将tmemusic放在前面gcc -g -o main main.c -L. -ltmemusic -lqqmusic
将qqmusic放在前面gcc -g -o main main.c -L. -lqqmusic -ltmemusic
《程序的自我修养-链接、装载与库》应该好好的啃一遍, 这个一个后台开发必备的知识技能
-fvisibility=hidden的用法 https://blog.csdn.net/caspiansea/article/details/77113066
多共享动态库中同名对象重复析构问题的解决方法 https://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/
GCC的符号可见性——解决多个库同名符号冲突问题 http://blog.chinaunix.net/uid-27875-id-5759441.html
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
当前名称:记录一次采坑--如何处理Linux动态库同名函数?-创新互联
网页网址:https://www.cdcxhl.com/article40/dejdho.html
成都网站建设公司_创新互联,为您提供服务器托管、手机网站建设、网站营销、网页设计公司、网站导航、品牌网站设计
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联