linux中对象文件的符号表symbols查看工具nm简介

本文介绍了nm工具的作用及其使用方法。nm工具能够列出.o、.a、.so文件等的符号信息,包括符号的值、类型及名称。文中还通过实例演示了如何使用nm工具查看由gcc编译生成的可执行文件中的符号。
部署运行你感兴趣的模型镜像

1.nm工具作用

nm工具列出.o文件、.a文件、.so文件等的符号信息,包括诸如符号的值,符号类型及符号名称等。所谓符号,通常指定义出的函数,全局变量等等。


2.nm的使用方法

nm [option] filename

例如,nm -C a.out


 常用的选项有:

         -A    打印出来的每个符号所属的对象文件的名称

         -C    使用nm工具打印出来的符号名称看不懂,使用-C选项后就可以看懂了。

         

3.使用举例

源程序main.c为:

#include "stdio.h"

int cc = 4;

int func_1(){
        int a = 4;
        int b = 3;
        int c = a + b;

}

int main(){
        int stack_of[100000000];
        int b=1;
        int* a;
        *a=b;
}
使用gcc main.c -o main后生成名称为main的可执行文件。

<span style="color:#660000;">#nm -C main
000000000050087c A __bss_start
00000000004003dc t call_gmon_start
0000000000500878 D </span><span style="color:#ff0000;">cc</span><span style="color:#660000;">
000000000050087c b completed.1
0000000000500688 d __CTOR_END__
0000000000500680 d __CTOR_LIST__
0000000000500860 D __data_start
0000000000500860 W data_start
0000000000400550 t __do_global_ctors_aux
0000000000400400 t __do_global_dtors_aux
0000000000500868 D __dso_handle
0000000000500698 d __DTOR_END__
0000000000500690 d __DTOR_LIST__
00000000005006a8 D _DYNAMIC
000000000050087c A _edata
0000000000500880 A _end
0000000000400588 T _fini
0000000000500680 A __fini_array_end
0000000000500680 A __fini_array_start
0000000000400440 t frame_dummy
0000000000400678 r __FRAME_END__
0000000000400468 T func_1
0000000000500840 D _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
0000000000400370 T _init
0000000000500680 A __init_array_end
0000000000500680 A __init_array_start
0000000000400598 R _IO_stdin_used
00000000005006a0 d __JCR_END__
00000000005006a0 d __JCR_LIST__
                 w _Jv_RegisterClasses
0000000000400510 T __libc_csu_fini
00000000004004b0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400485 T </span><span style="color:#ff0000;">main</span><span style="color:#660000;">
0000000000500870 d p.0
0000000000500680 A __preinit_array_end
0000000000500680 A __preinit_array_start
00000000004003b0 T _start</span>

在上图结果输出中,第一列是符号的值,一般表示内存偏移量,但要视具体的符号类型来决定。第二列时符号的类型,具体各种类型的含义可以参见man nm。第三列是符号名称,例如上面飘红的就是我们定义的全局函数和全局变量的名称。


您可能感兴趣的与本文相关的镜像

TensorFlow-v2.9

TensorFlow-v2.9

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

Linux 环境下调试未导出符号表的函数,可以使用多种工具和方法。以下是详细的解决方案: ### 1. 使用 `objdump` 和反汇编技术 如果目标文件或库中包含调试信息(如通过 `-g` 编译选项生成),可以使用 `objdump` 工具进行反汇编。即使函数未导出符号表,也可以通过地址定位到代码段并分析其逻辑。 例如: ```bash objdump -d obj ``` 这条命令会显示整个目标文件的反汇编代码[^1]。如果目标是特定段,则可以限制为 `.text` 段: ```bash objdump -j .text -d obj ``` 通过结合 `nm` 命令查找符号地址: ```bash nm -C obj | grep <function_name> ``` 如果函数未导出,可以通过地址直接定位到反汇编代码[^2]。 ### 2. 使用 `gdb` 调试未导出符号符号表未导出时,仍然可以通过地址直接调试函数。假设已知函数的地址范围(通过 `nm` 或其他工具获取),可以在 `gdb` 中设置断点: ```bash gdb ./program (gdb) break *0x<address> ``` 这里 `<address>` 是函数的入口地址。运行程序后,`gdb` 将在指定地址处暂停执行[^4]。 如果符号表完全缺失,还可以通过以下方式加载外部符号表: ```bash set debug-file-directory /path/to/symbols ``` ### 3. 结合 `gprof` 分析函数调用 如果需要分析未导出符号的函数调用情况,可以使用 `gprof`。通过在编译时添加 `-pg` 选项,GCC 会在每个函数中插入性能统计代码。尽管未导出符号不会直接出现在报告中,但可以通过地址关联到具体函数[^3]。 ### 4. 使用 `addr2line` 定位源码位置 如果已知函数的内存地址,可以通过 `addr2line` 将地址映射回源代码行号: ```bash addr2line -e obj 0x<address> ``` 这有助于理解未导出符号的具体实现[^2]。 ### 5. 内核态调试工具(如 `kdump`) 对于内核模块或驱动程序中的未导出符号,可以使用 `kdump` 捕获崩溃后的内存镜像,并通过 `/proc/vmcore` 进行分析。虽然 `kdump` 主要用于内核崩溃转储,但它可以提供更深层次的符号解析支持[^5]。 ### 示例代码 以下是一个简单的示例,展示如何通过 `gdb` 调试未导出符号: ```c // test.c void hidden_function() { printf("This is a hidden function\n"); } int main() { hidden_function(); return 0; } ``` 编译时不导出符号: ```bash gcc -o test test.c -fno-ident -s ``` 使用 `gdb` 调试: ```bash gdb ./test (gdb) break *0x<address_of_hidden_function> (gdb) run ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值