查看so库中是否有某个定义_论Linux ELF中动态库符号重定义利用 属性/Linker 做隐藏的手法...

假如libgetthree.so libgetseven.so , 同时这两个so内部都用了internal_do_calculation()函数,并且各自定义了自己的internal_do_calculation()的实现,你会想当然的认为他们各自不影响,libgetthree和libgetseven会分别用自己的internal_do_calculation(),但事与愿违,你会发现都只会用其中一个so的符号

他经历的过程如下:

  1. 当exe执行的时候,他会去寻找PublicGetThree符号,于是dynamic loader就会在libgetthree.so种进行reslove
  2. 当exe执行的时候,他会去寻找PublicGetSeven符号,于是dynamic loader就会在libgetseven.so种进行reslove
  3. 接下来开始寻找internal_do_calculation符号,他发现在libgethree.so中有,于是就全部用他的了

于是你会发现,libgetseven.so用的是其他库的这个符号,错误就产生了。取决于你怎么链接顺序,经过测试,发现跟第一个库的顺序有关

489a449c2998d70e4165b30192273deb.png

但是如果我们一旦隐藏比如three.cpp的符号

0db912f710fc93307584df92fd4afc83.png

我们再重新链接,发现就正常了

d52692f2c606415af33ba1e04a618721.png

可以总结出如果你对某个so库中的符号做了hidden,他实际上有两个作用:

  1. 对于自己来说,他告诉这个动态库对于这个符号不能从其他库中去读取,只能读取自己的这个internal符号(-Bsymbolic / -Bsymbolic-functions仅仅起到这个第一个作用)
  2. 对于其他库来说,这个库中的这个符号被隐藏了,自然只能用自己的符号了

通过上面这两个效果,你可以发现,无论你是hidden libgetthree.so还是libgetseven.so都是work的。

除了以上的好处之外,如果你控制得体,比如全局使用-fvisibility=hidden,对对应的public API使用__attribute__((visibility("default")))来暴露,这样有以下额外的好处:

  1. 你的库的load time会减少
  2. 你的整体的运行speed会提高,因为编译器知道他可以对devirtualization / inline functions做额外的优化
  3. 你的shared library的size大小会减小,因为编译器会从exported symbols table中丢失hidden symbols

坏处:

他会让你做单元测试更加困难,因为你已经把你的内部实现符号都给隐藏了,因此当你做unit testing的时候,你需要用default visibility来重新build.你可以借此来重新配置你的debug / release build flags:

Debug:

  • -g - 加上debug info
  • -O0 - 不提供任何优化(可以提供在开发阶段的debug使用体验)

Release:

  • -fvisibility=hidden - 上面说的,可以提高效率
  • -O2 - 优化大小和提高速度

有一个需要注意的地方就是关于异常C++ Exceptions,当binary code捕获住了一个exception的时候,他需要typeinfo的查找,但是typeinfo的symbols会随着你本身symbols的hidden而hidden.

通过linker的-Bsymbolic / -Bsymbolic-functions同样可以解决上面的问题(gcc是要加上-Wl,-Bsymbolic),比如你可以用如下的命令来进行编译

78de852aa2fe80733f56cd5e0cb41163.png

他会带来正确的结果:

f18a5bfd0028d62e506f639235612c1a.png

但是如果那他跟hidden visibility做比较的话还是有诸多缺点:

  1. -Bsymbolic的方式仍然会export他们的符号,因此可以认为他们只解决了我们上面提到的两个作用的第一个作用,因此仍然有可能其他库会去使用他,如果我们交换了libseven.so以及libthree.so的位置,可能就会出现问题
5a4a3116e3ac6688e5b3e0a720ce877d.png
d9394887e9c4b41edb5882c9086515f2.png
  1. hidden visibility比-B的方式优化了对应的空间以及提高了运行速度
  2. 也不是说-Bsymbolic没有任何好处,他相对hidden visibility的手法让你写单元测试的时候只需要进行一次库的编译

除了以上提供的方法之外,你还能利用-fvisibilty=protected来达到效果,他跟hidden类似,可以保护你当前shared library的库的符号不会被其他库方便,但是他不保证你的库会去污染其他库的符号表,比如我们来看例子:

3b06d17459112865f785a0cc40ac3778.png

这个情况下是OK的,因为我们保护了Seven本身,因此他的内部符号只会用自己的

我们来看另外一个例子

2418db0bf18a4f6bbe09a8b36501c5f2.png

这就出问题了,因为我们虽然保护了three本身,但是他的符号也确实污染到了libseven.so,因此输出了3

