函数库文件中的符号表-nm命令
来源:互联网 发布:php环境 编辑:程序博客网 时间:2024/05/16 04:54
nm命令可以列出一个函数库文件中的符号表。它对于静态的函数库和共享的函数库都起作用。对于一个给定的函数库,nm命令可以列出函数库中定义的所有符号,包括每个符号的值和类型。还可以给出在原程序中这个函数(符号)是在多少行定义的,不过这必须要求编译该函数库的时候加“-l”选项。
关于符号的类型,这里我们再多讨论一下。符号的类型是以一个字母的形式显示的,小写字母表示这个符号是本地(local)的,而大写字母则表示这个符号是全局的(global,externel)。一般来说,类型有一下几种:T、D、B、U、W。各自的含义如下:T表示在代码段中定义的一般变量符号;D表示时初始化过的数据段;B表示初始化的数据段;U表示没有定义的,在这个库里面使用了,但是在其他库中定义的符号;W,weak的缩写,表示如果其他函数库中也有对这个符号的定义,则其他符号的定义可以覆盖这个定义。
如果你知道一个函数的名字,但是你不知道这个函数在什么库中定义的,那么可以用mn的“-o”选项和grep命令来查找库的名字。-o选项使得显示的每一行都有这个函数库文件名。例如,你要查找“cos”这个是在什么地方定义的,大致可以用下面的命令:
nm libUserDecorate.so -A -l 2> /dev/null |grep init_cnf
libUserDecorate.so:0002e476 T _ZN3ZBP18UserDecorateServer8init_cnfEPKc /data/home/macky/svn/isd_qqvipserver_rep/Decorate_proj/trunk/operate_server/src/main/user_decorate_server.cpp:76
关于nm的更详细的用法:man nm
转同事steven的一篇故障定位文章:
上线通知存在两个问题:
1, 共享内存泄漏
2, 共享内存attach后没有dettach。上线通知对共享内存的使用比较特殊,会在各个函数中调用attach以使用共享内存。这样,在每次使用后没有dettach的后果是:shm的nattach数量不断递增,到一定程度导致程序core。这个问题查了好久也没有查出原因,之前在析构函数中加printf,发现根本没有调用析构函数。在打算修改共享内存的使用方法时(共享内存只在启动时attach,避免在功能函数中attach),still大师帮忙找出问题的关键所在。
下面分别谈谈这两个问题的分析与定位。
1, 共享内存泄漏定位
Ø 在出问题的机器上查看共享内存使用情况,用ipcs –m查看结果存在大量如下共享内存段:
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 1835059 user_00 600 204800 0
0x00000000 1867828 user_00 600 20 0
Shm的key为0,大小固定。
Ø 在开发机上启动程序时统计大小为204800的共享内存块的个数。ipcs -m|grep 204800|wc –l,发现每启动一次,个数增加1.
Ø 查看上线通知进程id
Ø 查看各个进程的共享内存使用情况:
为便于显示,省略时间戳信息。
1) Cache_main进程:
2) Notify_worker进程id为11639)
主角出现,该worker使用了大小为204800的shm块,并且key为0.
3) Weihu_worker(进程id为11637)
发现只用到了一个16M的shm,为worker与proxy之间的shm。
Ø 结论:Notify_worker进程每次启动时都会创建一块shm大小为204800的共享内存块。到初始化函数中检查,并无对应的创建过程;后来比对与以前版本的区别发现之前版本有对应的创建过程,这个是由于自己注释掉之后没有立即重新编译,后来忘记了这事:(
以后使用共享内存要多注意检查!!!
2, 共享内存attach后没有dettach,导致core。
首先,查看进程中析构函数的汇编码。执行gdb cache_main
disassemble main,出现很多信息,找到如下关注信息:
反汇编CShmQueue,如下:
继续反汇编~CShmQueue,如下:
发现该函数为空函数,按照代码逻辑来说该函数应该去析构其成员CShm和CSem对象,从而dettach共享内存。进而推测该函数在链接成共享内存时被替换。
写一个简单的脚本对所有的静态库进行反汇编并利用CShmQueue过滤结果,发现libcredence2.a中有如下显示:
发现该~CShmQueue为T,强类型函数。
再看看我们自身的析构函数,使用nm -C CNotitySvr.o |grep CShmQueue 查看如下:
发现该~CShmQueue为W,弱类型函数,因为我们的析构函数是内联函数。
也可以查看更详细信息如下,确定这个析构函数是我们自身的:
注意:如果在CShmQueue实现的静态库中用nm是查不到内联析构函数的,只有在使用这个类的目标文件中可以查到。
最后,确定我们的~CShmQueue是被libcredence2.a中同名析构函数覆盖,之所以编译时候没有警告或者错误提示,是因为我们的析构函数是内联函数。
解决方法:
Ø 使用命名空间对类的作用域进行限制。
Ø 以后类实现时,构造函数和析构函数尽量放在源文件中,或者用特定的名字空间进行限制。
延伸阅读(库文档的开发与使用)http://www.cppblog.com/amazon/archive/2010/01/12/105471.html
- 函数库文件中的符号表-nm命令
- nm命令 查看符号文件
- nm命令查看库文件的符号
- 符号表,nm命令,EXPORT_SYMBOL 与 EXPORT_SYMBOL_GPL
- 符号表,nm命令,EXPORT_SYMBOL 与 EXPORT_SYMBOL_GPL
- Mac平台下使用nm命令查看文件的符号表
- 查看.o, .obj文件符号列表,强大的nm命令
- #nm 命令 列出目标文件的符号清单
- 查看.o, .obj文件符号列表,强大的nm命令
- 【Linux】文件中符号分析命令strings 和 nm
- nm命令与符号说明
- 查看库中的符号nm
- C/C++ -- Lib库文件nm调试之符号表
- C/C++ Lib库文件nm调试之符号表
- C/C++ -- Lib库文件nm调试之符号表
- nm命用于显示二进制目标文件的符号表
- nm命令中符号类型详解
- nm命令显示的符号类型
- C#组合算法
- php中获取当前时间
- baidu域名被劫持
- C#-explicit 和 implicit 的含义
- VC 中断点 无效 我把->组建->删除,就好了,
- 函数库文件中的符号表-nm命令
- hibernate.hbm.xml
- VC中CString,int,string,char*之间的转换 转载别人的加了点点自己的
- 计算机科学专业必读的44册经典著作
- (转)inux indent 命令详解
- Google搜索 入门 2
- 奉贤 美食餐饮
- 其实想中奖一点都不难!
- MQ配置和编程最佳实践