gdb调试的简单回顾

1. 查看寄存器

(gdb) i r
(gdb) i r a                     # 查看所有寄存器(包括浮点、多媒体)
(gdb) i r esp
(gdb) i r pc


2. 查看内存

(gdb) x /wx 0x80040000    # 以16进制显示指定地址处的数据
(gdb) x /8x $esp
(gdb) x /16x $esp+12
(gdb) x /16s 0x86468700   # 以字符串形式显示指定地址处的数据
(gdb) x /24i 0x8048a51      # 以指令形式显示指定地址处的数据(24条)


3. 修改寄存器的值

(gdb) set $v0 = 0x004000000
(gdb) set $epc = 0xbfc00000


4. 修改内存的值

(gdb) set {unsigned int}0x8048a51=0x0
(gdb) set *(unsigned int*)0x8048a54=0x55aa55aa


5. 内存搜索

Usage:
find <start> <end> <count> <value>

(gdb) define find                            
set $ptr = $arg0
set $cnt = 0
while ( ($ptr<=$arg1) && ($cnt<$arg2) )
    if ( *(unsigned int *)$ptr == $arg3 )
        x /wx $ptr
        set $cnt = $cnt + 1
    end
    set $ptr = $ptr + 4
end
end


6. 断点、监测点

(gdb) b *0x80400000
(gdb) watch *(unsigned int *)0xbffff400==0x90909090



九.机器语言工具     

      有一组专用的gdb变量可以用来检查和修改计算机的通用寄存器,gdb提供了目前每一台计算机中实际使用的4个寄存器的标准名字:     
  l   $pc   :   程序计数器     
  l   $fp   :   帧指针(当前堆栈帧)     
  l   $sp   :   栈指针     

  l   $ps   :   处理器状态    


      gdb通常可以捕捉到发送给它的大多数信号,通过捕捉信号,它就可决定对于正在运行的进程要做些什么工作。例如,按CTRL-C将中断信号发送给gdb, 通常就会终止gdb。但是你或许不想中断gdb,真正的目的是要中断gdb正在运行的程序,因此,gdb要抓住该信号并停止它正在运行的程序,这样就可以 执行某些调试操作。     
    
      Handle命令可控制信号的处理,他有两个参数,一个是信号名,另一个是接受到信号时该作什么。几种可能的参数是:     
  l   nostop   接收到信号时,不要将它发送给程序,也不要停止程序。     
  l   stop   接受到信号时停止程序的执行,从而允许程序调试;显示一条表示已接受到信号的消息(禁止使用消息除外)     
  l   print   接受到信号时显示一条消息     
  l   noprint   接受到信号时不要显示消息(而且隐含着不停止程序运行)     
  l   pass   将信号发送给程序,从而允许你的程序去处理它、停止运行或采取别的动作。     
  l   nopass   停止程序运行,但不要将信号发送给程序。     
     
      例如,假定你截获SIGPIPE信号,以防止正在调试的程序接受到该信号,而且只要该信号一到达,就要求该程序停止,并通知你。要完成这一任务,可利用如下命令:     
  (gdb)   handle   SIGPIPE   stop   print    





 小结:常用的gdb命令     
  backtrace   显示程序中的当前位置和表示如何到达当前位置的栈跟踪(同义词:where)     
  breakpoint   在程序中设置一个断点     
  cd   改变当前工作目录     
  clear   删除刚才停止处的断点     
  commands   命中断点时,列出将要执行的命令     
  continue   从断点开始继续执行     
  delete   删除一个断点或监测点;也可与其他命令一起使用     
  display   程序停止时显示变量和表达时     
  down   下移栈帧,使得另一个函数成为当前函数     
  frame   选择下一条continue命令的帧     
  info   显示与该程序有关的各种信息     
  jump   在源程序中的另一点开始运行     
  kill   异常终止在gdb   控制下运行的程序     
  list   列出相应于正在执行的程序的原文件内容     
  next   执行下一个源程序行,从而执行其整体中的一个函数     
  print   显示变量或表达式的值     
  pwd   显示当前工作目录     
  pype   显示一个数据结构(如一个结构或C++类)的内容     
  quit   退出gdb     
  reverse-search   在源文件中反向搜索正规表达式     
  run   执行该程序     
  search   在源文件中搜索正规表达式     
  set   variable   给变量赋值     
  signal   将一个信号发送到正在运行的进程     
  step   执行下一个源程序行,必要时进入下一个函数     
  undisplay   display命令的反命令,不要显示表达式     
  until   结束当前循环     
  up   上移栈帧,使另一函数成为当前函数     
  watch   在程序中设置一个监测点(即数据断点)     
  whatis   显示变量或函数类型 