你也可以通过匿名空间来达到效果

1a41592bb6f801b5f92027765cacd42b.png

注意不要把你的public API也给包了,仅仅包你的实现,然后你通过nm查看发现他们默认变成小t了

a679bbe1c82b6b52a8d774ce189bfd98.png

但是如果你不用匿名空间,而是带名字的空间,他是大T的会做污染

242af3b41ba2013d603718ce9b1fbc85.png

因此可以看到匿名空间的一个作用就是自动帮你把符号隐藏. 同样,如果你的函数定义成static静态的,你的函数符号默认也是hidden的,也能起到同样的效果

Dynamic Linking解决相关问题:

试想一下如果你的library A和B都对C有依赖,其中A用的是新的C,B用的是老的C。这里面可能存在数据结构的不一致,就会出现问题,但是正是因为有了dynamic linking,如果A和B对于major version的C是兼容的,那么dynamic linking会帮你解决这个问题,因为他们所有遇到过的C的符号通过上面的解释,都会保持一致,因为有override的行为在里面。 但是并不是说dynamic linking就是万能解药,静态编译static linking的一个原因就是拥有尽可能小的分发依赖。 另外一个原因就是你要测试所有版本的依赖非常困难,通过静态编译到一个特定的版本允许让你拥有这个依赖的一致行为

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/552285.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为新系统鸿蒙能互通吗,「连接」万物的鸿蒙,能拯救华为手机吗?

为 IoT 而生的鸿蒙操作系统,其优势与特点几乎都是围绕「万物互联」展开的。在曝光两年之后,华为的鸿蒙系统终于正式和用户见面了。6 月 2 日,华为鸿蒙操作系统及华为全场景新品发布会开启,正式推出 HarmonyOS 2.0,并发…

dw中html颜色的设置颜色代码,Dreamweaver 如何编辑字体大小颜色

以下为学做网站论坛关于“Dreamweaver 如何编辑字体大小颜色”讲解视频教程。dreamweaver是个可视化的软件,你直接选中你要更改的设置,在编辑器中直接就可以更改了。或是用CSS也可以设置你说的那些内容字体大小、颜色样式。dreamweaver编辑字体大小、颜色…

html 图片position,【图解CSS#Position】

关于CSS position,来自MDN的描述:CSS position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left 属性则决定了该元素的最终位置。先看一个图片:child没设置position的样式代码如下:child1-1child1-2child1-3chi…

佳能g3800故障灯说明书_佳能打印机故障如何维修 佳能打印机故障维修方法【介绍】...

在现代办公中是离不开打印机的,一些办公文件都是需要用它来打印的,也因此在办公中的地位是很重要的。也正因此它要是出现了故障,会给我们带来很大的麻烦,很是影响工作进度。佳能是很知名的,即使是这样,它在…

ll微信2下载安装_【兰苑文学】:陈振 ll黄金槐

作者简介陈振,新余市作协会员,江西省优秀乡村教师,中国网络诗歌学会会员。作品见于《诗选刊》《诗歌月刊》《诗潮》《鸭绿江》《诗人》《作家报》《长江诗歌》《海口日报》印尼《千岛日报》和《2018江西诗歌年选》《中国民间短诗精选》《中国…

无法扩展该卷 因为群集的数量将超过文件系统_浏览器将支持Python项目!Mozilla发布Pyodide...

作者|Michael Droettboom 编译|王强、覃云 近日,Mozilla 发布了一个实验项目 Pyodide,旨在浏览器内运行一个完整的 Python 数据科学堆栈。链接:https://github.com/iodide-project/pyodide/Pyodide 的创意起源于 Mozil…

华锋e路航x10升级工具_万商云集:疫情下火爆的电子合同,背后是企业数字化升级的必然...

近年来,数字经济快速发展成为中国经济发展的新动能,作为企业数字化转型中非常重要的一环,电子合同也随着产业数字化程度的加深快速渗透到各行各业,万商云集早在去年年底就已经正式拥抱电子合同,助力客户实现数字化升级…

edge播放视频HTML5黑屏,Win10 edge浏览器播放视频黑屏解决方法

Edge看不了视频怎么办呢? 出现这样的问题是由于Edge浏览器中需要点击允许才能看视频,但如果不弹出提示窗口我们就无法正常观看视频,所以当我们遇到这样的情况可以按下面方法进行操作!Edge看不了视频解决步骤:1、按下winR 组合键打开运行&…

@async 如何返回list_图解 Await 和 Async

