Log_Debug

调试打印文件名等信息                                                            

#define _DEBUG_TRACE_CMH_ 2  
#if 0 != _DEBUG_TRACE_CMH_  
    #include <cstdio>  
#endif  
  
#if 1==_DEBUG_TRACE_CMH_    //普通打印  
    #define TRACE_CMH printf  
#elif 2==_DEBUG_TRACE_CMH_  //打印文件名、行号  
    #define TRACE_CMH(fmt,...) \  
        printf("%s(%d): "##fmt, __FILE__, __LINE__, ##__VA_ARGS__)  
#elif 3==_DEBUG_TRACE_CMH_  //打印文件名、行号、函数名  
    #define TRACE_CMH(fmt,...) \  
        printf("%s(%d)-<%s>: "##fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)  
#else  
    #define TRACE_CMH  
#endif //_TRACE_CMH_DEBUG_  

这段代码中用到了这几个宏:
  1) __VA_ARGS__   是一个可变参数的宏,这个可宏是新的C99规范中新增的,目前似乎gcc和VC6.0之后的都支持(VC6.0的编译器不支持)。宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用。
  2) __FILE__    宏在预编译时会替换成当前的源文件名
  3) __LINE__   宏在预编译时会替换成当前的行号
  4) __FUNCTION__   宏在预编译时会替换成当前的函数名称

函数Trace:

#define FUNC_ENTRY    \
	{\
	printf("FUNC_ENTRY:   %s L#%d \n", __func__, __LINE__);  \
	}
#define FUNC_EXIT    \
	{\
	printf("FUNC_EXIT:   %s L#%d \n", __func__, __LINE__);  \
	}
#define FUNC_EXIT_RC(x)    \
	{\
	printf("FUNC_EXIT:   %s L#%d Return Code : %d \n", __func__, __LINE__, x);  \
	return x; \
	}

只显示文件名,不显示路径                                                      

#include <string.h> //strrchr()函数所需头文件
windows:
#define filename(x) strrchr(x,'\\')?strrchr(x,'\\')+1:x
linux:
#define filename(x) strrchr(x,'/')?strrchr(x,'/')+1:x


Marvell SDK                                                                               

#ifdef LOG_DEBUG

