nm的全称是names,作用是可以显示二进制文件(通常是库文件和可执行文件)中的符号表。
格式
nm(选项)(参数)
选项
-A:每个符号前显示文件名;
-D:显示动态符号;
-g:仅显示外部符号;
-r:反序显示符号表。
借用别人的一个例子说明一下:
[taoge@localhost learn_nm]$ ls
main.c test.c test.h
[taoge@localhost learn_nm]$ gcc -c test.c main.c
[taoge@localhost learn_nm]$ gcc test.o main.o
[taoge@localhost learn_nm]$ ./a.out
rainy days
[taoge@localhost learn_nm]$ nm *
a.out:
08049564 d _DYNAMIC
08049630 d _GLOBAL_OFFSET_TABLE_
0804849c R _IO_stdin_used
w _Jv_RegisterClasses
08049554 d __CTOR_END__
08049550 d __CTOR_LIST__
0804955c D __DTOR_END__
08049558 d __DTOR_LIST__
0804854c r __FRAME_END__
08049560 d __JCR_END__
08049560 d __JCR_LIST__
0804964c A __bss_start
08049648 D __data_start
08048450 t __do_global_ctors_aux
08048330 t __do_global_dtors_aux
080484a0 R __dso_handle
w __gmon_start__
0804844a T __i686.get_pc_thunk.bx
08049550 d __init_array_end
08049550 d __init_array_start
080483e0 T __libc_csu_fini
080483f0 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
0804964c A _edata
08049654 A _end
0804847c T _fini
08048498 R _fp_hw
08048290 T _init
08048300 T _start
0804964c b completed.5963
08049648 W data_start
08049650 b dtor_idx.5965
08048390 t frame_dummy
080483c8 T main
080483b4 T print
U puts@@GLIBC_2.0
nm: main.c: File format not recognized
main.o:
00000000 T main
U print
nm: test.c: File format not recognized
nm: test.h: File format not recognized
test.o:
00000000 T print
U puts
[taoge@localhost learn_nm]$
从上图可以看出,使用nm命令可以打开.out文件和.o文件(.so文件也可打开),然后列出了符号信息,在符号明前厚一些大小写字母,那么这些字母代表什么意思呢?
答案是字母代表这些符号所在的位置,如“b”代表在未初始化数据区("b" The symbol is in the uninitialized data section (known as BSS).),“D”代表在Data段。。。这些都可以使用man nm命令在Linux中查出来,在此就不赘述了。
本人在工作中用过一次,我是负责后台的,UI在调用我给的.so文件后说有个变量未定义,所以我使用“nm sdk.so | grep xxx”来看这个变量是否被定义。