1.宏定义开关方法
我们在调试程序的时候,经常会需要知道在运行时某些变量的状态(值),我们可以通过定义调试开关,来生成debug调试版本或者release最终发行版本程序,先看个简单的例子:
void main(void)
{
int runtime_flag;//举例一个流程时的判断标志
/***注释标记1***
省略一些变量定义或函数运行
这些函数可能会影响runtime_flag的值
***************/
if(runtime_flag == 1)
{
/***注释标记2***
省略一些函数运行
这些函数可能会影响runtime_flag的值
***************/
}
else
{
/***注释标记3***
省略一些函数运行
这些函数可能会影响runtime_flag的值
***************/
}
/***注释标记4***
省略一些函数运行
这些函数可能会影响runtime_flag的值
***************/
}
以上我们举了一个比较简单的例子说明,在类似代码中,我们如果需要知道某一变量运行时的状态,比如想知道注释标记3处的runtime_flag的值,我们该怎么办?
一般调试,是通过编译调试软件进入调试debug模式下加断点等方法。
但是,很多场景下,尤其是产品项目已落地测试维护的产品,我们是没有办法在现场通过调试软件进行源码分析,此时通过预先的宏技巧,来实现调试开关就显得尤为关键。让我们直接上源码:
/*宏调试开关*/
#define debug
/*显示打印信息所在的文件、行数、函数名以及需要print的信息*/
#define DBG_PRINTF(fmt, args...) \
{
printf("<<File:%s Line:%d Function:%s>> ", __FILE__, __LINE__, __FUNCTION__);\
printf(fmt, ##args);\
}
void main(void)
{
int runtime_flag;//举例一个流程时的判断标志
/***注释标记1省略处***/
#ifdef debug
DBG_PRINTF("runtime_flag=%d\r\n",runtime_flag) ;
#endif
if(runtime_flag == 1)
{
/***注释标记2省略处***/
}
else
{
/***注释标记3省略处***/
#ifdef debug
DBG_PRINTF("runtime_flag=%d\r\n",runtime_flag) ;
#endif
}
/***注释标记4省略处***/
}
通过以上的宏定义开关,我们就可以知道标记1以及标记3处我们需要知道的变量值在运行到所在文件、行数、函数名、以及变量值是多少。在调试阶段我们可以宏定义debug,测试无问题后,可将debug宏定义注释,直接生成release版本,后续如果需要debug,再宏定义恢复,这就及其方便。
2.变量开关方法
上述宏定义技巧在切换为release版本时,还需要通过编译软件修改源码在进行操作,有没有什么方法可以在外部调试的情况下,直接切换debug模式状态或者release状态?让我们直接上源码:
/*显示打印信息所在的文件、行数、函数名以及需要print的信息*/
#define DBG_PRINTF(fmt, args...) \
{
printf("<<File:%s Line:%d Function:%s>> ", __FILE__, __LINE__, __FUNCTION__);\
printf(fmt, ##args);\
}
int debug = 1 ; // 全局变量,默认开关为打开状态
void main(void)
{
int runtime_flag;//举例一个流程时的判断标志
/***注释标记1省略处***/
if(debug == 1)
DBG_PRINTF("runtime_flag=%d\r\n",runtime_flag) ;
if(runtime_flag == 1)
{
/***注释标记2省略处***/
}
else
{
/***注释标记3省略处***/
if(debug == 1)
DBG_PRINTF("runtime_flag=%d\r\n",runtime_flag) ;
}
/***注释标记4省略处***/
}
/*不同应用对象应用的中断形式不同,我们以外部输入触发中断举例*/
void interrupt input_var ()
{
scanf("%d",&debug) ;
}
通过以上的变量开关,可以实现动态运行测试时就可以切换是否输出调试日志信息。
关于中断触发,不同的应用平台使用的方式方法不一样,统一抽象的思想是:
在流程动态运行中,输入debug值,会触发中断(不同的形式叫法不一样),这会改变debug值,从而实现动态的外部切换debug或release版本状态,也就是是否输出调试时我们希望看到的调试日志信息。
3.小结对比
让我们将两个方法做个对比:
- 共同点:
- 都可以在程序动态运行时,输出对应的调试日志信息;
- 在debug版本模式下所占用空间类似。
- 不同点:
- 宏开关在relase版本下,由于未定义debug开关,所以之后的宏定义判断不占用程序空间,不会增加计算消耗;
- 变量开关在切换relase版本时候只需要debug=0即可。