模块调试技巧

公司评级题,现在给自己做过总结,模块调试很有用!

调试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 参数后面跟要定义的宏)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值