在学会了使用GDB启动调试设置gdb调试断点后,为了验证程序的执行结果是否符合预期,经常需要查看和验证一些关键变量的值。

GDB下可以使用 printdisplaycommandinfo 等命令查看变量。

为了便于理解,本文所有内容使用下面的简单 demo 进行举例说明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[])
{
int int_val = 666;
float float_val = 9.9;
const char *const_str = "https://vimjc.com";
int int_array[10] = {0,1,2,3,4,5,6,7,8,9};
char *char_array = NULL;
char_array = (char*)malloc(257);

if(NULL == char_array)
{
return-1;
}

for(int i = 0; i < 256; ++i)
{
char_array[i] = 'a' + (i % 7);
}

char_array[256] = '\0';
delete char_array;
return 0;
}

一、查看普通变量

基本类型变量、数组、字符串等可以使用 print 命令 (缩写形式 p) 快速查看其在当前上下文中的值。

在本文所用 demo 下,p int_val 可查看整型变量 int_val 在内存中的值。

可以在变量名前面加上文件名或函数名限定变量的范围。例如,p 'main'::int_val 表示查看 main 函数中的整型变量 int_val 的值。

当要查看的字符串内容较长时,默认情况下使用 print 命令查看时只会显示前面的 200 个字符,剩下的字符会用 … 表示。

可以在 GDB 下使用 set print elements 0 设置显示字符串内容时不限制长度。当然,也可以通过 set print elements 250 来设置最长显示 250 个字符。

gdb查看变量

如果想一次性查看数组中多个元素的值,可以在数据名后加 @ 并跟上期望查看的元素个数。例如,p *int_array@3 可查看数组 int_array 的前3个元素。

此外,还可以自定义 Linux 环境变量形式 ($ 形式) 的下标变量查看指定数组中指定位置的元素。

下面的gdb教程动图展示了一种快速查看 int_array 数组中最后4个元素的方法。

gdb查看数组变量

二、指定变量输出格式

print 命令默认情况下会根据变量的类型对应的格式打印变量值。如果需要更加灵活的变量打印格式控制,则需要使用格式控制符 (类比 C 语言中的 printf 函数)。

常用的格式控制符包括:

  1. d:按十进制格式打印变量
  2. x:按十六进制格式打印变量
  3. t:按二进制格式打印变量
  4. o:按八进制格式打印变量
  5. f:按浮点数格式打印变量
  6. c:按字符格式打印变量

例如,p/x int_val 可以以十六进制的形式打印整型变量 int_val 的值。但是,使用 p/t float_val 以二进制形式打印浮点型变量 float_val 时,会因为被转换为整型而出错 (二进制 1001 表示9)。这时候,需要用到另外一个查看变量的命令 examine

gdb变量格式输出

examine 命令 (缩写形式 x) 可以查看变量在对应内存地址中的值,其命令格式为:x/[n][f][u] addr

其中,可选参数 n 表示要打印的内存单元个数,默认值为1;f 表示上面介绍的各种格式控制符;u 表示要打印的内存单元长度;addr 表示变量的内存地址 (注意:不能是变量名)。

常用的内存单元包括:b (单字节)、h (双字节)、w (四字节)、g (八字节)。

如果需要以单字节为单位,以二进制的方式打印浮点变量 float_val,可以使用 GDB 命令 x/4tb &float_val;同样地,x/10dw int_array 可以四字节的方法打印以 int_array 地址开始的连续10个内存单元的值 (这正好是整型数组 int_array 10个元素的值)。

gdb打印数组

三、其他查看变量的方法

除了常用的 printexamine 命令外,display 命令可以用于当程序被 GDB 暂停时自动打印某变量的值。

info registers 命令可以查看除浮点寄存器外的所有寄存器值。

扩展阅读:

  1. GDB入门教程之如何使用GDB启动调试
  2. GDB入门教程之暂停程序
  3. GDB入门教程之恢复程序执行

《女程序员说》

原创不易,希望能给小女子的公众号加个关注~