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

2019-07-13 02:51发布

  上接:如何在嵌入式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的支持;在后续的讨论中会加上…….