本文共 15600 字,大约阅读时间需要 52 分钟。
#ifdef DEBUG
Printf(“valriable x has value = %d\n”, x)
#endif
然后在编译选项中加入-DDEBUG
更复杂的调试应用如:
#define BASIC_DEBUG 1
#define EXTRA_DEBUG 2
#define SUPER_DEBUG 4
#if (DEBUG &EXTRA_DEBUG)
printf …
#endif
在这种情况下如果设置编译器标志为-DDEBUG=5,将启用BASIC_DEBUG和SUPER_DEBUG。 标志-DDEBUG=0将禁用所有的调试信息,也可以在程序中添加如下语句:
#ifndef DEBUG
#define DEBUG 0
#endif
Gcc编译的时候要加上-g选项,让编译器在程序中添加额外的调试信息。如果正式发布,这些调试信息可以使用strip命令删除。
Gdb:
Backtrace栈跟踪
splint功能:
常识性测试并产生一些警告信息。它可以检测未经赋值的变量使用,函数的参数未使用等异常情况。
显示执行所花费的时间具体都用在什么操作上。
ElectricFence函数库和valgrind可以用来检查动态内存分配的一些问题,包括内存泄漏。
Linux下的调试工具
随着XP的流行,人们越来越注重软件的前期设计、后期的实现,以及贯穿于其中的测试工作,经过这个过程出来的自然是高质量的软件。甚至有人声称XP会淘汰调试器!这当然是有一定道理的,然而就目前的现实来看,这还是一种理想。在日常工作中,调试工具还是必不可少的。在Linux下,调试工具并非只有gdb,还有很多其它调试工具,它们都各有所长,侧重方面也有所不同。本文介绍几种笔者常用的调试工具:
1. mtrace
在linux下开发应用程序,用C/C++语言的居多。内存泄露和内存越界等内存错误,无疑是其中最头疼的问题之一。glibc为解决内存错误提供了两种方案:
一种是hook内存管理函数。hook内存管理函数后,你可以通过记下内存分配的历史记录,在程序终止时查看是否有内存泄露,这样就可以找出内存泄露的地方了。你也可以通过在所分配内存的首尾写入特殊的标志,在释放内存时检查该标志是否被破坏了,这样就可以达到检查内存越界问题的目的。
另外一种方法更简单,glibc已经为第一种方案提供了默认的实现,你要做的只是在特定的位置调用mtrace/muntrace两个函数,它们的函数原型如下:
#include <mcheck.h>
void mtrace(void);
void muntrace(void);
你可能会问,在哪里调这两种函数最好?这没有固定的答案,要视具体情况而定。对于小程序来说,在进入main时调用mtrace,在退出main函数时调用muntrace。对于大型软件,这样做可能会记录过多的信息,分析这些记录会比较慢,这时可以在你所怀疑代码的两端调用。
另外,还需要设置一个环境变量MALLOC_TRACE,它是一个文件名,要保证当前用户有权限创建和写入该文件。glibc的内存管理器会把内存分配的历史信息写入到MALLOC_TRACE指定的文件中。
程序运行完毕后,使用mtrace工具分析这些内存分配历史信息,可以查出内存错误的位置(mtrace在glibc-utils软件包里)。
2. strace
在编程时,检查函数的返回值是一种好习惯。对于像glibc等标准C的函数,光检查返回值是不够的,还需要检查errno的值。这样的程序往往显得冗长,不够简洁。同时也可能是出于偷懒的原因,大多数程序里并没有做这样的检查。
这样的程序,一旦出现错误,用调试器一步一步定位错误,然后想法查出错误的原因,也是可以的,不过比较麻烦,对调试器来说有些大材小用,不太可取。这时,用strace命令可能会更方便一点。它可以显示各个系统调用/信号的执行过程和结果。比如文件打开出错,一眼就看出来了,连错误的原因(errno)都知道。
3. binutil
binutil是一系列的工具,你可能根本不知道它们的存在,但是没有它们你却寸步难行。Binutil包括下列工具:
其中部分工具对调试极有帮助,如:
你可以用objdump反汇编,查看目标文件或可执行文件内部信息。
你可以用addr2line把机器地址转换到代码对应的位置。
你可以用nm查看目标文件或可执行文件中的各种符号。
你可以用gprof分析各个函数的使用情况,找出性能的瓶颈所在(这需要加编译选项)。
4. ld-linux
现在加载ELF可执行文件的工作,已经落到ld-linux.so.2头上了。你可能会问,这与有调试程序有关系吗?有的。比如,在linux中,共享库里所有非static的函数/全局变量都是export的,更糟的是C语言中没有名字空间这个概念,导致函数名极易冲突。在多个共享库中,名字冲突引起的BUG是比较难查的。这时,你可以通过设置LD_ DEBUG环境变量,来观察ld-linux.so加载可执行文件的过程,从中可以得到不少帮助信息。LD_ DEBUG的取值如下:
5. gdb
对于真正意义的调试器来说,gdb在linux下是独一无二的。它有多种包装,有字符界面的,也有图形界面的,有单独运行的,也有集成到IDE中的。gdb功能强大,图形界面的gdb容易上手一点,但功能无疑受到了一些限制,相信大部分高手还是愿意使用字符界面的。Gdb太常用了,这里不再多说。
6. gcc/boundschecker
相信很多人用过win32下的BoundsChecker(Compuware公司)和Purify(IBM公司)两个工具吧。它们的功能实在太强大了,绝非能通过重载内存管理函数就可以做到,它们在编译时插入了自己的调试代码。
gcc也有个扩展,通过在编译时插入调试代码,来实现更强大的检查功能。当然这要求重新编译gcc,你可以到 下载gcc的补丁。它的可移植性非常好,笔者曾一个ARM 平台项目里使用过,效果不错。
7. valgrind
最好的东西往往最后才见到。Valgrind是我的最爱,用习惯了,写的程序不在valgrind下跑一遍,就像没有写单元测试程序一样,有点放心不下。它有BoundsChecker/Purify的功能,而且速度更快。
有点遗憾的是valgrind目前只支持x86平台,当然,这对大多数情况已经足够了。
你可以到 下载最新版本。
尽管你可以在大多数(即便不是全部)Linux调试 任务中使用GDB,但与长时间坐在GDB命令行前面相比,许多人还是更愿意使用诸如DDD或Eclipse这样的图形化工具。从各方面来看,大多数非常花 哨的图形化调试工具不过是建立在GDB基础上的一个抽象,所以选择哪一种图形化工具完全属于个人爱好。
本节将介绍两个这样的工具,当然还存在其他许多这样的工具(包括GDB的前端GNU insight),它们也被各种开发团队所使用。
从事Linux应用开发一年多了,感觉很不规范很山寨,准备系统地学习一下下linux开发,首先从调试工具的学习开始,以下是从网上看到的一篇linux调试工具介绍,准备好好学习这些工具的使用。
“工欲善其事 必先利其器”现在将一些常见的调试工具进行一下总结.
【1】
名称:MEMWATCH
功能:
1、MEMWATCH 支持 ANSI C
2、它提供结果日志纪录
3、能检测双重释放(double-free)
4、错误释放(erroneous free)
5、没有释放的内存(unfreed memory)、
6、溢出和下溢等等。
参考文献:
【1】:
【2】
名称:YAMD
功能:
1、查找 c 和 c++ 中动态的、与内存分配有关的问题
参考文献:
【1】
【2】
【3】
名称:electric fence
功能:
1、检测内存泄露
2、检查数据越界
3、分配受保护的内存
参考文献:
【1】
【2】
【3】
【4】
名称:strace
功能:
1、显示用户空间程序发出的系统调用
2、显示调用的参数和返回值
【5】
名称:gdb
功能:
1、启动程序
2、使程序能够停止在指定文件的指定位置
3、查看程序变量值
4、改变程序执行期间的相关变量、路径等
【6】
名称:Oops
功能: 显示系统错误信息
参考文献:
【1】
【7】
名称:mtrace
功能:
1、检测一些内存分配和泄漏的失败等
参考文献:
【1】
【2】
【3】
【8】
名称:binutil
说明:binutil为一个工具集合,包含如下的工具。
addr2line 把程序地址转换为文件名和行号。在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上是哪个文件以及行号。
ar 建立、修改、提取归档文件。归档文件是包含多个文件内容的一个大文件,其结构保证了可以恢复原始文件内容。
as 主要用来编译GNU C编译器gcc输出的汇编文件,产生的目标文件由连接器ld连接。
c++filt 连接器使用它来过滤 C++ 和 Java 符号,防止重载函数冲突。
gprof 显示程序调用段的各种数据。
ld 是连接器,它把一些目标和归档文件结合在一起,重定位数据,并链接符号引用。通常,建立一个新编译程序的最后一步就是调用ld。
nm 列出目标文件中的符号。
objcopy 把一种目标文件中的内容复制到另一种类型的目标文件中.
objdump 显示一个或者更多目标文件的信息。显示一个或者更多目标文件的信息。使用选项来控制其显示的信息。它所显示的信息通常只有编写编译工具的人才感兴趣。
ranlib 产生归档文件索引,并将其保存到这个归档文件中。在索引中列出了归档文件各成员所定义的可重分配目标文件。
readelf 显示ebf格式可执行文件的信息。
size 列出目标文件每一段的大小以及总体的大小。默认情况下,对于每个目标文件或者一个归档文件中的每个模块只产生一行输出。
strings 打印某个文件的可打印字符串,这些字符串最少4个字符长,也可以使用选项-n设置字符串的最小长度。默认情况下,它只打印目标文件初始化和可加载段中的可打印字符;对于其它类型的文件 它打印整个文件的可打印字符,这个程序对于了解非文本文件的内容很有帮助。
strip 丢弃目标文件中的全部或者特定符号。
libiberty 包含许多GNU程序都会用到的函数,这些程序有: getopt, obstack, strerror, strtol 和 strtoul.
libbfd 二进制文件描述库.
libopcodes 用来处理opcodes的库, 在生成一些应用程序的时候也会用到它, 比如objdump.Opcodes是文本格式可读的处理器操作指令.
功能:程序调试、归档等
参考文献:
【9】
名称: Purify
功能:内存检查工具
参考文献:
【10】
名称:pc-lint
功能:C/C++的静态代码检测工具
参考文献:
【1】
【11】
名称:splint
说明:splint是一个动态检查C语言程序安全弱点和编写错误的程序
功能:
1、空引用错误
2、未定义的变量错误
3、类型错误
4、内存检查
参考文献:
【1】
【2】
【12】
名称:boundercheck
功能:检查内存泄露
【13】
名称:valgrind
功能:
1、检查内存错误
参考文献:
IDA最知名的是反汇编器,它是二进制文件执行静态分析的最佳工具之一。由于现代反静态分析技术的复杂性,人们常常将静态分析与动态分析技术结合起来,以利用二者的优势。理想情况下,所有这些工具集成在一个软件包中。Hex-Rays在推出4.5版的IDA调试器时,做出巩固IDA的作用将其作为一个通用的逆向工程工具这一举动。随着IDA的后续版本,调试功能得到改善。在最新版本中,IDA能够在多个不同的平台上进行本地和远程调试,并支持多种不同的处理器。
Rythem是什么 Rythem是一个与Fiddler同类的软件,和Fiddler一样具有 代理抓包/替换 功能,与Fiddler最大的不同是Rythem是跨平台&开源的。 官方详细介绍: http://www.alloyteam.com/2012/05/web-front-end-tool-rythem-1/ 以下为Rythem运行的截图:(MacO... |
YAGAC 是一个库用来链接到你的C程序,让您可以方便地跟踪应用程序中的内存泄漏问题。根据你的代码部分。它跟踪你的代码只分配内存,不监测第三部分库,你可以有多个垃圾收集。跟踪可以被激活的更新调试标志,而无需重新启动您的应用程序。其目的是为守护程... |
最近更新: 发布于 1年前
libcsdbg 是一个 C++ 异常堆栈跟踪器。当异常被抛出、捕获和处理时,libcsdbg 提供可工具来创建和处理异常堆栈的跟踪,并通过调用堆栈来传播异常路径。跟踪器提供异常发生的函数以及额外的 addr2line 信息(源码级别) 功能列表: 复杂的异常堆栈跟踪(支持... |
最近更新: 发布于 4天前
GDB(GNU symbolic debugger)简单地说就是一个调试工具。它是一个受通用公共许可证即GPL保护的自由软件。 象所有的调试器一样,GDB可以让你调试一个程序,包括让程序在你希望的地方停下,此时 你可以查看变量,寄存器,内存及堆栈。更进一步你可以修改变量... |
最近更新: 发布于 12天前
GNU DDD (Data Display Debuger) 是一个图形化的调试工具,通过对调试命令例如 GDB、DBX、WDB、JDB、XDB 等等命令行工具的封装,提供一个非常友好的调试界面。 |
strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统呼叫及它所接收的系统信息。 strace是一个有用的小工具,它可以通过跟踪系统调用来让你知道一个程序在后台所做的事情。Strace是一个基础的调试工具,在大多数Linux系 统上默认已经... |
灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题。当程序越来越复杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题。内存泄漏是最常见的内存问题之一。内存泄漏如果不是很严重,在短时间内对程序不会有太大的影响,这也使得内... |
Valgrind是一个运行时诊断工具,它可以监视 一个指定程序的活动并通知你在你的代码中可能存在的各种各样的内存管理问题。它类似于老式的Electric Fence工具(该工具将标准的内存分配函数替换为自己的函数以提高诊断能力),但被认为更容易使用并且在多个方... |
最近更新: 发布于 3个月前
KDbg 是一个 gdb 调试工具的图形化界面的工具(点击查看大图)。 |
最近更新: 发布于 3个月前
OLLYDBG是一个新的动态追踪工具,将IDA与SoftICE结合起来的思想,Ring 3级调试器,非常容易上手,己代替SoftICE成为当今最为流行的调试解密工具了.同时还支持插件扩展功能,是目前最强大的调试工具. |
LLDB 是下一代高性能的调试器,构建一组可重用的组件,覆盖很多 LLVM 项目的库,例如 Clang 表达式解析器和 LLVM 反汇编器。目前该项目还处于前期开发状态,但已经注意支持在 Mac OS X 上的 C/C++ 和 Objective-C 的开发。... |
有不少开发者使用Visual Studio®提供的工具Spy++。使用Spy++,你可以了解一个运行中的应用程序的窗体布局或确定一个导致bug的特定窗体消息。然而,当你创建一 个基于Microsoft® .NET框架的应用程序,Spy++变得不太管用了,因为由Spy++截取窗体消息和类不... |
您还在使用gdb缓慢地调试UNIX/LINUX的程序吗?XBuildStudio是专为提升UNIX/LINUX的程序的开发而设计的在WINDOWS平台上调试UNIX/LINUX程序的开发工具,操作方式类似VC的环境,有效提升您的工作效率. |
cgdb,可以看成是gdb的终端界面增强版,相比windows下的visual studio而言,它的功能显得十分轻量级而没有太多繁杂,能在终端里运行。 |
EDB (Evan's Debugger) 是一个基于 Qt4 开发的二进制调试工具,主要是为了跟 OllyDbg 工具看齐,通过插件体系可进行功能的扩充,当前只支持 Linux ,将来会发布其他平台的版本。 |
最近更新: 发布于 1个月前
BuGLe 结合图形化的OpenGL调试与选择的过滤器上的OpenGL命令流。调试器可以查看状态、纹理、framebuffers ,着色器,而过滤器允许日志,错误检查,自由相机控制,视频捕捉等。 |
uuSpy工具很类似于Spy++。此外,还可以查看[***]的密码,甚至取得Internet Explorer的HTML。使用uuSpy你可以知道正在运行的窗口程序的结构。或者监视导致程序出错的特定的窗口消息。甚至你可以输出指定窗口的 style/exstyle,或做某些设置。 uuSpy可以对指... |
Crackerjack Project 是由中日韩三方共同参加开发,该项目主要目的是为Linux内核提供自动化的回归测试功能,以帮助提高内核开发质量等,项目包括一个完整的内核自动化测试框架,以实现自动化载入、执行、管理测试用例,还包括定义新的测试程序(用例),集... |
pev是一个小巧的基于命令行的windows可执行文件(PE)分析工具,支持linux、windows和OSX系统。特别的是它使用ANSI标准c编写,因此可以容易的在多个平台上编译。pev免费并且开放源代码。 |
MEMWATCH 由 Johan Lindh 编写,是一个开放源代码 C 语言内存错误检测工具。只要在代码中添加一个头文件并在 gcc 语句中定义了 MEMWATCH 之后,您就可以跟踪程序中的内存泄漏和错误了。MEMWATCH 支持 ANSI C,它提供结果日志记录,能检测双重释放(double-... |
|
转载地址:http://fzwub.baihongyu.com/