#define filename(x) strrchr(x,'/')?strrchr(x,'/')+1:x
#define my_d(_fmt_, ...)  \
		wmprintf(_fmt_ "\r\n",  ##__VA_ARGS__)
#define my_entry_d(_fmt_, ...)				\
		wmprintf("[%s(%d) - %s] " _fmt_ "\r\n", filename(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
#else
#define my_d(...)
#define my_entry_d(...)
#endif 



我习惯的写法                                                                                 

#ifdef CONFIG_MY_DEBUG
#define LOG(LogTypeString,format,...)  printf("%s[" __FUNCTION__ "] "format, LogTypeString, __VA_ARGS__)
#define CONERR(format,...) LOG("Error:",format,__VA_ARGS__)
#define CONMSG(format,...) LOG("",format,__VA_ARGS__)
#define CONWRN(format,...) LOG("Warn:",format,__VA_ARGS__)
#define CONDBG(format,...) LOG("",format,__VA_ARGS__)
#else
#define LOG(LogTypeString,format,...)
#define CONERR(format,...)
#define CONMSG(format,...)
#define CONWRN(format,...)
#define CONDBG(format,...)
#endif 

配置echo格式                                                                             

echo显示带颜色,需要使用参数-e
格式如下:
echo -e "\033[字背景颜色;文字颜色m字符串\033[0m"
例如: 
echo -e "\033[41;37m TonyZhang \033[0m"
其中41的位置代表底色, 37的位置是代表字的颜色
 注:
1、字背景颜色和文字颜色之间是英文的“""”
2、文字颜色后面有个m
3、字符串前后可以没有空格,如果有的话,输出也是同样有空格
下面看几个例子:

echo -e "\033[30m 黑色字 \033[0m"
echo -e "\033[31m 红色字 \033[0m"
echo -e "\033[32m 绿色字 \033[0m"
echo -e "\033[33m 黄色字 \033[0m"
echo -e "\033[34m 蓝色字 \033[0m"
echo -e "\033[35m 紫色字 \033[0m"
echo -e "\033[36m 天蓝字 \033[0m"
echo -e "\033[37m 白色字 \033[0m"
 
echo -e "\033[40;37m 黑底白字 \033[0m"
echo -e "\033[41;37m 红底白字 \033[0m"
echo -e "\033[42;37m 绿底白字 \033[0m"
echo -e "\033[43;37m 黄底白字 \033[0m"
echo -e "\033[44;37m 蓝底白字 \033[0m"
echo -e "\033[45;37m 紫底白字 \033[0m"
echo -e "\033[46;37m 天蓝底白字 \033[0m"
echo -e "\033[47;30m 白底黑字 \033[0m"
控制选项说明 :
\33[0m 关闭所有属性 
\33[1m 设置高亮度 
\33[4m 下划线 
\33[5m 闪烁 
\33[7m 反显 
\33[8m 消隐 
\33[30m -- \33[37m 设置前景色 
\33[40m -- \33[47m 设置背景色 
\33[nA 光标上移n行 
\33[nB 光标下移n行 
\33[nC 光标右移n行 
\33[nD 光标左移n行 
\33[y;xH设置光标位置 
\33[2J 清屏 
\33[K 清除从光标到行尾的内容 
\33[s 保存光标位置 
\33[u 恢复光标位置 
\33[?25l 隐藏光标 
\33[?25h 显示光标 


字符串转换操作                                                                                               

/*将字符串s转换成相应的十进制整数*/  例如 "10" -> 10
int atoi(char s[])  
{  
    int i;  
    int n = 0;  
    for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)  {  
        n = 10 * n + (s[i] - '0');  
    }  
    return n;  
}  

/*将大写字母转换成小写字母*/  
int tolower(int c)  
{  
    if (c >= 'A' && c <= 'Z')  {  
        return c + 'a' - 'A';  
    }  
    else{  
        return c;  
    }  
}  

//将十六进制的字符串转换成整数  
int htoi(char s[])  
{  
    int i;  
    int n = 0;  
    if (s[0] == '0' && (s[1]=='x' || s[1]=='X'))  {  
        i = 2;  
    }  
    else  {  
        i = 0;  
    }  
    for (; (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z') || (s[i] >='A' && s[i] <= 'Z');++i)  {  
        if (tolower(s[i]) > '9')  {  
            n = 16 * n + (10 + tolower(s[i]) - 'a');  
        }  
        else  {  
            n = 16 * n + (tolower(s[i]) - '0');  
        }  
    }  
    return n;  
}  

// 十六进制数组 -> 字符串
int hex2str(uint8_t *src, char *dst, int len)
{
	int i;
	uint8_t hb;
	uint8_t lb;
	for(i = 0 ; i < len ; i++){
		hb = (src[i] & 0xf0) >> 4;
		if((hb >= 0)&&(hb <= 9))
			hb += 0x30;
		else if((hb >= 10)&&(hb <= 15))
			hb = hb - 10 + 'A';
		else
			return 1;

		lb = src[i] & 0x0f;
		if((lb >= 0)&&(lb <= 9))
			lb += 0x30;
		else if((lb >= 10)&&(lb <= 15))
			lb = lb - 10 + 'A';
		else
			return 1;

		dst[i*2] = hb;
		dst[i*2+1] = lb;
	}
	return 0;
}


// 字符串 -> 16进制
void strToHex(char *pbDest, char *pbSrc, int nLen)
{    
	char h1,h2;    
	char s1,s2;    
	int i;    

	for (i=0; i<nLen; i++){        
		h1 = pbSrc[2*i];        
		h2 = pbSrc[2*i+1];        
		s1 = toupper(h1) - 0x30;        

		if (s1 > 9)        
			s1 -= 7;        
		s2 = toupper(h2) - 0x30;        
		if (s2 > 9)        
			s2 -= 7;        
		pbDest[i] = s1*16 + s2;    
	}
}


输出限制范围内的随机数                                                                                  

static int get_rand(int limit)
{
	int val;
	while (1) {
		val = rand() % limit;
		if (val)
			break;
	}
	return val;
}


另外,关于time_t和tm讲解,有一篇不错的参考文章:

http://blog.csdn.net/luoweifu/article/details/20288549


GDB                                                                                                                                    

参考文章:

GDB十分钟教程:    http://blog.csdn.net/liigo/article/details/582231/

命令 解释 示例
file <文件名>加载被调试的可执行程序文件。
因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径。
(gdb) file gdb-sample
rRun的简写,运行被调试的程序。
如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。
(gdb) r
cContinue的简写,继续执行被调试程序,直至下一个断点或程序结束。(gdb) c
b <行号>
b <函数名称>
b *<函数名称>
b *<代码地址>

d [编号]

b: Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。
其中在函数名称前面加“*”符号表示将断点设置在“由编译器生成的prolog代码处”。如果不了解汇编,可以不予理会此用法。

d: Delete breakpoint的简写,删除指定编号的某个断点,或删除所有断点。断点编号从1开始递增。

(gdb) b 8
(gdb) b main
(gdb) b *main
(gdb) b *0x804835c

(gdb) d

s, ns: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数;
n: 执行一行源程序代码,此行代码中的函数调用也一并执行。

s 相当于其它调试器中的“Step Into (单步跟踪进入)”;
n 相当于其它调试器中的“Step Over (单步跟踪)”。

这两个命令必须在有源代码调试信息的情况下才可以使用(GCC编译时使用“-g”参数)。

(gdb) s
(gdb) n
si, nisi命令类似于s命令,ni命令类似于n命令。所不同的是,这两个命令(si/ni)所针对的是汇编指令,而s/n针对的是源代码。(gdb) si
(gdb) ni
p <变量名称>Print的简写,显示指定变量(临时变量或全局变量)的值。(gdb) p i
(gdb) p nGlobalVar
display ...

undisplay <编号>

display,设置程序中断后欲显示的数据及其格式。
例如,如果希望每次程序中断后可以看到即将被执行的下一条汇编指令,可以使用命令
“display /i $pc”
其中 $pc 代表当前汇编指令,/i 表示以十六进行显示。当需要关心汇编代码时,此命令相当有用。

undispaly,取消先前的display设置,编号从1开始递增。

(gdb) display /i $pc

(gdb) undisplay 1

iInfo的简写,用于显示各类信息,详情请查阅“help i”。(gdb) i r
qQuit的简写,退出GDB调试环境。(gdb) q
help [命令名称]GDB帮助命令,提供对GDB名种命令的解释说明。
如果指定了“命令名称”参数,则显示该命令的详细说明;如果没有指定参数,则分类显示所有GDB命令,供用户进一步浏览和查询。
(gdb) help display

设置某个文件某一行断点:

(gdb) break [<file-name>:]<func-name>
(gdb) break [<file-name>:]<line-num>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值