查看栈信息

当程序被停住了,首先要确认的就是程序是在哪儿被断住的。这个一般是通过查看调用栈信息来看的。在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;
    }

我们可以以如下方式获取函数的返回值:

1. 通过finish命令运行至函数结束,此时会打印函数返回值。

(gdb) finish
    Run till exit from #0 foo () at main.c:9
    main () at main.c:15
    15 }
    Value returned is $2 = 100

2. 返回值会存储在eax寄存器中,通过查看信息可以获取返回值。

(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 调试(查看运行时数据)(五)的更多相关文章

  1. gdb 调试(查看运行时数据) 四

    在使用GDB调试程序时,触发断点后,可以使用print命令(简写为p),或是同义命令inspect来查看当前程序的运行数据.print命令的格式是: print <expr>    pri ...

  2. 014-通过JDB调试,通过HSDB来查看HotSpot VM的运行时数据

    一.JDB调试        在预发环境下进行debug时,时常因为工具和环境的限制,导致debug体验非常差,那么有什么方法能够简化我们进行debug的体验吗?JDB就是一种.        JDB ...

  3. JVM 专题十:运行时数据区(五)堆

    1. 核心概述 1.1 堆概述 一个进程对应一个jvm实例,一个运行时数据区,又包含多个线程,这些线程共享了方法区和堆,每个线程包含了程序计数器.本地方法栈和虚拟机栈. 一个jvm实例只存在一个堆内存 ...

  4. jvm入门及理解(五)——运行时数据区(虚拟机栈)和本地方法接口

    一.虚拟机栈背景 由于跨平台性的设计,java的指令都是根据栈来设计的.不同平台CPU架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要 ...

  5. JVM 内存区域 (运行时数据区域)

    JVM 内存区域 (运行时数据区域) 链接:https://www.jianshu.com/p/ec479baf4d06 运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内 ...

  6. JVM系列之四:运行时数据区

    1. JVM架构图 Java虚拟机主要分为五大模块:类装载器子系统.运行时数据区.执行引擎.本地方法接口和垃圾收集模块. 2. JDK1.7内存模型-运行时数据区域 根据<Java 虚拟机规范( ...

  7. JVM 运行时数据区域划分

    目录 前言 什么是JVM JRE/JDK/JVM是什么关系 JVM执行程序的过程 JVM的生命周期 JVM垃圾回收 JVM的内存区域划分 一.运行时数据区包括哪几部分? 二.运行时数据区的每部分到底存 ...

  8. JVM 专题八:运行时数据区(三)虚拟机栈

    2.虚拟机栈 1. 概述 1.1 虚拟机栈出现背景 由于跨平台性的设计,java的指令都是根据栈来设计的.不同平台CPU架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编译器容易实现, ...

  9. JVM运行时数据区--堆

    一个进程对应一个jvm实例,一个运行时数据区,又包含多个线程,这些线程共享了方法区和堆,每个线程包含了程序计数器.本地方法栈和虚拟机栈. 核心概述 1.一个jvm实例只存在一个堆内存,堆也是java内 ...

随机推荐

  1. learning scala 操作符

    scala 操作符: 算术运算符:  +  - *  / % 关系统运算符: > , < ,= ,!= ,>=,<=, 逻辑运算符: && . || , ! 位 ...

  2. Vue SSR的渲染性能

    一.前言 前端技术年年有新宠,Vue.js 2.0以其轻量级.渐进式.简洁的语法在MVVM框架中脱颖而出,一经推出便很受业界青睐. 为了提高首屏渲染速度 缓存+直出 是必不可少的.在Vue 1× 时代 ...

  3. Python Threading多线程简单例子

    业务监控,多线程例子,实现每类个监控项的不同监控间隔. #coding=utf-8import sysimport pymysqlimport osfrom prometheus_client imp ...

  4. Spring-data-jpa详解

    转自:http://www.cnblogs.com/dreamroute/p/5173896.html

  5. 【转】Linux编程之UDP SOCKET全攻略

    转自:http://www.cnblogs.com/skyfsm/p/6287787.html?utm_source=itdadao&utm_medium=referral 这篇文章将对lin ...

  6. 【DevExpress v17.2新功能预告】WinForms上的图表增强

    在WinForms Charts v17.2中,我们新增了一些有用的功能,开发人员和最终用户可能都会喜欢. 基于标准的过滤 Chart控件已经支持一系列的过滤,但是在这个版本中,我们用FilterCr ...

  7. 【DevExpress v17.2新功能预告】DevExtreme TreeList

    在即将到来的v17.2中,您可以查看到DevExtremeHTML5 TreeList小部件的这些新功能. 1. 递归选择模式 TreeList将包括一个新的递归选择模式,您只需一次点击即可选择或取消 ...

  8. 【笔记】《深入浅出MFC》第6章 MFC程序的生死因果

    一.头文件说明 STDAFX.H 这个文件用来作为Precompile header file,其内只是载入其他的MFC头文件.应用程序通常会准备自己的头STDAFX.H. AFXWIN.H 每一个W ...

  9. VS2012调用64位IIS Express

    在注册表键HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0\WebProjects下添加DWORD "Use64BitIISExp ...

  10. Python 文件路径

    # 文件路径: # 1. 相对路径: 相对于当前程序所在的文件夹, 如果在文件夹内, 随便找, 直接写名字 # 如果不在这个文件夹内, 可能需要出文件夹或者进文件夹 # 出文件夹 ../ # 进文件夹 ...