在Linux中动态库的确给程序带来了良好的扩充性,并减少了内存的使用量,但这是有代价的。例如:

#include

Int main(int argc, char *argv[])

{

Printf(“hello\n”);

Return 0;

}

我们知道printf是在glibc中定义的,如果不适用动态库,而是将glibc静态链接到进程中的话,那么printf函数的地址在编译时就是已知的了,使用很简单的依据地址转移,就可以进行函数调用。

可是如果采用动态库的话,在程序编译阶段,编译器就无法得知printf的函数地址,因为动态库加载的内存地址时随机的。那么对于动态库的情况,针对printf是如何寻址的呢?

在程序运行时,当调用printf的时候,程序会将处理权交给linker,由其负责在执行文件以及其连接的动态库中查找printf的函数地址。由于linker不知道printf具体是在哪个动态库,所以它将在整个执行文件和动态库的范围内查找。更糟糕的是在C++程序中,符号的命名是类名+函数名,这导致在做字符串比较时,往往直到字符串的结尾才能获得结果。

这也就导致了在进程启动过程中,符号查找占据了一大部分时间。在Linux的KDE进程启动中,符号查找甚至占据了进程启动80%的时间。

因此就针对上述的情况,有以下优化解决方案:

1、减少导出符号的数量

在动态库编译和生成时,默认所有的函数和全局变量都是导出的。而实际上有很多函数只是动态库内部使用,通过去掉那些动态库中不必要的导出符号,从而减少动态库在做链接时所查找的符号数量,可以加快动态库链接的速度。

可以使用ld的ld --retain-symbols-file --version-script两个选项实现。写一个导出符号文件,如 symbol 指定你只导出的函数,如 func1。使用 ld 的--retain-symbols-file  参数可以在 static section 里取消 func1 以外的所有函数。这时你用 readelf 看编译好后的 .so 文件 static section 里没有了,使用 nm 看 .so文件它无法查出导出函数。但这并不完全。因为在 dynamic section 里还是会看到所有符号被导出。如果想在 dynsym section 里也不让他导出的话,需要再编写一个 script 文件,指定 global 与 local 在 global 中指定你要导出的函数,简单的格式如下:

VERSION{

VER_1.0{

global: 导出函数名;

local: *;

};

}

再在 ld 时用 --version-script  选项来 load 你的文件。都完事后再使用 readelf 观察static 与 dynamic section 发现只导出了你指定的函数名即符号。

例:

ld -shared --retain-symbols-file  符号文件 --version-script  脚本文件 -o 动态库文件。so filename

2、减少符号的长度

3、使用prelink

在这里另外在提一个问题,很有趣的东西。

gcc -fvisibility=hidden 只在链接时传入的.c文件起作用,对.o文件不其作用;

比如test.c test1.c,使用以下命令:

gcc -shared -fvisibility=hidden -otest.so test.c test1.c

和命令

gcc -c test.c test1.c

gcc -shared -fvisibility=hidden -otest.so test.o test1.o

生成的test.so中的对应可见性是不一样的,使用“readelf -s test.so”查看发现:

第一个达到预期目的,即将两个.c文件中的functions设为HIDDEN,

而第2个则不行,-fvisibility=hidden不起作用;

再用gcc -shared -fvisibility=hidden -o test.so test.o test1.c

生成的so,则可发现test1.c中的函数为HIDDEN,但test.o中的函数仍为DEFAULT;

