赞
踩
今天在运行模块执行文件时,出现了如下报错 "symbol lookup error"、"undefined symbol",提示 cos_getfile_mcd 可执行文件在加载 .so 文件时,出现了无法找到符号的错误,并给出了具体错误:_ZN20CCosGetfileTimerInfoC2Ev 符号未定义。
那么如何定位该错误呢?一般可以先使用 ldd指令 去查看一下可执行文件的链接库,但是我的可执行文件是在加载调用.so文件的过程中出现报错,ldd指令并没有解决我的问题,因此要用的nm指令来定位错误源。那么接着请往下看看 nm指令 介绍。
nm命令主要是用来列出某些文件中的符号(说白了就是一些函数和全局变量等),后端程序员一般需要掌握该指令。
nm指令的参数如下:
- # 指令使用格式
- nm -xx [objfile...]
- # 指令中的-xx即为如下参数列表
- [-a|--debug-syms]
- [-g|--extern-only] //只显示外部符号.
- [-B]
- [-C|--demangle[=style]]
- [-D|--dynamic]
- [-S|--print-size]
- [-s|--print-armap]
- [-A|-o|--print-file-name]
- [-n|-v|--numeric-sort]
- [-p|--no-sort]
- [-r|--reverse-sort] [--size-sort]
- [-u|--undefined-only] //只显示未定义的符号.
- [-t radix|--radix=radix] //符号值得进制。d 十进制, o 八进制, x 十六进制.
- [-P|--portability]
- [--target=bfdname]
- [-fformat|--format=format] //输出的格式,有"bsd","sysv" 或"posix"可选。默认是“bsd”
- [--defined-only] //只显示已定义的符号.
- [-l|--line-numbers] //对每一个符号,使用调试信息去查找文件名和行号
- [--no-demangle]
- [-V|--version]
- [-X 32_64]
- [--help] //显示帮助

nm命令的输出包含三个部分:1)符号值,默认显示十六进制,也可以指定; 2 )符号类型,小写表示本地符号,大写表示全局符号(external),符号类型介绍如下所示;3)符号名称,符号名称前后分别会加上一段拓展名,代表不同的符号类型,例如后面的扩展名D1EV是指的C++析构函数。
输出示例如下。
定位指令如下所示,可以看到结果中红框标注的符号,其类型即为未定义的 U。那么这里就可以确定代码中未定义的符号即为CCosGetfileTimerInfo。
nm -g ../../bin/cos_getfile.so | grep CCosGetfileTime
使用grep指令定位源码中CCosGetfileTimerInfo符号的位置,并定位到cos_getfile_mcd中的位置,之后去源码中查看相关定义使用的具体位置,并进行输出测试(在使用处前后加上测试输出,定位是否在此处出错),接着就可以确定出未定义符号的位置。
grep CCosGetfileTimerInfo *
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。