gdb使用笔记(一)

一、编译生成可调试的执行程序

  • example: test.c
    下面展示一些 内联代码片
// An highlighted block
#include <stdlib.h>
#include <stdio.h>

int main() {
    int i;
    int array[7] = {1, 2, 3, 4, 5, 6, 7};
    printf("Hi April ! \n");
    for(i=0; i<sizeof(array); i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
    printf("Bye April \n");

    return 0;
}
  • 执行 gcc test.c -o test -g / gcc test.c -og test
  • 执行 ll 看到除了生成执行文件 test 外,还生成了调试文件 g
总用量 56
drwxrwxr-x  3 gaochzh gaochzh  4096 12月  8 15:30 ./
drwxrwxrwx 10 gaochzh gaochzh  4096 12月  8 14:38 ../
-rwxrwxr-x  1 gaochzh gaochzh 16784 12月  8 15:07 g*
-rwxrwxr-x  1 gaochzh gaochzh 19344 12月  8 14:55 test*
-rw-rw-r--  1 gaochzh gaochzh   214 12月  8 15:34 test.c
drwxrwxr-x  2 gaochzh gaochzh  4096 12月  8 15:30 .vscode/

二、进入调试模式

  gdb -tui test -quiet 
  • -tui : 可以在运行的同时显示代码,也可以不带此参数,进入 gdb 后,输入 focus / layout (未生效)
  • -quiet / -q / -silent : 取消启动 GDB 调试器时打印的介绍信息和版权信息

在这里插入图片描述

三、基本的操作指令

3.1、显示代码

  • list / l :
    • 显示test.c中的main函数附近的代码:
      	(gdb)list test.c:main
      	(gdb)l test.c:main
      
    • 显示main函数附近的代码:
      	(gdb)list main
      	(gdb)l main
      
    • 显示test.c中的第3到10行的代码:
      	(gdb)list test.c:3,10
      	(gdb)l test.c:3,10
      
    • 显示第3到10行的代码:
      	(gdb)list 3, 10
      	(gdb)l list 3, 10
      
    • ps: 如已使用了参数: -tui 或者执行了: focus 上述操作仍有效。

3.2、设置断点

  • 以行号设置断点

    	(gdb)break 7
    	(gdb)b 7
    
  • 以函数名设置断点

    	(gdb)break function_name
    	(gdb)b function_name
    
  • 以条件表达式设置断点

    	(gdb)break 7 if i==99
    	(gdb)b 7 if i==99
    
  • 以表达式设置断点的方法

    	(gdb)watch i==99
    	
    	这个命令必须在变量 i 被定义之后才会成功运行。可以在变量 i 被定义的后一行设置中断,然后使用 run 命令运行程序,程序暂停后就可以使用 watch i==99 设置断点了。
    
  • 查看当前设置的断点信息

    	(gdb)info breakpoints
    
  • 使中断失效(断点仍然存在)或有效

    	(gdb)info breakpoints
    	(gdb)disable b_id           //使中断失效,b_id 为中断编号
    	(gdb)info breakpoints
    	(gdb)enable b_id         	//使中断有效,b_id 为中断编号
    	(gdb)info breakpoints
    
  • 删除断点

    	clear : 		删除程序中所有的断点
    	clear 行号 : 	删除这行的断点
    	clear 函数名 : 	删除该函数的断点
    	delete b_id1 b_id2 ... : 删除指定编号的断点
    

3.3、运行程序

  • 单步执行
    	(gdb)next
    	(gdb)n
    
  • 执行被调试的程序,其会自动在第一个断点处暂停执行
    	(gdb) run
    	(gdb) r
    
  • 继续执行被调试的程序。当程序在某一断点处停止运行后,使用该指令可以继续执行,直至遇到下一个断点或者程序结束
    	(gdb) continue
    	(gdb) c
    

3.4、查看和设置变量值

  • print

    • 命令格式
      	(gdb)print ×××
      	(gdb)p ××
      
    • 操作符
      • @ 是一个和数组有关的操作符
      	(gdb)print array@len
      	
      	array 为数组的其实地址,len 为需要打印的长度(可以缺省),如
      	(gdb)print array[1]@2	// 打印数组 array 第二,第三的元素
      	(gdb)print array	// 打印数组 array 所有元素
      
      • :: 指定一个在文件或是一个函数中的变量
      	(gdb)print file::variable	// 打印文件 file 中的全局变量 variable
      	(gdb)print function::variable	// 打印函数 function 中的局部变量 variable
      
      	ps: 如果你的局部变量和全局变量发生冲突(也就是重名),一般情况下是局部变量会隐藏全局变量。
      	ps: 如果程序编译时开启了优化选项,在用GDB调试被优化过的程序时,可能会发生某些变量不能访问,或是取值错误码的情况,需要在编译程序时关闭编译优化。可以使用“-gstabs” 选项来解决这个问题。
      
    • 格式输出
      • /x 以十六进制的形式打印出整数
      • /d 以有符号、十进制的形式打印出整数
      • /u 以无符号、十进制的形式打印出整数
      • /o 以八进制的形式打印出整数
      • /t 以二进制的形式打印出整数
      • /c 以字符形式打印变量或表达式的值
      • /f 以浮点数的形式打印变量或表达式的值
      	(gdb)print/x i	// 以十六进制的形式打印变量 i
      
  • whatis 命令:显示某个变量或表达式值的数据类型

    	(gdb)whatis i	// type = int 需要在变量 i 初始化后裁可以查看
    
  • display 命令:

    • 与print 命令一样,display 命令也用于调试阶段查看某个变量或表达式的值,区别是:使用 display 命令查看变量或表达式的值,每当程序暂停执行(如单步执行)时,GDB 调试器都会自动帮我们打印出来,而 print 命令则不会。也就是说,使用 1 次 print 命令只能查看 1 次某个变量或表达式的值,而同样使用 1 次 display 命令,每次程序暂停执行时都会自动打印出目标变量或表达式的值。因此,当我们想频繁查看某个变量或表达式的值从而观察它的变化情况时,使用 display 命令可以一劳永逸。

    • 命令格式

      	(gdb) display expr
      	(gdb) display/fmt expr
      	
      	ps: display 命令和 /fmt 之间不要留有空格。以 /x 为例,应写为 (gdb)display/x expr。
      

      expr 表示要查看的目标变量或表达式;参数 fmt 用于指定输出变量或表达式的格式:

      • /x 以十六进制的形式打印出整数
      • /d 以有符号、十进制的形式打印出整数
      • /u 以无符号、十进制的形式打印出整数
      • /o 以八进制的形式打印出整数
      • /t 以二进制的形式打印出整数
      • /f 以浮点数的形式打印变量或表达式的值
      • /c 以字符形式打印变量或表达式的值
    • 对于使用 display 命令查看的目标变量或表达式,都会被记录在一张列表(称为自动显示列表)中。通过执行info dispaly命令,可以打印出这张表:

      	(gdb) info display
      		Auto-display expressions now in effect:
      		Num Enb Expression
      		2:      y      /t result
      		1:      y      num
      
      • Num 列为各变量或表达式的编号,GDB 调试器为每个变量或表达式都分配有唯一的编号;
      • Enb 列表示当前各个变量(表达式)是处于激活状态还是禁用状态,如果处于激活状态(用 y 表示),则每次程序停止执行,该变量的值都会被打印出来;反之,如果处于禁用状态(用 n 表示),则该变量(表达式)的值不会被打印。
      • Expression 列:表示查看的变量或表达式。
    • 删除

      	(gdb) undisplay num...
      	(gdb) delete display num...
      	
      	ps: 参数 num... 表示目标变量或表达式的编号,编号的个数可以是多个。 如:
      	(gdb) undisplay 1
      	(gdb) info display
      		Auto-display expressions now in effect:
      		Num Enb Expression
      		2:      y      /t result
      
    • 禁用和激活

      	(gdb) disable display num...
      	(gdb) enable display num...
      
      	ps: 参数 num... 表示要激活的变量或表达式的编号,编号的个数可以是多个,表示一次性激活多个变量或表达式。如:
      	(gdb) disable display 2
      	(gdb) info display
      		Auto-display expressions now in effect:
      		Num Enb Expression
      		2:	n	/t result
      
      	(gdb) enable display 2
      	(gdb) info display
      		Auto-display expressions now in effect:
      		Num Enb Expression
      		2:	y 	/t result
      

Continue …

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值