DBUG软件包Fred Fish's dbug library ---编程调试利器
DBUG软件包Fred Fish's dbug library ---编程调试利器
转载注明出处--UnGeek http://www.cnblogs.com/UnGeek/archive/2013/04/14/3020617.html
一. 介绍
我们在代码中常常要嵌入调试代码比如常用的printf,cout,assert之类的,在发布最终的release版本的时候,如果没有经过一些宏替换之类的方法的话,我们可能又要删除这部分代码(assert 除外),或者不用删除但是可能会进行额外的空函数调用做为原来调试函数的代替,这不仅曾加了我们编写代码的难度,而且可能会引入额外的bug和运行开销,而dbug库则非常漂亮的解决了这个问题,下载dbug后,我们只需要src目录下的dbug.h 和 dbug.c,虽然代码量不如其他库那么多,然而这正是它的优势,它可以直接添加进你的工程之中,无需编译库和链接,如果你下载的dbug无法再你的平台工作,那么可以考虑使用我修改过的版本
dbug官方下载地址http://sourceforge.net/projects/dbug/
本人修改可运行于VS2010与MinGW gcc4.7 https://github.com/sijianwudi/varlib/tree/master/dbug
二.使用
下面看看官方例子:
/* * This file is Public Domain * * Just short example, how Fred Fish's dbug package should be used * * Tonu Samuel <tonu@spam.ee> * */ #include "dbug.h" static int sub1 (void); static void sub2 (const char *arg); static int sub1 (void) { DBUG_ENTER ("sub1"); sub2 ("Hello world!"); sub2 ("Hello earth!");; sub2 ("Hello programmer!"); DBUG_RETURN (0); } static void sub2 (const char *arg) { DBUG_ENTER ("sub2"); DBUG_PRINT ("info", ("Got argument: '%s'", arg)); printf ("%s\n", arg); DBUG_VOID_RETURN; } int main (void) { int ret = 0; DBUG_PUSH ("d:t:O"); DBUG_PROCESS ("example"); ret = sub1 (); DBUG_PRINT ("info", ("Returned value: %d", ret)); return 0; }
输出为
>sub1
| >sub2
| | info: Got argument: 'Hello world!'
Hello world!
| <sub2
| >sub2
| | info: Got argument: 'Hello earth!'
Hello earth!
| <sub2
| >sub2
| | info: Got argument: 'Hello programmer!'
Hello programmer!
| <sub2
<sub1
info: Returned value: 0
Process returned 0 (0x0) execution time : 0.053 s
Press any key to continue.
怎么样?是不是很漂亮的完成了你想要的功能。
当你要发布自己的release版本的时候,只要在文件头加上
#define DBUG_OFF
就能将所有的代码替换为空宏或者相应的return <value>语言,完全不用担心有额外的开销
三.小结
dbug可以说是一个非常精炼非常有用的库,里面的代码可以用优雅来形容,可以暂时没有进行详细的浏览,但是我想以后有时间我会进行详细的研究或者对原始版本进行改进。
最后,向dbug作者Fred Fish,这位伟大的程序员致敬!
四.附录
dbug在许多开源项目中有所应用如mysql
下面是mysql官方描述
MySQL服务器和多数MySQL客户端都带着由Fred Fish初创的DBUG 软件包编译成的。当你为调试配置MytSQL之时,这个软件使你可以得到一个程序正在调试什么的跟踪文件。请参阅E.1.2节,“创建跟踪文件”。
这一节总结了你对已建立支持调试的MySQL程序在命令行的调试选项处可以指定的参量值。要获取更多使用DBUG软件包来编程的信息,请参阅MySQL源发布包里dbug目录下的DBUG手册。最好使用最近的MySQL 5.1发布包以获得最近更新的DBUG手册。
你通过用--debug="..."或the -#... 选项调用一个程序来使用调试软件包。
多数MySQL程序有默认的调试字符串,如果你不给--debug指定一个选项,就使用这个默认的。默认的跟踪文件通常是/tmp/program_name.trace(在Unix上)和\program_name.trace (在Windows上)。
调试字符串是一系列冒号隔开的区段,如下:
<field_1>:<field_2>:...:<field_N>
每个区段包含一个强制标志字符,后面跟着已和可选的 ‘,’ 以及一列用逗号隔开的修改量:
flag[,modifier,modifier,...,modifier]
当前被识别的标记符号是:
标记 | 描述 |
d | 允许对当前状态从DBUG_<N>宏输出。可能跟着一列关键词,这些关键词仅对那些带有关键词的DBUG宏选择输出。一个空的关键词列意味着对所有宏输出。 |
D | 在每个调试起输出行后延迟。参量一个十分之一秒为单位来延迟的数,它受限于机器的能力。比如 -#D,20 指定一个2秒的延迟。 |
f | 限制调试和/或跟踪,以及简单设定于列出名字的函数。注意,空列将禁止所用函数。应该给出适当的d 或 t 标记,如果它们被允许了,这个标记仅限制它们的动作。 |
F | 对调试或跟踪输出的每一行识别源文件名。 |
i | 对调试或跟踪输出的每一行用PID或线程ID识别进程。 |
g | 允许解析,创建名为的dbugmon.out文件,它包含可用来简单设定程序的信息。可能跟着一列关键词,它们是选择只对列中的函数做简单设定。一个空列意味着所有函数都要考虑到。 |
L | 为调试或跟踪输出的每一行识别源文件行号。 |
n | 为调试或跟踪输出的每一行打印当前函数嵌套深度。 |
N | 给调试输出的每一行编号。 |
o | 重定向调试器输出流到指定文件。默认输出是stderr 文件。 |
O | 类似于 o,但是文件在每次写操作之间被冲刷。当需要之时,文件在每次写操作之间被关闭然后重新打开。 |
p | 限制调试器作用于指定进程。为使调试器动作,一个进程必须用DBUG_PROCESS宏来识别,且匹配列表中的一个。 |
P | 为调试或跟踪输出的每一行打印当前进程名字。 |
r | 当推出一个新状态时,不继承前状态的操作嵌套深度级别。当输出在左边空白开始时有用。 |
S | 在每个调试过的函数做_sanity(_file_,_line_)函数直到 _sanity() 返回不同于0的结果。(大多数的时候与safemalloc 一起用来找出内存漏洞)。 |
t | 允许函数调用/退出跟踪行。可能跟着一个给出最大跟踪级别的数字列(只含一个修改量),超过这个数字,调试中或跟踪中的宏不能产生任何输出。 默认为一个编译时间选项。 |
可能出现在外壳命令行(-# 典型地被用来引入一个控制字符串到一个应用程序中) 的调试控制字符串的一些例子如下:
-#d:t -#d:f,main,subr1:F:L:t,20 -#d,input,output,files:n -#d:t:i:O,\\mysqld.trace
在MySQL中, 打印的一般标记是(用 d 选项)是 enter, exit, error, warning, info, 和 loop 。