gdb调试工具

# Linux下的编译和调试

gdb工具的使用

编译和调试

生成debug版本可执行文件,用选项-ggdb:

$ gcc filename.c -o filename -g
$ gdb fork

$ gcc -ggdb filename.c  
$ gdb 

进入调试状态(gdb)。


gdb调试命令


file //装入想要调试的可执行文件。
kill //终止正在调试的程序。
list //程序列表并显示行号。
next //执行一行源代码但不进入函数内部。 
step //执行一行源代码而且进入函数内部(单步调试)。 
run //执行当前被调试的程序 (至断点) 
quit //终止 gdb 
watch/display(变量名) //监视/显示变量的值而不管它何时被改变。 
break //在代码里设置断点, 这将使程序执行到这里时被挂起。 
make //使你能不退出 gdb 就可以重新产生可执行文件。 
shell  //使你能不离开 gdb 就执行 UNIX shell 命令。
stop   //停止调试


断点的设置

    break line-number  使程序恰好在执行给定行之前停止。
    break function-name  使程序恰好在进入指定的函数之前停止。
    break line-or-function if condition  如果condition(条件)是真,程序到达指定行或函数时停止。
    break routine-name 在指定例程的入口处设置断点
用break命令(可以简写为b)设置断点,该命令有如下四种形式:  

    break line-number  使程序恰好在执行给定行之前停止。
    break function-name  使程序恰好在进入指定的函数之前停止。
    break line-or-function if condition  如果condition(条件)是真,程序到达指定行或函数时停止。
    break routine-name 在指定例程的入口处设置断点
如果程序是由很多源文件构成的,需要在各个原文件中设置断点,其方法如下:

    break filename:line-number
    break filename:function-name
    break filename:line-or-function-or-routine if expr 
从断点继续运行:continue 

断点的管理

    · 显示当前gdb的断点信息:info break   
        - 以如下的形式显示所有的断点信息:
Num Type Disp Enb Address What 1 breakpoint keep y 0x000028bc in init_random at qsort2.c:155 2 breakpoint keep y 0x0000291c in init_organ at qsort2.c:168   
    · 删除指定的某个断点:delete breakpoint 1   
        - 该命令将会删除编号为1的断点,  
        - 如果不带编号参数,将删除所有的断点:delete breakpoint   
    · 禁止使用某个断点:disable breakpoint 1 该命令将禁止断点 1  
    · 允许使用某个断点:enable breakpoint 1 该命令将允许断点 1    
    · 清除原文件中某一代码行上的所有断点:clean number   
        - number 为原文件的某个代码行的行号  



gdb 应用举例 

下面列出了将被调试的程序。 这个程序被称为 greeting , 它显示一个简单的问候, 再用反序将它列出。 


#include <stdio.h>

void main () 
{ 
    
    char my_string[] = “hello there”; 
 
    my_print (my_string); 
 
    my_print2 (my_string); 

} 

void my_print (char *string) 
{ 
    
    printf (“The string is %s\n”, string); 

} 

void my_print2 (char *string) 
{ 
   
    char *string2; 
    
    int size, i; 
  
    size = strlen (string); 
   
    string2 = (char *) malloc (size + 1); 
 
    for (i = 0; i < size; i++) 
        
        string2[size - i] = string[i]; 
    
    string2[size+1] = ‘\0’; 
   
    printf ("The string printed backward is %s\n", string2); 

} 

· 用下面的命令编译它: 


gcc -o greeting greeting.c 
        · 这个程序执行时显示如下结果: 
  
    The string is hello there 
  
    The string printed backward is 
    · 输出的第一行是正确的, 但第二行打印出的东西并不是我们所期望的反序:The string printed backward is ereht olleh  
    my_print2 函数没有正常工作?  


    · 用gdb 看看问题出在哪儿
        - 键入如下命令:gdb greeting 
            · 注意: 记得在编译 greeting 程序时把调试选项-ggdb打开。
            · 如果你在输入命令时忘了把要调试的程序作为参数传给 gdb , 你可以在 gdb 提示符下用 file 命令来载入它:
(gdb) file greeting  
        - 用 gdb 的 run 命令来运行 greeting  
        - 设一个断点:在 my_print2 函数的 for 语句后设一个断点
            · 在 gdb 提示符下键入 list 命令三次, 列出源代码及其行号。
            · 若要设断点的地方在第24行, 则键入如下命令设置断点: 
(gdb) break 24 
            · 再键入 run 命令
            · 设置一个观察string2[size - i] 变量的值的观察点:
(gdb) watch string2[size - i] 

            · 用 next 命令来一步步的执行 for 循环:
(gdb) next


 gdb跟踪进程

使用gdb调试的时候,gdb只能跟踪一个进程。

 

可以在fork函数调用之前,通过指令设置gdb调试工具跟踪父进程或子进程。

默认情况下gdb是跟踪父进程的。

 

set follow-fork-mode child  //命令设置gdbfork之后跟踪子进程。

set follow-fork-mode parent  //设置跟踪父进程。

 

注意: 一定要在fork函数调用之前设置。




**开源精神**




阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页