原文链接:Await and Async Explained with Diagrams and Examples文章目录简介Promise问题:组合 PromiseAsync 函数Await错误处理讨论简介JavaScript ES7中的 async/await 使得协调异步 promise 变得更容易。如果你需要从多个数据库或 API 异步获取数据&…

求一个向量变换为另一个向量的矩阵_OpenGL里旋转等变换矩阵为什么是4x4的矩阵...

OpenGL ES 的很多教程里都会有这样一个例子来讲解纹理:将一张图片作为纹理显示在屏幕上。因为纹理坐标和实际屏幕显示的坐标不一样,把图片渲染在屏幕上后,图片是上下颠倒的。一个解决方法是对当前的顶点坐标,乘以绕 z 轴旋转180度…

白鹭时代与html5关系,白鹭时代观点:HTML5行业将进入红利收割期

2016年,H5产业风风火火,各种引人注目。最大成果无疑是游戏《传奇世界H5》月流水破了3000万,引起整个行业巨大震动,同时,也标志着H5重度游戏时代来临。国内最大的HTML5移动技术与服务供应商白鹭时代认为,201…

boot定时任务开启和关闭 spring_Spring之定时任务实践

Java下的定时任务实现有Timer,Spring,QuartZ等,这里我们介绍Spring中定时任务的应用,其通过 Scheduled 注解即可轻松实现概述Spring 的定时任务可以支持各种形式的定时调度任务。其通过加在定时方法上的 Scheduled 注解来配置任务…

计算机怎么取消用户密码,怎么取消开机密码:计算机开机进入Windows时的开机密码怎么取消?...

优质回答 回答者:168长腿欧巴在电脑中的“用户账户”界面即可设置取消开机密码,具体操作请参照以下步骤。1、右键Win10系统的开始菜单,选择弹出菜单里的“运行”选项。2、然后在出现的运行对话框里输入命令“netplwiz”,点击确定。…

echarts symbol 回调函数_【OpenLayer 实战】实现仿Echarts风格的动态迁徙图/航班图

使用的数据还是来自echarts,模拟了全国各地到湖南重点景区的客流情况。分析要实现动态迁徙图的效果,主要需解决两个问题 曲线的绘制。因为给出的数据只有起点和终点两个点位,所以想要绘制曲线可以参考turf中的bezier曲线生成API。 点迹…

校运会计算机科学系大本营,计算机系团总支学生会学期总结大会

(本网讯)时光飞逝,又一个学期即将就此画上了圆满的句号。为推动我系团总支学生会工作更长久的发展,提高学生会干部工作的热情和质量,2016年12月8日晚上19:00在第一教学楼C102课室里,校学生会全体成员齐聚一堂,参加了20…

hexo评论_【前端简历加分】hexo框架搭建个人博客站点,手把手教学

最近,粉丝们在金九银十期间也是不断的面试,有比较多的毕业生说我在这个期间出多一些面试题,上几期都是倾向于面试文章,这期出一次简历加分项操作,使用hexo框架搭建个人博客。作为应届毕业生或者1-3年工作经验的程序员拥…

电脑抓整个路由器的包_网络是电竞游戏体验的命脉 2018年年度电竞路由器功能盘点...

2018年是电竞路由器的元年,从2017年的概念产品诞生开始,电竞路由器很快就确定了品类,随着《绝地求生》、《王者荣耀》等对网络质量敏感的竞技游戏的火爆,电竞路由器迅速被竞技玩家熟知,并在2018年以野火燎原的速度发展…

dos 改某个目录下所有文件的时间_go语言入门学习笔记(2)-DOS操作及go语言变量学习...

API:application program interface:应用程序编程接口。就是我们go的各个包的各个函数。我们想要了解这些函数我们可以通过Go的中文网在线标准库文档:https://studygolang.com/pkgdocDOS介绍:Dos:Disk Operating System 磁盘操作系…

es multi match_PHP 的ES搜索操作

原文:https://blog.csdn.net/JineD/article/details/106650695首先从ES的支持的字段说起,ES文档中字段有多种类型 官方文档。这几个比较常用:text,keyword,integer,float,boolean,object,geo_point(地理坐标),geo_shape(描述地理区域),date.注…

git 怎么还原历史版本_4. Git--修改/回退等操作

》》点赞,收藏关注,理财&技术不迷路《《我们已经成功地添加并提交了一个readme.txt文件,现在,是时候继续工作了,于是,我们继续修改readme.txt文件,改成如下内容:Git is a distri…