博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
__FILE__,__LINE__,__func__ 真好用,DEBUG利器啊!
阅读量:5375 次
发布时间:2019-06-15

本文共 4269 字,大约阅读时间需要 14 分钟。

我是不喜欢用类似VC下的F5,F10。曾经很喜欢用。被代码逻辑逼的没招了。所以不喜欢用了。

比如,错误是根据动态数据,产生的行为错误,无论是该写的未写,还是不该写的写了。指针跑飞什么等等,无非就是上述两个错导致。但要找到具体原因,F5,F10根本不够。所以索引不用了。

这里介绍一下我现在的方法。不过注明这不是LOG。

一个头文件。大体如下:

1 #ifndef _debug_H_ 2 #define _debug_H_ 3  4 #include 
5 #include
6 #include
7 8 #ifndef UNDEBUG_FILE 9 #define DEBUG_FLAG 110 #else11 #define DEBUG_FLAG 012 #endif13 14 #if (DEBUG_FLAG == 1)15 16 static unsigned int __sdebug_time = 0;17 #define __debug_Msg_Size 102418 static char __pdebug_Msg[__debug_Msg_Size];19 //注意下面的__attribute__不是C标准。。。。20 static void __debug_info(const char *prefix,const char *fmt, ...) __attribute__((format (printf, 2, 3)));21 #define __NEXT_DBG_TIME() do{sdebug_time++;}while(0)22 #define __PRINT_POS() do {fprintf(stderr,"%s(%d){%s}",__FILE__,__LINE__,__func__);}while(0)23 #define __FUNC_LOG() do{__PRINT_POS();fprintf(stderr,": t = %d ",__sdebug_time++);} while(0)24 #define __FUNC_LOGn() do{__FUNC_LOG();fprintf(stderr,"\n");} while(0)25 #define __PRINT_POS_exp(exp) do{__PRINT_POS();fprintf(stderr,"| (%s):",#exp);}while(0)26 #define __PRINT_POS_P_exp(prefix,exp) do{__PRINT_POS();fprintf(stderr,"|<%s> (%s):",prefix,#exp);}while(0)27 #define __PRINT_POS_expn(exp) do{__PRINT_POS_exp(exp);fprintf(stderr,"\n");}while(0)28 #define __PRINT_POS_P_expn(prefix,exp) do{__PRINT_POS_P_exp(prefix,exp);fprintf(stderr,"\n");}while(0)29 #define __ASSERT(exp) do{if (exp){}else{__PRINT_POS_P_expn("ASSERT ERROR",exp);}}while (0)30 #define __ASSERT_EXIT(exp) do{if (exp){}else{__PRINT_POS_P_expn("ASSERT ERROR",exp);exit(1);}}while (0)31 32 #define __debug_info_LOG(exp,PREFIX,fmt,...) do{if (exp){__PRINT_POS_P_exp(PREFIX,exp);__debug_info(PREFIX,fmt,__VA_ARGS__);}}while (0)33 34 #define __ASSERT_LOG(exp,fmt,...) __debug_info_LOG(exp,"ASSERT!",fmt,__VA_ARGS__)35 #define __ERROR_LOG(exp,fmt,...) __debug_info_LOG(exp,"ERROR!",fmt,__VA_ARGS__)36 define __BEFORE_LOG(N,fmt,...) do {__debug_info_LOG((N) < __sdebug_time,"BEFORE!",fmt,__VA_ARGS__);__NEXT_DBG_TIME()}while(0) 37 #define __AFTER_LOG(N,fmt,...) do {__debug_info_LOG((N) >= __sdebug_time,"AFTER!",fmt,__VA_ARGS__); __NEXT_DBG_TIME();}while(0) 38 static void __debug_info(const char *prefix,const char *fmt, ...) {39 va_list params; 40 va_start(params, fmt);41 __ASSERT_EXIT((__pdebug_Msg) && (__pdebug_Msg_Size ));42 vsnprintf(__pdebug_Msg, __pdebug_Msg_Size, fmt, params);43 if (prefix){44 fprintf(stderr, " %s %s\n", prefix, __pdebug_Msg);45 }else{46 fprintf(stderr, " %s\n", __pdebug_Msg);47 }48 va_end(params);49 }50 #else51 #define __NOP do{}while(0)52 #define __NEXT_DEBUG_TIME() __NOP53 #define __FUNC_LOGn() __NOP54 #define __FUNC_LOG() __NOP55 #define __PRINT_POS_Sn(exp) __NOP56 #define __PRINT_POS_S(exp) __NOP57 #define __ASSERT(exp) __NOP58 #define __ASSERT_EXIT(exp) __NOP59 #define __debug_info_LOG(exp,PREFIX,fmt,...) __NOP60 #define __ASSERT_LOG(exp,fmt,...) __NOP61 #define __ERROR_LOG(exp,fmt,...) __NOP62 #define __BEFORE_LOG(N,fmt,...) __NOP 63 #define __AFTER_LOG(N,fmt,...) __NOP 64 65 #endif66 #endif

