linux中的nm命令简介
2015-07-27 21:45
579 查看
一般来说, 搞linux开发的人, 才会用到nm命令, 非开发的人, 应该用不到。 虽然nm很简单, 但是还是有必要写几句, 聊表心意。
nm不是ni ma的缩写, 当然, 也不是ni mei的缩写, 而是names的缩写, nm命令主要是用来列出某些文件中的符号(说白了就是一些函数和全局变量等)。 下面, 我们一起来看看。
test.h为:
test.c为:
main.c为:
继续看nm能否读取目标文件和可执行文件:
我们继续看静态库和动态库, 如下:
好, 我们再来看看全局变量的情形, 我们把main.c改为:
我们还应该注意到, 在上面看不到"good", 为啥呢? 因为nm是用来看szTest而非"good"的。 别忘了, 我们之前介绍过的strings命令可干这事, 如下:
nm命令主要列出特性文件中的符号信息, 具体更加详细的用法, 请问man, 我就不再过多介绍了。
nm不是ni ma的缩写, 当然, 也不是ni mei的缩写, 而是names的缩写, nm命令主要是用来列出某些文件中的符号(说白了就是一些函数和全局变量等)。 下面, 我们一起来看看。
test.h为:
void print();
test.c为:
#include <stdio.h> #include "test.h" void print() { printf("rainy days\n"); }
main.c为:
#include "test.h" int main() { print(); return 0; }好, 我们看看nm命令的作用效果, 如下:
[taoge@localhost learn_nm]$ nm * nm: main.c: File format not recognized nm: test.c: File format not recognized nm: test.h: File format not recognized [taoge@localhost learn_nm]$ni ma, 啥都没有, 这说明nm对这类文件无用。
继续看nm能否读取目标文件和可执行文件:
[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]$可以看到, 对于目标文件和可执行文件而言, 均可以获得其中的函数, 如print函数。
我们继续看静态库和动态库, 如下:
[taoge@localhost learn_nm]$ ls main.c test.c test.h [taoge@localhost learn_nm]$ gcc -c test.c [taoge@localhost learn_nm]$ ar rcs libtest.a test.o [taoge@localhost learn_nm]$ gcc -shared -fPIC -o libtest.so test.o [taoge@localhost learn_nm]$ ls libtest.a libtest.so main.c test.c test.h test.o [taoge@localhost learn_nm]$ nm lib* libtest.a: test.o: 00000000 T print U puts libtest.so: 000014bc a _DYNAMIC 00001590 a _GLOBAL_OFFSET_TABLE_ w _Jv_RegisterClasses 000014a8 d __CTOR_END__ 000014a4 d __CTOR_LIST__ 000014b0 d __DTOR_END__ 000014ac d __DTOR_LIST__ 000004a0 r __FRAME_END__ 000014b4 d __JCR_END__ 000014b4 d __JCR_LIST__ 000015a4 A __bss_start w __cxa_finalize@@GLIBC_2.1.3 00000440 t __do_global_ctors_aux 00000350 t __do_global_dtors_aux 000014b8 d __dso_handle w __gmon_start__ 00000419 t __i686.get_pc_thunk.bx 000015a4 A _edata 000015ac A _end 00000478 T _fini 000002ec T _init 000015a4 b completed.5963 000015a8 b dtor_idx.5965 000003e0 t frame_dummy 00000420 T print U puts@@GLIBC_2.0 [taoge@localhost learn_nm]$可以看到, 我们可以从静态库和动态库中获取到函数名称, 如print函数。
好, 我们再来看看全局变量的情形, 我们把main.c改为:
#include <stdio.h> int add(int x, int y) { return x + y; } int aaa; int bbb = 1; char szTest[] = "good"; int main() { int ccc = 2; return 0; }然后用nm分析a.out(注意, 如果只有nm命令, 则默认a.out为其要处理的文件):
[taoge@localhost learn_nm]$ ls main.c [taoge@localhost learn_nm]$ gcc main.c [taoge@localhost learn_nm]$ ./a.out [taoge@localhost learn_nm]$ nm a.out 08049538 d _DYNAMIC 08049604 d _GLOBAL_OFFSET_TABLE_ 0804847c R _IO_stdin_used w _Jv_RegisterClasses 08049528 d __CTOR_END__ 08049524 d __CTOR_LIST__ 08049530 D __DTOR_END__ 0804952c d __DTOR_LIST__ 08048520 r __FRAME_END__ 08049534 d __JCR_END__ 08049534 d __JCR_LIST__ 08049628 A __bss_start 08049618 D __data_start 08048430 t __do_global_ctors_aux 08048310 t __do_global_dtors_aux 08048480 R __dso_handle w __gmon_start__ 0804842a T __i686.get_pc_thunk.bx 08049524 d __init_array_end 08049524 d __init_array_start 080483c0 T __libc_csu_fini 080483d0 T __libc_csu_init U __libc_start_main@@GLIBC_2.0 08049628 A _edata 08049634 A _end 0804845c T _fini 08048478 R _fp_hw 08048274 T _init 080482e0 T _start 08049630 B aaa 08048394 T add 0804961c D bbb 08049628 b completed.5963 08049618 W data_start 0804962c b dtor_idx.5965 08048370 t frame_dummy 080483a2 T main 08049620 D szTest [taoge@localhost learn_nm]$可以看到, 不仅有add函数, 还有全局变量aaa, bbb和szTest, 要注意, aaa是未初始化的, 所以在Bss段, 而bbb、szTest是初始化了的, 所以在Data段。 值得注意的是, 并没有ccc, 因为ccc是局部变量, nm看不到的。
我们还应该注意到, 在上面看不到"good", 为啥呢? 因为nm是用来看szTest而非"good"的。 别忘了, 我们之前介绍过的strings命令可干这事, 如下:
[taoge@localhost learn_nm]$ ls a.out main.c [taoge@localhost learn_nm]$ strings a.out /lib/ld-linux.so.2 __gmon_start__ libc.so.6 _IO_stdin_used __libc_start_main GLIBC_2.0 PTRh [^_] good [taoge@localhost learn_nm]$
nm命令主要列出特性文件中的符号信息, 具体更加详细的用法, 请问man, 我就不再过多介绍了。
相关文章推荐
- Linux Mint---ATI显卡驱动安装篇
- linux 系统中的64种信号
- Linux信号(signal) 机制分析
- CentOS 安装笔记
- Linux Mint---更新软件源
- Linux Mint---安装篇
- Linux命令行之文件操作
- linux下top命令详细介绍
- linux如何查看端口被谁占用
- Linux环境中程序的始终
- CentOS7_x86_64部署WebLogic11g并设置开机自启
- Linux初级之总结一linux概述
- linux 列出目录下的所有文件和目录
- linux awk 内置变量使用介绍
- windows 与 linux 多线程对应函数
- Linux的常用命令
- 【linux高级程序设计】(第九章)进程间通信-管道 3
- 安装Centos7后恢复windows启动项(非UEFI启动)
- linux 查看进程的命令(top)
- linux pwd命令详解