如何在嵌入式Linux产品中做立体、覆盖产品生命期的调试 ( 2 )

来源:互联网 发布:数据结构与算法c语言版 编辑:程序博客网 时间:2024/05/18 18:00
 
上接:如何在嵌入式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 <glib/gtypes.h>
#include <stdio.h>
#include <stdarg.h>
#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的支持;在后续的讨论中会加上…….
 
原创粉丝点击