break   NUM   在指定的行上设置断点。     
    bt   显示所有的调用栈帧。该命令可用来显示函数的调用顺序。     
    clear   删除设置在特定源文件、特定行上的断点。其用法为clear  FILENAME:NUM     
    continue   继续执行正在调试的程序。该命令用在程序由于处理信号或断点而  导致停止运行时。     
    display   EXPR   每次程序停止后显示表达式的值。表达式由程序定义的变量组成。     
    file   FILE   装载指定的可执行文件进行调试。     
    help   NAME   显示指定命令的帮助信息。     
    info   break   显示当前断点清单,包括到达断点处的次数等。     
    info   files   显示被调试文件的详细信息。     
    info   func   显示所有的函数名称。     
    info   local   显示当函数中的局部变量信息。     
    info   prog   显示被调试程序的执行状态。     
    info   var   显示所有的全局和静态变量名称。     
    kill   终止正被调试的程序。     
    list   显示源代码段。     
    make   在不退出   gdb   的情况下运行   make   工具。     
    next   在不单步执行进入其他函数的情况下,向前执行一行源代码。     
    print   EXPR   显示表达式   EXPR   的值。    


jump <linespec>
指定下一条语句的运行点。<linespce>可以是文件的行号,可以是file:line格式,可以是+num这种偏移量格式。表式着
下一条运行语句从哪里开始。
jump <address>
这里的<address>是代码行的内存地址。
注意,jump命令不会改变当前的程序栈中的内容,所以,当你从一个函数跳到另一个函数时,当函数运行完返回时进行弹栈操作时必然会发生错误,可能结果还是非常奇怪的,甚至于产生程序Core Dump。所以最好是同一个函数中进行跳转。

熟悉汇编的人都知道,程序运行时,有一个寄存器用于保存当前代码所在的内存地
址。所以,jump命令也就是改变了这个寄存器中的值。于是,你可以使用“set
$pc”来更改跳转执行的地址。如:
set $pc = 0x485

 set n=4


(gdb) info addr x
Symbol "x" is static storage at address 0x100109d8.
(gdb) info addr z
Symbol "z" is static storage at address 0x100109d0.
(gdb) x /1fw 0x100109d8
0x100109d8 <x>: 39.2314987

在GDB中,你可以随时查看以下三种变量的值:
1、全局变量(所有文件可见的)
2、静态全局变量(当前文件可见的)
3、局部变量(当前Scope可见的)
如果你的局部变量和全局变量发生冲突(也就是重名),一般情况下是局部变量会隐藏全局变量,也就是说,如果一个全局变量和一个函数中的局部变量同名时,如果当前停止点在函数中,用print显示出的变量的值会是函数中的局部变量的值。如果此时你想查看全局变量的值时,你可以使用“::”操作符:
file::variable
function::variable
可以通过这种形式指定你所想查看的变量,是哪个文件中的或是哪个函数中的。例如,查看文件f2.c中的全局变量x的值:
gdb) p 'f2.c'::x

本文转自:

http://blog.chinaunix.net/uid-24174632-id-3435935.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值