gdb 调试(查看运行时数据)(五)
查看栈信息
当程序被停住了,首先要确认的就是程序是在哪儿被断住的。这个一般是通过查看调用栈信息来看的。在gdb中,查看调用栈的命令是backtrace,可以简写为bt。
(gdb) bt
#0 pop () at stack.c:10
#1 0x080484a6 in main () at main.c:12
也可以通过info stack命令实现类似的功能(我更喜欢这个命令):
(gdb) info stack
#0 pop () at stack.c:10
#1 0x080484a6 in main () at main.c:12
查看源程序
当程序断住是,gdb会显示当前断点的位置:
Breakpoint 1, pop () at stack.c:10
10 return stack[top--];
可以用list命令来查看当前断点附近的程序的源代码:
(gdb) list
5 int top = -1;
6
7
8 char pop(void)
9 {
10 return stack[top--];
11 }
12
13 void push(char c)
14 {
list命令后面还可以更一些参数,来显示更多功能:
- <linenum> 行号。
- <+> [offset] 当前行号的正偏移量。
- <-> [offset] 当前行号的负偏移量。
- <filename:linenum> 文件的中的行行。
- <function> 函数的代码
- <filename:function> 文件中的函数。
- <*address> 程序运行时的语句在内存中的地址。
不过,就算有这些信息,查看代码仍然不大方便。现在新版的gdb都带一个tui的功能,可以通过focus命令开启,其主要界面如下:

这个界面比起list来说方便多了,能高亮当前语句的执行位置,步进时也会跟着变化,有点使用Turbo C的感觉。
不知道是不是由于focus比较新的缘故,貌似网上并没有多少文章介绍它,虽然它比较容易上手,但也有不少可以介绍的地方,限于篇幅我这里就不做更多的说明,感兴趣的朋友可以看下gdb的gui用法这篇文章。
查看运行时数据
gdb中查看变量的命令是print,一般用它的简写形式p。它的语法如下:
print [</format>] <expr>
其中参数expr可以是一个变量,也可以是表达式。format表示输出格式,例如,可以用/x来将结果按16进制输出。如下是几个基本的例子:
(gdb) p top
$16 = 1
(gdb) p &top
$17 = (int *) 0x804a014 <top>
(gdb) p 3+2*5
$18 = 13
(gdb) p /x 3+2*5
$19 = 0xd
format的取值范围有如下几种:
- x 按十六进制格式显示变量。
- d 按十进制格式显示变量。
- u 按十六进制格式显示无符号整型。
- o 按八进制格式显示变量。
- t 按二进制格式显示变量。
- a 按十六进制格式显示变量。
- c 按字符格式显示变量。
- f 按浮点数格式显示变量。
查看函数返回值
查看函数返回值是在调试的过程中经常遇到的需求。例如,对于如下函数
int foo()
{
return 100;
}
我们可以以如下方式获取函数的返回值:
(gdb) finish
Run till exit from #0 foo () at main.c:9
main () at main.c:15
15 }
Value returned is $2 = 100
(gdb) p $eax
$3 = 100
(gdb) info registers
eax 0x64 100
查看连续内存
可以使用GDB的"@"操作符查看连续内存,"@"的左边是第一个内存的地址的值,"@"的右边则你你想查看内存的长度。
例如,对于如下代码:int arr[] = {2, 4, 6, 8, 10};,可以通过如下命令查看arr前三个单元的数据。
(gdb) p *arr@3
$2 = {2, 4, 6}
查看内存
可以使用examine命令(简写为x)来查看内存地址中的值。x命令的语法如下所示:
x /<n/f/u> <addr>
- n 表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
- f 表示显示的格式,如果是字符串,则用s,如果是数字,则可以用i。
- u 表示从当前地址往后请求的字节数,默认是4个bytes。(b单字节,h双字节,w四字节,g八字节)
- <addr> 表示一个内存地址。
例如:以两字节为单位显示前面的那个数组的地址后32字节内存信息如下.
(gdb) x /16uh arr
0xbffff4cc: 2 0 4 0 6 0 8 0
0xbffff4dc: 10 0 34032 2052 0 0 0 0
自动显示
在VisualStudio中,可以通过监视窗口动态查看变量的值。在gdb中,也提供了类似的命令display,它的语法是:
display <expr>
display /<fmt> <expr>
display /<fmt> <addr>
expr是一个表达式,fmt表示显示的格式,addr表示内存地址。当你用display设定好了一个或多个表达式后,只要你的程序被停下来(单步跟踪时),GDB会自动显示你所设置的这些表达式的值。
几个相关的命令如下:
- undisplay <dnums...> 不显示dispaly
- delete display [dnums] 删除自动显示,不带dnums参数则删除所有自动显示,也支持范围删除,如: delete display 1,3-5
- disable display <dnums...> 使display失效
- enable display <dnums...> 恢复display
- info display 查看display信息
gdb 调试(查看运行时数据)(五)的更多相关文章
- gdb 调试(查看运行时数据) 四
在使用GDB调试程序时,触发断点后,可以使用print命令(简写为p),或是同义命令inspect来查看当前程序的运行数据.print命令的格式是: print <expr> pri ...
- 014-通过JDB调试,通过HSDB来查看HotSpot VM的运行时数据
一.JDB调试 在预发环境下进行debug时,时常因为工具和环境的限制,导致debug体验非常差,那么有什么方法能够简化我们进行debug的体验吗?JDB就是一种. JDB ...
- JVM 专题十:运行时数据区(五)堆
1. 核心概述 1.1 堆概述 一个进程对应一个jvm实例,一个运行时数据区,又包含多个线程,这些线程共享了方法区和堆,每个线程包含了程序计数器.本地方法栈和虚拟机栈. 一个jvm实例只存在一个堆内存 ...
- jvm入门及理解(五)——运行时数据区(虚拟机栈)和本地方法接口
一.虚拟机栈背景 由于跨平台性的设计,java的指令都是根据栈来设计的.不同平台CPU架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要 ...
- JVM 内存区域 (运行时数据区域)
JVM 内存区域 (运行时数据区域) 链接:https://www.jianshu.com/p/ec479baf4d06 运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内 ...
- JVM系列之四:运行时数据区
1. JVM架构图 Java虚拟机主要分为五大模块:类装载器子系统.运行时数据区.执行引擎.本地方法接口和垃圾收集模块. 2. JDK1.7内存模型-运行时数据区域 根据<Java 虚拟机规范( ...
- JVM 运行时数据区域划分
目录 前言 什么是JVM JRE/JDK/JVM是什么关系 JVM执行程序的过程 JVM的生命周期 JVM垃圾回收 JVM的内存区域划分 一.运行时数据区包括哪几部分? 二.运行时数据区的每部分到底存 ...
- JVM 专题八:运行时数据区(三)虚拟机栈
2.虚拟机栈 1. 概述 1.1 虚拟机栈出现背景 由于跨平台性的设计,java的指令都是根据栈来设计的.不同平台CPU架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编译器容易实现, ...
- JVM运行时数据区--堆
一个进程对应一个jvm实例,一个运行时数据区,又包含多个线程,这些线程共享了方法区和堆,每个线程包含了程序计数器.本地方法栈和虚拟机栈. 核心概述 1.一个jvm实例只存在一个堆内存,堆也是java内 ...
随机推荐
- Openwrt Support MINI-PCIE EC20 (6)
1 Scope of Document This document describes MINI PCIE usb hardware design, for EC20 4G module 2 ...
- 快速切题sgu126. Boxes
126. Boxes time limit per test: 0.25 sec. memory limit per test: 4096 KB There are two boxes. There ...
- 《Python》 面向对象三大特性之继承
一.继承大纲: 继承和抽象(两个概念) 1.单继承: 语法: 父类.基类.超类 子类.派生类 继承与重用:子类可以使用父类中的名字(变量和方法) 继承与派生:子类在父类的基础上又新创建了自己需要的方法 ...
- windows下清除svn密码
刚进公司的时候没有SVN账号,暂用别人的账号很平常,为了更好的代码管理,后面肯定用自己的账号. 那么怎么清除呢. 进入 C:\Documents and Settings\Administrator\ ...
- docker-compose工具
环境:CentOS7.0 安装版本:1.3.2 参考资料:https://docs.docker.com/compose/install/ 安装方式: [root@Docker ~]#curl -L ...
- SVM的新理解
svm导出的原始问题然后利用KKT条件,为何还需要对偶空间? 一方面,实际上KKT条件怎么得到的?KKT条件的推导是:svm原始问题->极大极小问题(先算极小这步,但极小这步中α是有约束的,不好 ...
- 51Nod:1265 四点共面
计算几何 修改隐藏话题 1265 四点共面 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出三维空间上的四个点(点与点的位置均不相同),判断这4个点 ...
- .Net Core:部署应用
实战Asp.Net Core:部署应用 1.前言 某一刻,你已经把 .Net Core 的程序写好了.接下来,还可以做什么呢?那就是部署了. 作为一名开发工程师,如果不会部署自己开发的应用,那么这 ...
- Python 操作Excel之通过xlutils实现在保留原格式的情况下追加写入数据
在Python操作Excel 的模块有 xlrd.xlwt.xlutils等. xlrd:读取Excel文件数据 xlwt:写入Excel 数据,缺点是Excel格式无法复用,为了方便用户,写入的话, ...
- C# 处理DateTime算法,取某月第1天及最后一天
代码如下所示: /// <summary> /// 取得某月的第一天 /// </summary> /// <param name="datetime" ...