Linux下的调试工具

来源:互联网 发布:阿里云服务器升级配置 编辑:程序博客网 时间:2024/05/23 00:02

http://blog.csdn.net/absurd/archive/2006/02/28/612612.aspx

1.mtrace

在linux下开发应用程序,用C/C++语言的居多。内存泄露和内存越界等内存错误,无疑是其中最头疼的问题之一。glibc为解决内存错误提供了两种方案:

一种是hook内存管理函数。hook内存管理函数后,你就可以通过记下内存分配的历史记录,在程序终止时查看是否有内存泄露,这样就可以找出内存泄露的地方了。你也可以通过在所分配内存的首尾写入特殊的标志,在释放内存时检查该标志是否被破坏了,这样就可以达到检查内存越界问题的目的。

 

glibc已经为第一种方案提供了默认的实现,你要做的只是在特定的位置调用mtrace/muntrace两个函数,它们的函数原型如下:

 

对于小程序来说,在进入main时调用mtrace,在退出main函数时调用muntrace。对于大型软件,这样做可能会记录过多的信息,分析这些记录会比较慢,这时可以在你所怀疑代码的两端调用。

 

另外,还需要设置一个环境变量MALLOC_TRACE,它是一个文件名,要保证当前用户有权限创建和写入该文件。glibc的内存管理器会吧内存分配的历史信息写入到MALLOC_TRACE指定的文件中。

 

程序执行完毕后,使用mtrace工具分析这些内存分配历史信息,可以查出内存错误的位置(mtrace在glibc-utils软件包里)。

 

2.strace

在编程时,检查函数的返回值是一种好习惯。对于像glibc等标准C的函数,光检查返回值是不够的,还需要检查errno的值。这样的程序往往显得冗长,不够简洁。同事也可能是出于偷懒的原因,大多数程序里并没有做这样的检查。

 

这样的程序,一旦出现错误,用调试器一步一步定位错误,然后想法查出错误的原因,也是可以的,不过比较麻烦,对调试器来说有些大材效用,不太可取。这时,用strace命令可能会更方便一点。它可以显示各个系统调用/信号的执行过程和结果。比如文件打开出错,一眼就看出来,连错误的原因(errno)都知道。

 

3.binutil

binutil是一系列的工具。binutil包括下列工具:

ld - the GNU linker

as - the GNU assembler

addr2line - Convert addresses into filenames and line numbers

ar - A utility for creating, modifying and extracting from archives

c++ filt - Filter to demangle encoded C++ symbols

gprof - Displays profiling information

nulmconv - Converts object code into an NLM

nm - Lists symbols from object files

objcopy - Copys and translates object files

objdump - Display information from object files

ranlib - Generates an index to the contents of an archive

readelf - Display information from any ELF format object file

size - Lists the section size of an object or archive file

strings - Lists pritntable strings from files

strip - Discards symbols

windres - A compiler for Window resource files

其中部分工具对调试极有帮助,如:

用objdump反汇编,查看目标文件或可执行文件内部信息。

用addr2line把机器地址转换到代码对应的位置

用nm查看目标文件或可执行文件中的各种符号

用grpof分析各个函数的使用情况,找出性能的瓶颈所在(这需要加编译选项)

 

4.ld-linux

现在加载ELF可执行文件的工作,已经落到ld-linux.so.2头上了。在linux中,共享库里所有非static的函数/全局变量都是export的,

更糟糕的是C语言中没有名字空间这个概念,导致函数名极易冲突。在多个共享库中,名字冲突引起的BUG是比较难查的。这是,你可以通过设置LD_DEBUG环境变量,来观察ld-linux.so加载可执行文件的过程,从中可以得到不少帮助信息。LD_DEBUG的取值如下:

libs         display library search paths

reloc       display relocation processing

files        display progress for input file

symbols  display symbol table processing

bindings  display information about symbol binding

versions  display version dependencies

all           all previous options combined

statistics display relocation statistics

unused    determined unused DSOs

help        display this help message and exit

 

6. gcc/boundschecker

gcc也有个扩展,通过在编译时插入调试代码,来实现更强大的检查功能。当然这要求重新编译gcc,你可以到ttp://sourceforge.net/projects/boundschecking/ 下载gcc的补丁。

 

7.valgrind