1、 线程调试
对线程的调试用的最多的可能是thread命令了,查看程序中有多少线程使用Infothreads。进入到某个线程的内部使用thread count。这样就能够进入到count线程的内部。线程调试中用的最多的还有就是bt命令。这个命令主要是查看线程的桟信息,光看桟信息还是差了点什么。那就是使用frame count命令,这个命令能够在桟帧之间移动,假设要查看这个桟的源码就用到之前我们使用的list。
在frame中使用的多的还有up和down命令,能够顺序切换桟的frame。
GDB可以使用进程号或者是线程号动态的将调试器附加到已经执行的进程上,用ps命令来确定系统上如今执行的程序。
对线程下断点、监视点等都和前面的进程一样。没有不论什么差别。仅仅是假设线程出错。每一个线程里面都会有一个拷贝的errno变量记录了线程的错误。
2、perror或strerror查看错误
perror函数接受一个參数,且没有返回值,它输出字符串,后面跟一个冒号和空格。
strerroràchar *strerror(int errno)以errno做为參数。并返回一个描写叙述错误的字符串。
3、 strace命令和ltrace命令
strace有用程序输出程序进行的各个系统调用及其參数和返回值-o logfile输出到文件。或-s N选项截断为N个字符。多线程中使用-o log –ff切换。将单个子进程的strace输出捕获到一个名为log.xxx的文件里,当中xxx是进程ID。
ltrace显示库调用,而不是系统调用。
ldd命令能够查看可运行程序须要的库文件。
4、 调试GUI程序
调试GUI,启动GDB,这次不同之处在于告诉GDB程序在不同中断窗体中运行。而不是GDB在运行的那个窗体,在窗体中运行tty命令确定窗体的ID号。所以(gdb) tty/dev/pts/X。如今该程序的全部键盘输入和屏幕输出都将在运行窗体。这时能够在运行窗体中运行类似一下功能的命令sleep xxxx,当中xxxx是睡眠,不接收输入。
这样在该窗体中的键盘输入会进入程序。而不是shell命令窗体。
或者使用还有一种方法,让程序先执行,打开还有一个窗体执行gdb。然后附加上这个执行的程序。
5、 调试助跑
5.1 splint的使用
使用splint对程序静态检查。能够对程序包含返回值在内的检查,使用之前先进行安装,debian系统用apt-get install,假设不记得程序的名称。能够使用apt-cache search搜索后再安装。假设是红帽系列应该使用yum命令查找并安装。
该程序提供了几种不同的检查功能。严格控制程度不同分别有standard默认选项,checks是中度检查。strict是高度严格检查。假设使用某个功能使用+,不使用某个功能使用-。比如splint +weak *.c。
put.c
#include <stdio.h>
int main(void)
{
int i;
scanf("%d", &i);
return 0;
}
使用splint检測,默认的话会提示你scanf有返回值。你没有接收,假设使用+weak之后就不会提醒。
5.2 ElectricFence的使用
该软件所提供的功能是内存方面的检查,能够是越界,反复释放,訪问错误。内存泄漏等。内存越界检查在gcc中也提供了这个功能,仅仅是gcc中是以宏的形式表现出来的。
编敲代码的时候有时会把訪问数组的个数弄错,导致越界訪问。越界訪问并不一定表现出不论什么错误。这也是最可怕的,所以使用该软件联合编译会检查你的程序,数组有没有越界,假设越界。编译运行会出现段错误并打印出错误的地方。比如:gcc –g3 –Wall –std=c99 outofband.c –o outofband –lefence。efence默认仅仅捕获越出动态分配区域最右一个元素的读或写。
outofbound.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *a = (int *)malloc(2 * sizeof(int));
for (int i = 0; i <= 2; i++)
{
a[i] = i;
printf("%d\n", a[i]);
}
free(a);
return 0;
}
6、VIM使用技巧
k查询man页中的函数,在程序中直接使用k查看。
gd和gD查找变量声明。
[^D和]^D跳到宏定义。
]d,[d,[D,]D显示宏定义。
总结
假设有不论什么错误,希望大家指正。谢谢