linux查看动态库导出的符号,Linux下控制动态库导出相关推荐

  1. linux查看端口被占用且释放,Linux查看端口占用情况,并强制释放占用的端口

    1.查找被占用的端口 netstat -tln netstat -tln | grep 8080 netstat -tln 查看端口使用情况,而netstat -tln | grep 8080则是只查 ...

  2. linux 查看 man 路径配置文件 man.config,linux man 1,2,3....

    Linux的man很强大,该手册分成很多section,使用man时可以指定不同的section来浏览,各个section意义如下: 1 - commands 2 - system calls 3 - ...

  3. linux查看磁盘分区恢复磁盘,在Linux,误删磁盘分区怎么恢复呢【转】

    在我们运维工作中,频繁的操作,可能命令写入错误,造成磁盘分区的删除,那么应该怎么办呢?怎么恢复磁盘分区呢? 一不小心删除了磁盘分区.如下图,删除了sda磁盘的第一个分区,为系统boot分区,系统如果重 ...

  4. linux查看通道的命令,10个Linux新手必须记住的Linux基本命令,快速入门通道!!...

    原标题:10个Linux新手必须记住的Linux基本命令,快速入门通道!! Linux 作为免费操作系统,与 Windows.OS x 齐名.比起后两者,Linux 显得很低调,低调得不少人都以为自己 ...

  5. linux查看内存空间分配情况,也看linux内存去哪儿了

    前两天一台128G内存的oracle主机发生故障触发kdump,最终由于var目录空间不足,导致kdump生成不完全.结合之前redhat给出的建议,crash设置的空间最好大于memory 空间.对 ...

  6. linux查看防火墙有没关闭了,linux查看防火墙是否关闭的实例方法

    linux查看防火墙是否关闭的实例方法 一.service方式 查看防火墙状态: [root@centos6 ~]# service iptables status iptables:未运行防火墙. ...

  7. linux查看日志的几种命令,Linux查看日志三种命令(转载)

    第一种:查看实时变化的日志(比较吃内存) 最常用的: tail -f filename (默认最后10行,相当于增加参数 -n 10) Ctrl+c 是退出tail命令 其他情况: tail -n 2 ...

  8. linux怎么打出管道命令这个符号,linux 管道命令 竖线 ‘ | ’

    管道符号,是unix功能强大的一个地方,符号是一条竖线:"|", 用法: command 1 | command 2 他的功能是把第一个命令command 1执行的结果作为comm ...

  9. linux查看usb3.0还是2.0,Linux分辨电脑是否有USB 3.0接口的命令行 怎么看电脑用独立显卡还是集成显卡...

    延伸:怎么看电脑用独立显卡还是集成显卡 描述:方法一.通过接口来判断我们在主机箱后面的接口上,看你的链接数据线的接口接上了哪个接口,如果是连接集成显卡的话那就是连接到竖的的接口上,因为集成显卡的VGA ...

最新文章

  1. 13、MySQL比较运算符
  2. Google发布用于Google Cloud的.Net API
  3. python线程退出_python子线程退出及线程退出控制的代码
  4. 史上最神奇的公式,竟然藏着这么多秘密!
  5. Winform登录窗体登录仿asp.net验证成功后进入主界面
  6. mysql简单聚合函数根据条件单表查询
  7. Spring Boot 文件上传功能实现与简单示例
  8. 分布式链路追踪工具skywalking 介绍
  9. LIRe提供的6种图像特征描述方法的评测
  10. 13.C++ vector 操作
  11. vim个性化设置---给脚本文件加注释头信息
  12. 免费搭建私人云盘+内网渗透+不限速无限存储
  13. python 经典图书排行榜_书榜 | 计算机书籍(8.26-9.1)销售排行榜
  14. Exception:No serializer found for class and no properties discovered to create BeanSerializer
  15. ubantu14.04搜狗拼音安装
  16. 数据结构实验-稀疏一元多项式计算
  17. STM32G070CBTx使用LL库原生I2C读取FM24C04D
  18. if和for的几个经典题目
  19. 【前端实例】Html网页开启全屏功能
  20. 23个机器学习最佳入门项目!(附数据+源代码)

热门文章

  1. python去哪里学-杭州python编程入门去哪学?
  2. cmd切换python版本-cmd 切换python版本
  3. 怎么在python下载网站内容-Python下载网页的几种方法
  4. python主要运用于-python主要应用领域有哪些?看这一篇就够了
  5. python切片语法-Python切片符号(:)用法及示例
  6. python介绍和用途-python匿名函数的介绍及用途
  7. linux下载哪个python版本-修改linux下python的默认版本
  8. python学习手册中文版免费下载-Python学习手册(第3版)
  9. python安装教程3.8.5-[分享栈]centos7安装python3.8.5
  10. pycharm如何在程序运行后查看变量的值,变量的类型(不通过print和debug的方式)