上面

 
1 UNDEBUG_FILE 

是如下用法,如果你觉得加了一对debug信息太乱,那么整体C文件(模块)暂时没错可以如下

1 ...2 #define UNDEBUG_FILE3 #include "debug.h"
1 __FUNC_LOGn();

可以写在每个函数的入口。这对跟踪函数之间的调用很有帮助(注意不是LOG,LOG打印这些就是没事找事了)

1 __PRINT_POS_Sn

主要是,例如指针跑飞,可以在各个地方加插该内容,以判断是否经过该地方。其和

1 __FUNC_LOGn();

输出是一样,但前者不影响sdebug_time。可以给出文件路径,行号,函数名和位置。一些输出情况如下:

1 src/graph.c(90){create_graph_abs_by_ID}: t = 02 src/graph_abstract.c(40){refresh_graph_abs}: t = 03 src/graph_abstract.c(41){refresh_graph_abs}: t = 14 src/graph_abstract.c(41){refresh_graph_abs}|
(1): N = 825 src/graph_abstract.c(42){refresh_graph_abs}: t = 26 src/graph.c(91){create_graph_abs_by_ID}: t = 1

上面的内容就是上述头文件被#include到graph.c ,graph_abstract.c中,对应调用

1 __FUNC_LOGn();2 以及 3  __ASSERT_LOG(1,"N = %d",N);

的结果。需要注意,__ASSERT_LOG,我和传统的__ASSERT是反过来的。此处表示,断言成立下,才LOG信息到stderr中。

1 src/graph_abstract.c(42){refresh_graph_abs}: t = 2

实际上表示对 

1 __sdebug_time

第3次累加的位置。其实比如该文件对应累加

1 __sdebug_time

运行了6000次后才出现某个情况出错,则可以使用

1 __AFTER_LOG

__BEFORE_LOG则是反过来。

1 __ASSERT_LOG
 

这相对F5,F9,F10,仅针对静态代码,进行断点要方便的多。当然你要额外增加一堆if判断,再加F9,我也没意见。哈。

 

vs不支持 __func__ 用 __FUNCTION__ 代替

转载于:https://www.cnblogs.com/youngt/p/3680990.html

你可能感兴趣的文章
ZOJ 1133
查看>>
alibaba / zeus 安装 图解
查看>>
Ubuntu:让桌面显示回收站
查看>>
Android上传头像代码,相机,相册,裁剪
查看>>
git 安装体验
查看>>
Oracle 给已创建的表增加自增长列
查看>>
if 循环
查看>>
uva 111 History Grading(lcs)
查看>>
Python学习week2-python介绍与pyenv安装
查看>>
php判断网页是否gzip压缩
查看>>
一个有意思的js实例,你会吗??[原创]
查看>>
sql server中bit字段实现取反操作
查看>>
Part3_lesson2---ARM指令分类学习
查看>>
jQuery拖拽原理实例
查看>>
JavaScript 技巧与高级特性
查看>>
Uva 11729 Commando War
查看>>
增强学习(一) ----- 基本概念
查看>>
ubuntu下USB连接Android手机
查看>>
C# 语句 分支语句 switch----case----.
查看>>
反射获取 obj类 的属性 与对应值
查看>>