什么是GDB:
GDB应用:
静态分析工具与动态分析工具:
GDB启动方式:
GDB启动之后会有一个交互式的命令行,可以输入GDB特定的命令让GDB去工作。
gdb test.out意思是这一次gdb启动关注的是test.out这个进程。
gdb test.out core意思是程序崩溃时产生core文件。
动态连接:
gdb test.out pid意思是gdb去跟踪test.out这个程序文件对应的进程号为pid的进程。
应用示例一:
应用示例二:
实验:
test.c程序如下:
1 #include <stdio.h> 2 #include <unistd.h> 3 4 extern int* g_pointer; 5 extern void func(); 6 7 void test_1() 8 { 9 printf("test_1() : %p ", test_1); 10 } 11 12 void test_2() 13 { 14 printf("test_2() : %p ", test_2); 15 } 16 17 void test_3() 18 { 19 printf("test_3() : %p ", test_3); 20 } 21 22 int main(int argc, char *argv[]) 23 { 24 typedef void(TFunc)(); 25 TFunc* fa[] = {test_1, test_2, test_3}; 26 int i = 0; 27 28 printf("main() : begin... "); 29 30 for(i=0; i<argc; i++) 31 { 32 printf("argv[%d] = %s ", i, argv[i]); 33 } 34 35 for(i=0; i<100; i++) 36 { 37 fa[i%3](); 38 sleep(argc > 1); 39 } 40 41 printf("g_pointer = %p ", g_pointer); 42 43 func(); 44 45 printf("main() : end... "); 46 47 return 0; 48 }
func.c如下:
1 #include <stdio.h> 2 3 int* g_pointer; 4 5 void func() 6 { 7 *g_pointer = (int)"D.T.Software"; 8 9 return; 10 }
test程序直接运行会产生段错误:
如果想使用gdb调试,那么程序编译时需要带上调试信息,即:
gcc -g test.c func.c -o test.out
然后使用命令 ulimit -c unlimited,这条命令的意思就是在程序崩溃的时候产生core文件。
再次运行程序结果如下:
可以看到产生了core文件。
下一步就可以借助gdb进行调试了。
可以看到gdb给我们指出了问题,在func.c的第七行。
g_pointer是指向0地址处的。
单独运行gdb并载入test.out:
输入run,结果如下:
gdb会动态的跟踪进程的执行,发现向0地址写东西会立即告诉我们。
再次进行如下的实验:
ctrl+c可以让test.out进程暂停,如果想继续执行,敲入continue:
gdb动态连接的实验:
先启动test.out进程:
在另一个中端里面使用ps aux查看进程号,然后跟踪这个进程:
attach到test.out进程后,这个进程就暂停执行了。
敲入continue继续执行:
执行到最后结果如下:
gdb断点调试:
软件断点只对加载到内存中执行的程序有效。
在flash中执行的程序只能打硬件断点。
break设置的断点总是有效的,tbreak设置的断点只有一次有效。
断点相关操作:
delete删除断点可以指定断点的号,1,2,n都是短点号。
硬件断点应用:
实验:
run命令启动程序后继续向下执行,start启动程序后立即暂停:
可以看到start启动后自动设置了一个临时断点。停止在了main函数的入口处。
打断点:
next会执行下一条指令。
我们不可能用next一直执行下去,需要有其他的手段。
打印一下i的值:
$1、$2代表第一次打印和第二次打印。
我们将i的值设置为了100,再次执行next:
可以看到执行了两次next之后程序到了第41行。
设置一个一次性断点,并继续执行:
程序到了第43行,但是还没有调用func函数。
我们可以通过命令跳过第43行func函数的执行:
跳过func函数,程序没有崩溃,这说明我们之前的程序崩溃发生在func函数中。
在进行第二次调试:
程序到了第25行,我们通过tbreak打一个断点,通过函数名字打断点,然后continue继续执行:
程序停下来了,停在了func函数的第7行:
在第一次调试时,我们确定了是func函数出现了问题,为了确认就是func函数内部出了问题,现在我们通过return强制func函数返回:
返回后继续执行:
启动第三次调试:
当前系统只支持一个硬件断点。
打硬件断点,并继续执行:
程序停在了func的第七行:
打印并设置g_pointer的值:
敲continue继续执行:
可以看到程序正常结束了,没有产生崩溃。
小结: