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

    技术2022-05-11  83

    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的保护模式,通过越权访问内存主动引发异常。不同处理器可以参考处理器编程说明。

    最新回复(0)