zoukankan      html  css  js  c++  java
  • gdb调试程序之查看运行时数据【五】

    在用gdb调试程序时,当程序运行到之前设置的断点时,很容易想到的操作就是查看当前变量的值,而gdb可以很轻易地满足的你的需求的~~

    在gdb中最常用的命令就是print(简写p),具体格式如下:

    print <expr>
    print/f <expr>  f代表输出的格式
     x 按十六进制格式显示变量
     d 按十进制格式显示变量
     u 按十六进制格式显示无符号整型
     o 按八进制格式显示变量
     t 按二进制格式显示变量
     a 按十六进制格式显示变量
     c 按字符格式显示变量
     f 按浮点数格式显示变量
    

    表达式

    print命令可以接受表达式,其中表达式的定义遵循C/C++语法,需要注意的是表达式中不能出现程序中定义的宏表达式;同时在gdb表达式中,还支持以下三种特殊的操作符:

    @       是一个和数组有关的操作符,在后面会有更详细的说明
    ::      指定一个在文件或是一个函数中的变量,注意与C++语法中的::操作符的区分
    {}      表示一个指向内存地址的类型为type的一个对象
    

     

    程序变量的定位

    在GDB中,查看以下三种变量的值:
    1、全局变量(所有文件可见的)
    2、静态全局变量(当前文件可见的)
    3、局部变量(当前Scope可见的)

    如果出现局部变量和全局变量相互冲突时,局部变量会覆盖全局变量,可以使用::限制符来查看全局变量

    file::variable
    function::variable
    

    注意事项:如果在编译时加入了编译优化选项,即-O3选项,编译器会修改你的程序,同时可能查看不同某些变量,这时在调试时建议把优化选项关掉,即-O0

    动态数组

    你需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。你可以使用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}
    

    查看内存

    gdb中可以使用examine命令来查看内存内容,简写为x,使用方法如下:

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

    例如

    x/3uh 0x54320  从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示
    

    自动显示

    在gdb中,你可以设置当程序停在断点处时,自动显示变量的内容,即display命令,使用如下:

     display <expr>
     display/<fmt> <expr>
     display/<fmt> <addr>
     expr是一个表达式,fmt表示显示的格式,addr表示内存地址
    

    一个非常有用的命令,显示源码与机器码的对应:

    display/i $pc
    $pc是GDB的环境变量,表示着指令的地址,/i则表示输出格式为机器指令码,也就是汇编。于是当程序停下后,就会出现源代码和机器指令码相对应的情形
    

    与display管理相关的命令:

    undisplay
    delete display
    disable display
    enable display
    info display  查看display设置的自动显示的信息
    

    查看寄存器

    info registers            查看寄存器的情况。(除了浮点寄存器)
    info all-registers        查看所有寄存器的情况。(包括浮点寄存器)
    info registers       查看所指定的寄存器的情况
    
  • 相关阅读:
    python笔记1
    git笔记
    手撸一个简陋直播系统
    spring-boot学习笔记1
    设计模式1--简单工厂模式
    网联:第一章:浏览器生成消息
    php线上预览日志--4.websocket客户端
    php线上预览日志--3.websocket服务部署
    php线上预览日志--2.谷歌插件开发
    php线上预览日志--1.概述
  • 原文地址:https://www.cnblogs.com/yangce/p/2256482.html
Copyright © 2011-2022 走看看