本文共 3497 字,大约阅读时间需要 11 分钟。
公司评级题,现在给自己做过总结,模块调试很有用!
调试API设计与实现
通过调试输出跟踪程序执行流程,排查程序问题是一种常用的手段,请设计一组调试接口,满足如下功能: 1)调试信息可按模块控制是否输出,模块定义如下 enum { DBG_A, DBG_B, DBG_C, DBG_D, DBG_E, DBG_F, DBG_G, DBG_H, DBG_MAX }; 2)每个模块有各自的调试级别控制,支持如下三个级别: enum { DEBUG, INFO, ERROR }; 3)调试级别间存在顺序关系 若设置为DEBUG,则DEBUG、INFO、ERROR级别均需要输出; 若设置为INFO,只输出INFO和ERROR级别信息; 若设置为ERROR,只输出ERROR级别信息。 4)调试输出接口支持类printf的变长参数 5)输出信息前自动附加模块名 6)用C语言宏实现如下接口,其余所需数据结构或内部接口请自行定义 (1)打开指定模块的指定级别调试开关 DBG_OPEN(module, level) (2)关闭指定模块的调试 DBG_CLOSE(module) (3)输出调试信息 DBG_LOG(module, level, format, ...) 7)调试宏受全局调试开关宏控制(CONFIG_DEBUG),在该宏未被定义时,调试宏无效,不影响代码运行 8)调用方法举例: void dhcp_main(int state) { ...; DBG_LOG(DBG_DHCP,level, "line %d@%s, state = %02x\n", _LINE_, _FILE_, state); ...; } 程序输出:dhcp: line 66@dhcp.c, state = 0x02参考资料:
http://hi.baidu.com/pragmatist/item/591a8a4ccbd643086dc2f035
http://blog.csdn.net/cqupt_chen/article/details/8055215 http://blog.csdn.net/chchchdx123/article/details/7597149 void debug_log(int module, int level, char *format, ...) { char buf[100]; va_list ap; if((module < 0) || (module >= DBG_MAX)) ; else if(module_debug[module].debug_evel > CLOSE) { if (level >= module_debug[module].debug_evel) { va_start(ap, format); vsnprintf(buf, sizeof(buf), format, ap); /* 将带参数的字符串按照参数列表格式化到buf中*/ va_end(ap); printf("%s %s", module_debug[module].name, buf); } } } #define DBG_LOG(module, level, format, ...) debug_log((module), (level), (format), ##__VA_ARGS__)答案
#ifndef _DEBUG_H#define _DEBUG_H#include测试程序test.c#include enum{ OFF, DEBUG, INFO, ERROR};enum{ DBG_A, DBG_B, DBG_C, DBG_D, DBG_E, DBG_F, DBG_G, DBG_H, DBG_MAX };struct module_info{ char debug_level; char *name;};struct module_info module_debug[DBG_MAX];#ifdef CONFIG_DEBUG /*全局宏*/ #define DBG_OPEN(module, level)\ do{\ if((module >= 0) && (module < DBG_MAX))\ if((level > 0) && (level <= ERROR))\ module_debug[module].debug_level = level;\ }while(0) #define DBG_CLOSE(module)\ do{\ if((module >= 0) && (module < DBG_MAX))\ module_debug[module].debug_level = OFF;\ }while(0)#define DBG_LOG(module, level, format, ...)\ do{\ if((module >= 0) && (module < DBG_MAX))\ if ((level > OFF) && (level >= module_debug[module].debug_level))\ printf("%s: "format, module_debug[module].name, ##__VA_ARGS__);\ }\ while(0)/* #define DBG_LOG(module, level, format, ...) debug_log((module), (level), (format), ##__VA_ARGS__)void debug_log(int module, int level, char *format, ...){ char buf[100]; va_list ap; if((module < 0) || (module >= DBG_MAX)) return; if(module_debug[module].level > OFF) { if (level >= module_debug[module].level) { va_start(ap, format); vsnprintf(buf, sizeof(buf), format, ap); // 将带参数的字符串按照参数列表格式化到buf中 va_end(ap); printf("%s %s", module_debug[module].name, buf); } }}*/#else#define DBG_OPEN(module, level) #define DBG_CLOSE(module) #define DBG_LOG(module, level, format, ...) #endif /* CONFIG_DEBUG */#endif /*_DEBUG_H*/
#include "debug.h"struct module_info module_debug[DBG_MAX] = { {OFF, "MOD_A"}, {OFF, "MOD_B"}, {OFF, "MOD_C"}, {OFF, "MOD_D"}, {OFF, "MOD_E"}, {OFF, "MOD_F"}, {OFF, "MOD_G"}, {OFF, "MOD_H"} };int main(int args, char **argv){ int module = DBG_B; DBG_OPEN(module, INFO); DBG_LOG(module, DEBUG, "debug: module_id:%d\n", module); DBG_LOG(module, INFO, "info: module_id:%d\n", module); DBG_LOG(module, ERROR, "error: module_id:%d\n", module); DBG_LOG(module, ERROR, "error!!!!!!\n"); return 0;}编译 gcc -o test.c -D CONFIG_DEBUG(-D 参数后面跟要定义的宏)