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

print <expr>
    print /<f> <expr>
<expr>是表达式,是所调试程序的语言的表达式(GDB可以调试多种编程语言);<f>是输出的格式,例如如果要把表达式按16进制的格式输出,那么就是/x。

一、表达式

print和许多GDB的命令一样,可以接受一个表达式,GDB会根据当前的程序运行的数据来计算这个表达式,既然是表达式,那么就可以是当前程序运行中的const常量、变量、函数等内容。可惜的是GDB不能使用你在程序中所定义的宏(因为宏是在编译时就已经展开了的)。表达式的语法应该是当前所调试的语言的语法。   
    在表达式中,有几种GDB所支持的操作符,它们可以用在任何一种语言中。    
    @        是一个和数组有关的操作符,在后面会有更详细的说明。        
    ::         指定一个在文件或是一个函数中的变量。        
    {<type>} <addr>        表示一个指向内存地址<addr>的类型为type的一个对象。

二、程序变量

在GDB中,你可以随时查看以下三种变量的值:
        1、全局变量(所有文件可见的)
        2、静态全局变量(当前文件可见的)
        3、局部变量(当前Scope可见的)        
    如果局部变量和全局变量发生冲突(也就是重名),一般情况下是局部变量会隐藏全局变量,也就是说,用print显示出的变量的值会是函数中的局部变量的值。如果此时想查看全局变量的值,可以使用“::”操作符:    
      file::variable
    function::variable
    可以通过这种形式指定想查看的变量是哪个文件中的或是哪个函数中的。例如,查看文件f2.c中的全局变量x的值:
    (gdb) p 'f2.c'::x    
    当然,“::”操作符会和C++中的发生冲突,GDB能自动识别“::” 是否C++的操作符,所以不必担心在调试C++程序时会出现异常。    
    另外,需要注意的是,如果程序编译时开启了优化选项,那么在用GDB调试被优化过的程序时,可能会发生某些变量不能访问,或是取值错误码的情况。这是因为优化程序会删改你的程序,整理你程序的语句顺序,剔除一些无意义的变量等,所以在GDB调试这种程序时,运行时的指令和所编写指令就有不一样,也就会出现所想象不到的结果。对付这种情况时,可以在编译程序时关闭编译优化。一般来说,几乎所有的编译器都支持编译优化的开关,例如,GNU的C/C++编译器GCC,你可以使用“-gstabs”选项来解决这个问题。关

三、数组

有时候,需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。可以使用GDB的“@”操作符,“@”的左边是第一个内存的地址的值,“@”的右边是想查看内存的长度。例如,程序中有这样的语句:     
        int *array = (int *) malloc (len * sizeof (int));        
    于是,在GDB调试过程中,你可以以如下命令显示出这个动态数组的取值:

p *array@len

@的左边是数组的首地址的值,也就是变量array所指向的内容,右边则是数据的长度,其保存在变量len中,其输出结果,大约是下面这个样子的:    
        (gdb) p *array@len
        $1 = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40}

如果是静态数组的话,可以直接用print数组名,就可以显示数组中所有数据的内容了。

四、输出格式

一般来说,GDB会根据变量的类型输出变量的值。但也可以自定义GDB的输出的格式。例如,想输出一个整数的十六进制,或是二进制来查看这个整型变量的中的位的情况。可以使用GDB的数据显示格式:    
    x 按十六进制格式显示变量。
    d 按十进制格式显示变量。
    u 按十六进制格式显示无符号整型。
    o 按八进制格式显示变量。
    t 按二进制格式显示变量。 
    a 按十六进制格式显示变量。
    c 按字符格式显示变量。
    f 按浮点数格式显示变量。

(gdb) p i
        $21 = 101           
        (gdb) p/a i
        $22 = 0x65        
        (gdb) p/c i
        $23 = 101 'e'        
        (gdb) p/f i
        $24 = 1.41531145e-43        
        (gdb) p/x i
        $25 = 0x65        
        (gdb) p/t i
        $26 = 1100101

五、查看内存

可以使用examine命令(简写是x)来查看内存地址中的值。x命令的语法如下所示:    
    x/<n/f/u> <addr>     
    n、f、u是可选的参数。    
    n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
    f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是s,如果地十是指令地址,那么格式可以是i。
    u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。    
    <addr>表示一个内存地址。

n/f/u三个参数可以一起使用。例如:    
    命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。

六、自动显示

