写代码同时应注意的几个代码调试手段

来源:互联网 发布:织梦域名授权 编辑:程序博客网 时间:2024/05/16 09:56
1。debug log信息
    这个重要性不用说了  虽然是最低级的调试手段  但是历史告诉我们  往往简单才是最有效的。
    debug最基本的初衷是为了让程序除了正常运行模式外,还能运行于debug模式,以方便跟踪程序的一举一动。
    见过几种debug的方式
   
    1)分等级
    最典型常见的就是printk  分等级的目的是为了将不同等级区分对待。然而printk存在并不是为了作为debug信息,当然可以用来输出debug信息,printk是了规划和整理整个大系统各个模块各个部门报告的信息。因此debug log信息不益完全参考printk做法。

#define xdebug(n, f, a...)                        /
    do {                                /
        if ((n) <= debug_level) {                /
            printk ("<"#n">" "(%s, %d): %s: ",        /
                __FILE__, __LINE__, __FUNCTION__);    /
              printk (f, ## a);                /
        }                            /
    } while (0)

    上面的做法是通过控制debug_level的值控制符合等级要求的debug信息的输出。当然debug_level可以是常数,也可以是变量(动态调整)。
    分等级的方法最大的缺点是使用时比较难于确定具体log信息的等级,等到最后信息都出来的时候,你会发现有的信息你本来希望是等级4,而过了几个你却希望它是等级5!


    2)分模块log信息
    分模块方法对于调试而言要好用的多,调试某个模块只用打开对应模块的信息即可。
    通常用一个bit表示一个模块进行编码,这样可以同时标记多个模块。
    下面是linux rpc的debug方法

#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
#define dprintk(level,args...) /
    do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0)
#else
#define dprintk(level,args...)
#endif

#define deb_info(args...)  dprintk(0x01,args)
#define deb_tuner(args...) dprintk(0x02,args)
#define deb_i2c(args...)   dprintk(0x04,args)
#define deb_ts(args...)    dprintk(0x08,args)
#define deb_sram(args...)  dprintk(0x10,args)
#define deb_rdump(args...)  dprintk(0x20,args)

    3)(1)和(2)的结合
    每个模块使用一段位图,多个模块需要位图数组,各个模块能按照自己等级打印。。。。。


2。assert

    assert主要用于程序处于debug模式的测试,正常模式assert不应该参加编译。
    assert可用范围相当广,应该养成对自己坚信不移的而缺乏验证的条件都加以assert,当然不相信的条件则更应该如此。有效的使用assert你会发现调试初期bug非常容易。


3。BUG()

    对于某些无法处理的情况,又或者认定不会发生的情况,一旦发生了,BUG()是唯一选择。
    应用程序中,进行简单的报错,或者加上core down之类,最后的操作一般是exit。kernel中当然也能显式的调用exit,但更正规的做法是主动造成一个硬件异常,使得程序被迫退出。x86 linux kernel利用cpu的保护模式,通过越权访问内存主动引发异常。不同处理器可以参考处理器编程说明。




原创粉丝点击