公司评级题,现在给自己做过总结,模块调试很有用!
调试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 <stdio.h>
#include <stdarg.h>
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*/
测试程序test.c
#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 参数后面跟要定义的宏)