可以设置一些自动显示的变量,当程序停住时,或是在单步跟踪时,这些变量会自动显示。相关的GDB命令是display。
    display <expr> 
    display/<fmt> <expr> 
    display/<fmt> <addr>    
    expr是一个表达式,fmt表示显示的格式,addr表示内存地址,当用display设定好了一个或多个表达式后,只要你的程序被停下来,GDB会自动显示你所设置的这些表达式的值。    
    格式i和s同样被display支持,一个非常有用的命令是:    
       display/i $pc    
    $pc是GDB的环境变量,表示着指令的地址,/i则表示输出格式为机器指令码,也就是汇编。于是当程序停下后,就会出现源代码和机器指令码相对应的情形,这是一个很有意思的功能。    
    下面是一些和display相关的GDB命令:    
    undisplay <dnums...>
    delete display <dnums...>
    删除自动显示,dnums意为所设置好了的自动显式的编号。如果要同时删除几个,编号可以用空格分隔,如果要删除一个范围内的编号,可以用减号表示(如:2-5)    
    disable display <dnums...>
    enable display <dnums...>
    disable和enalbe不删除自动显示的设置,而只是让其失效和恢复。    
    info display
    查看display设置的自动显示的信息。GDB会打出一张表格,向你报告当然调试中设置了多少个自动显示设置,其中包括,设置的编号,表达式,是否enable。

gdb 调试(查看运行时数据) 四的更多相关文章

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

    查看栈信息 当程序被停住了,首先要确认的就是程序是在哪儿被断住的.这个一般是通过查看调用栈信息来看的.在gdb中,查看调用栈的命令是backtrace,可以简写为bt. (gdb) bt    #0 ...

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

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

  3. 【JVM第四篇--运行时数据区】堆

    写在前面的话:本文是在观看尚硅谷JVM教程后,整理的学习笔记.其观看地址如下:尚硅谷2020最新版宋红康JVM教程 一.堆的概述 JVM的运行时数据区如下: 一个Java程序运行起来对应着一个进程(操 ...

  4. JVM详解(四)——运行时数据区-堆

    一.堆 1.介绍 Java运行程序对应一个进程,一个进程就对应一个JVM实例.一个JVM实例就有一个运行时数据区(Runtime),Runtime里面,就只有一个堆,一个方法区.这里也阐述了,方法区和 ...

  5. JVM 专题九:运行时数据区(四)本地方法栈

    1. 本地方法栈 2. 什么是本地方法栈? Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用   本地方法栈,也是线程私有的. 允许被实现成固定或者是可动态拓展的内存大小 ...

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

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

  7. jvm理论-运行时数据区

    三大流行jvm sun HotSpot ibm j9 BEA JRockit Oracle 会基于HotSpot整合 JRockit. jvm运行时数据区 java虚拟机所管理的内存将会包括以下几个运 ...

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

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

  9. Intermediate_JVM 20180306 : 运行时数据区域

    Java比起C++一个很大的进步就在于Java不用再手动控制指针的delete与free,统一交由JVM管理,但也正因为如此,一旦出现内存溢出异常,不了解JVM,那么排查问题将会变成一项艰难的工作. ...

随机推荐

  1. 小程序数组型图片自适应效果的实现(交流QQ群:604788754)

    //本例代码如有问题,请加群,下载今日日期文件,测试.(如对本例有疑问,也可加群咨询群主) WXML: <view class="imgbox"> <block ...

  2. EhLib 的 DbgridEh 影响 其他数据集的Open方法

    DbgridEh 对应数据集ADOTable1,其中有个字段 部门编码,另外增加查找字段比如 部门名称 ADOTable2对应查找数据集,包含 部门编码和 部门名称字段. ADOTable1 打开后, ...

  3. selenium安装后,需要安装浏览器驱动

    google的驱动:chromedriver.exe 驱动版本与chrome版本对应的目录: http://npm.taobao.org/mirrors/chromedriver/2.32/notes ...

  4. DevExpress v17.2新版亮点—ASP.NET篇(一)

    用户界面套包DevExpress v17.2终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress ASP.NET v17.2 的GridView Control. ...

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

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

  6. 安装win8时提不能在gpt磁盘中安装

    首先,你要知道,GPT和NTFS根本就是两码事儿.所谓的GPT,是指可扩展固件接口 (EFI) 使用的磁盘分区架构,是与主启动记录 (MBR) 分区架构相对应的,是一种磁盘分区架构.而ntfs,fat ...

  7. xampp for mac 本地服务器的使用

    1.下载xampp安装包 ,百度搜索下载合适版本安装包 2. 安装.下一步 ...->完成 3. 打开看到xampp启动页面. 打开你安装的路径:我这里的路径是:C:\xampp: 找见xamp ...

  8. java.util.logging

    我们目前记录日志用的最多的就是Apache的log4j,其实java.util本身也提供日志记录功能,即java.util.logging,值得关注的就是它的等级与log4j的等级有所不同: 首先我们 ...

  9. 京东Java面试题(一)

    1.说一下java类集2.字符串哈西相等,equals相等吗?反过来呢?3.Spring的工作原理,控制控制反转是怎么实现的,自己写过滤器过滤编码怎么实现4.框架的源码有没有看过5.动态代理是怎么实现 ...

  10. 【linux】wifi不能使用的问题

    Worked solution (Requirements: kernel >=4.11) : Download driver directory from this repo:https:// ...