上接:如何在嵌入式Linux产品中做立体、覆盖产品生命期的调试 ( 1)
这篇谈谈print的做法:
print函数很多:g_print, printf, vprintf, fprintf等;至于用哪一个,看你的平台了;
我们是否有这样的感觉:
编程开始时加入很多print函数,而且打印的信息五花八门,不少人为了区分自己的程序,往往这样做:
printf (“<<<<<<<<<<<<<<<<<<<<<<<< here!!!”)
printf (“>>>>>>>>>>>>>>>>>>>>>>>>>>step N !!!”)
printf (“===========================1 !!!”)
printf (“============================2 !!!”)
等等;
这样会引起一些问题:
1 过段时间后,发现程序很乱!
2 发布时要赶紧把这些print去掉;
3 出现问题时又要把这些print加上;
反反复复这样折腾的话,效率很低!
因此,
1 为了在release关掉打印,一般要定义一个宏来控制这个打印
2 写个通用的打印,可以接受可变参数
3 在函数入口、出口处监测
4 直接支持行数、函数名称、文件名称;
Debug.h
#ifndef _DEBUG_H_
#define _DEBUG_H_
//如果在你的makefile没有定义DEBUG_FUNC这个宏,则你程序中的这些打印函数将是空函数,不会有打印信息;反之,可以看到打印信息
#ifdef DEBUG_FUNC
#define ENTER_FUNC enter_func(__FUNCTION__)
#define LEAVE_FUNC leave_func(__FUNCTION__)
#define trace_verbose (...) dbg(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#else
#define ENTER_FUNC
#define LEAVE_FUNC
#define trace_verbose (...)
#endif
void enter_func(const char *name);
void leave_func(const char *name);
void dbg(const char *file, const char *func, const guint line, const char *format, ...);
#endif
Debug.c
#include
#include
#include
#include "debug.h"
static guint depth = 0;
void enter_func(const char *name)
{
guint i;
for (i = 0; i < depth; i++) {
fprintf(stderr, " ");
}
fprintf(stderr, "Entering %s/n", name);
depth++;
}
void leave_func(const char *name)
{
guint i;
depth--;
for (i = 0; i < depth; i++) {
fprintf(stderr, " ");
}
fprintf(stderr, "Leaving %s/n", name);
}
void dbg(const char *file, const char *func, const guint line, const char *format, ...)
{
guint i;
va_list args;
for (i = 0; i < depth; i++) {
fprintf(stderr, " ");
}
fprintf(stderr, "*** %s: ", func);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "(LINE: %d, FILE: %s )", line, file);
fprintf(stderr, "/n");
}
如何使用这样的通用模板呢?
1 要在makefile中定义宏DEBUG_FUNC
2 监测函数出入口和你想看的信息
void test_func1(void)
{
ENTER_FUNC;
trace_verbose ("do something in function 1.");
trace_verbose (“print msg: %d, %s”, 1, “test”);
LEAVE_FUNC;
return;
}
使用trace_verbose和使用各种print函数没有什么区别,怎么用print,就可以直接用trace_vebose代替它;
这种打印的好处
1 信息统一
2 可控;
3 而且可以看到函数调用的层次关系;
比一堆print好多了;
在release时,关掉DEBUG_FUNC宏就可以了,不必要手忙脚乱的去删除print;
在出现问题时,打开DEBUG_FUNC,就可以很称心的看到想看到的信息;
对于这种打印还可以再升级改造,比如增加环境变量的支持;增加log的支持;在后续的讨论中会加上…….