初窥gdb - 01

来源:互联网 发布:java从右截取字符串 编辑:程序博客网 时间:2024/04/29 15:13

阅读GDB中文手册是非常有必要的,如果有时间,更建议阅读《Debugging with gdb》

但手册类的文档多少有点在罗列命令的感觉,阅读性稍差一些。本人最近在学习c++的gdb调试技巧,顺便记下这些学习笔记,并力求简单易懂,循序渐进



初试GDB


我这里做了个简单的测试实验,从一个简单的程序开始学习调试,以熟悉基本的设置断点和观察点。

源文件:main.cpp

int main(){  int array[3]={0, 0, 0}; //数组初始化  for(int i;i<3;i++)   {     array[i]=i;          //数组赋值    }return 0;}


$ 粗体或者 (gdb) 粗体 表示终端或gdb环境下的命令


1.首先不添加调试信息

进行普通的编译,看看会怎么样:

$ g++ main.cpp 

默认输出 a.out 可执行文件

然后启动gdb(命令:gdb <program>):

$ gdb a.out

进入gdb环境

在main函数处添加断点(命令:breakpoint 或 b):

(gdb) b main

Breakpoint 1 at 0x40054a                                                       

运行调试:

(gdb) run

Starting program: /home/kevin/workstation/test/gdb/a.out 
                                                                                                      
Breakpoint 1, 0x000000000040054a in main ()                  

表示停在刚刚设置的断点处

接下来单步执行试试(命令:next 或 n):

(gdb) n

Single stepping until exit from function main,                      
which has no line number information.                                 

说明没有产生关于行信号的调试信息。


2.加上调试信息:

上一段简单解释了不加调试编译选项的后果,接下来我们加上调试选项-g

$ g++ -g main.cpp 

启动gdb:

$ gdb a.out

进入gdb环境

在main函数处添加断点(命令:breakpoint 或 b):

(gdb) b main

Breakpoint 1 at 0x40054e: file main.cpp, line 5.                 (这里可以看到额外的调试信息,main函数体所在文件,所在行数)

然后我试了一下,调试不运行不能设置观察点!

(gdb) watch array[0]

No symbol "array" in current context.                                     
那么我们就先运行调试:

(gdb) run

Starting program: /home/kevin/workstation/test/gdb/a.out 
                                                                                                      
Breakpoint 1, main () at main.cpp:5                                       
5    {                                                                                               

这里表示程序中断在main函数的函数体内开始的地方

接着我们为数组array的三个元素各自设置一个观察点:

(gdb) watch array[0]

Hardware watchpoint 2: array[0]                                              

(gdb) watch array[1]

Hardware watchpoint 3: array[1]                                              

(gdb) watch array[2]

Hardware watchpoint 4: array[2]                                              
由于观察点和断点类似,因此这里从Hardware watchpoint 2开始而不是Hardware watchpoint 1

接下来单步执行(命令: next 或者 n):

(gdb) n

6    int array[3]={0, 0, 0};                                                             
6表示行号

继续单步:

(gdb) n 

Hardware watchpoint 2: array[0]                                              
                                                                                                        
Old value = 4195760                                                                  
New value = 0                                                                              
0x0000000000400564 in main () at main.cpp:6                   
6    int array[3]={0, 0, 0};                                                             

数组初始化,观察点发生变化,值从未初始化值4195760变成初试化值0

继续单步:

(gdb) n

Hardware watchpoint 4: array[2]                                             
                                                                                                     
Old value = 4195408                                                                 
New value = 0                                                                             
main () at main.cpp:8                                                                 
8    for(int i;i<3;i++)                                                                     
这里初始化只显示了array[0]和array[2]的值发生了变化,至于原因并非本文重点,我尝试在附录中进行说明,这里先不提,但至少可以初步推断,在未初始化的时候,array[1]的值就为0。

继续单步:

(gdb) n

10      array[i]=i;                                                                            

(gdb) n

8    for(int i;i<3;i++)                                                                      

(gdb) n

10      array[i]=i;                                                                                                    

(gdb) n

Hardware watchpoint 3: array[1]                                              
                                                                                                        
Old value = 0                                                                                
New value = 1                                                                              
main () at main.cpp:8                                                                  
8    for(int i;i<3;i++)                                                                      


(gdb) n

10      array[i]=i;                                                                                

(gdb) n

Hardware watchpoint 4: array[2]                                           
                                                                                                        
Old value = 0                                                                                
New value = 2                                                                              
main () at main.cpp:8                                                                 
8    for(int i;i<3;i++)                                                                      


(gdb) n
13    return 0;                                                                                     

(gdb) n

14    }                                                                                                

(gdb) n

Watchpoint 2 deleted because the program has left the block in 
which its expression is valid.                                                               
                                                                                                                   
Watchpoint 3 deleted because the program has left the block in 
which its expression is valid.                                                               
                                                                                                                   
Watchpoint 4 deleted because the program has left the block in 
which its expression is valid.                                                               


运行结束。

退出GDB:

<ctl> + d


到此为止,我们熟悉了基本的设断点和观察的用法,这里断点设置以函数名作为参数(main)当然还可有其他变种,比如断行号等,待大家自己尝试。


附录:

1.验证未初始化的数组array的各项元素的值

修改源码:main.cpp

#include<iostream>using std::cout;using std::endl;int main(){int array[3];             //这里不进行初始化for(int i;i<3;i++){  cout<<array[i]<<endl;   //显示数组}return 0;}

$ g++ main.cpp  

$ ./a.out

4196672                
0                              
4196240                


可见array[1]的确为0 。
















0 0
原创粉丝点击