GDB调试总结

加入调试信息
      要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如:
            gcc -g hello.c -o hello
            g++ -g hello.cpp -o hello
      如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。
启动GDB
1、gdb
      program也就是你的执行文件,一般在当前目录下。
2、gdb core
      用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。

在GDB中运行程序
      当以gdb 方式启动gdb后,gdb会在PATH路径和当前目录中搜索的源文件,可使用llist命令,看看gdb是否能读到源代码。
      在gdb中,运行程序使用r或是run命令。程序的运行,你有可能需要设置下面四方面的事。
1、程序运行参数。
      set args 可指定运行时参数。(如:set args 10 20 30 40 50)
      show args 命令可以查看设置好的运行参数。
2、运行环境。
      path <dir> 可设定程序的运行路径。
      show paths 查看程序的运行路径。
      set environment varname [=value] 设置环境变量。如:set env USER=hchen
      show environment [varname] 查看环境变量。
3、工作目录。
      cd <dir> 相当于shell的cd命令。
      pwd 显示当前的所在目录。
4、程序的输入输出。
      info terminal 显示你程序用到的终端的模式。
      使用重定向控制程序输出。如:run > outfile
暂停程序执行
      在gdb中,我们可以有以下几种暂停方式:断点(BreakPoint)、观察点(WatchPoint)、捕捉点(CatchPoint)、信号(Signals)、线程停止(Thread Stops)。如果要恢复程序运行,可以使用c或是continue命令。
      当进程被gdb停住时,你可以使用info program 来查看程序的是否在运行,进程号,被暂停的原因。

断点
一、设置断点(BreakPoint)
我们用break命令来设置断点。正面有几点设置断点的方法:
      break
在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名。
      break
在指定行号停住。
      break +offset
      break -offset
在当前行号的前面或后面的offset行停住。offiset为自然数。
break filename:linenum
在源文件filename的linenum行处停住。
      break filename:function
在源文件filename的function函数的入口处停住。
      break *address
在程序运行的内存地址处停住。
      break
break命令没有参数时,表示在下一条指令处停住。
      break … if <condition>…可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。

查看断点时,可使用info命令,如下所示:(注:n表示断点号)
      info breakpoints [n]
      info break [n]

观察点
      观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:
      watch <expr>       为表达式(变量)expr设置一个观察点。一旦表达式值有变化时,马上停住程序。
      rwatch <expr>      当表达式(变量)expr被读时,停住程序。
      awatch <expr>      当表达式(变量)的值被读或被写时,停住程序。
      info watchpoints       列出当前所设置了的所有观察点。

恢复程序运行和单步调试
      当程序被停住了,你可以用continue命令恢复程序的运行直到程序结束,或下一个断点到来。也可以使用step或next命令单步跟踪程序。
            continue [ignore-count]
            c [ignore-count]
            fg [ignore-count]
      恢复程序运行,直到程序结束,或是下一个断点到来。ignore-count表示忽略其后的断点次数。continue,c,fg三个命令都是一样的意思。
      step <count>(单步跟踪),如果有函数调用,他会进入该函数。进入函数的前提是,此函数被编译有debug信息。很像VC等工具中的step in。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。
      next (单步跟踪) ,如果有函数调用,他不会进入该函数。很像VC等工具中的step over。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。
      set step-mode on(打开step-mode模式),于是,在进行单步跟踪时,程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。
      set step-mod off:关闭step-mode模式。
      finish运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。
      untilu当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。
      stepisi
      nextini
      单步跟踪一条机器指令!一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令。与之一样有相同功能的命令是“display/i $pc” ,当运行完这个命令后,单步跟踪会在打出程序代码的同时打出机器指令(也就是汇编代码)
显示源代码
      GDB 可以打印出所调试程序的源代码,当然,在程序编译时一定要加上-g的参数,把源程序信息编译到执行文件中。不然就看不到源程序了。当程序停下来以后,GDB会报告程序停在了那个文件的第几行上。你可以用list命令来打印程序的源代码。

list <linenum>显示程序第linenum行的周围的源程序
list <function>显示函数名为function的函数的源程序
list显示当前行后面的源程序
list -显示当前行前面的源程序
set listsize <count>设置一次显示源代码的行数
show listsize查看当前listsize的设置
list <first>, 显示从first行到last行之间的源代码
list , <last>显示从当前行到last行之间的源代码
list +往后显示源代码

      一般是打印当前行的上5行和下5行,如果显示函数是是上2行下8行,默认是10行,当然,你也可以定制显示的范围,使用以上最后命令可以设置一次显示源程序的行数。
      一般来说在list后面可以跟以下这些的参数:
      <linenum> 行号。
      <+offset> 当前行号的正偏移量。
      <-offset> 当前行号的负偏移量。
      <filename:linenum> 哪个文件的哪一行。
      <function> 函数名。
      <filename:function> 哪个文件中的哪个函数。
      <*address> 程序运行时的语句在内存中的地址。
查看运行时数据
在你调试程序时,当程序被停住时,你可以使用print命令(简写命令为p),或是同义命令inspect来查看当前程序的运行数据。print命令的格式是:
print <expr>
print <f> <expr>
<expr>是表达式,是你所调试的程序的语言的表达式(GDB可以调试多种编程语言),<f>是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x。
一、表达式
      print和许多GDB的命令一样,可以接受一个表达式,GDB会根据当前的程序运行的数据来计算这个表达式,既然是表达式,那么就可以是当前程序运行中的const常量、变量、函数等内容。可惜的是GDB不能使用你在程序中所定义的宏。

10页

help命令
      gdb所支持命令可以使用help命令来查看
      gdb的命令很多,gdb把之分成许多个种类。help命令只是例出gdb的命令种类,如果要看种类中的命令,可以使用help 命令,如:help breakpoints,查看设置断点的所有命令。也可以直接help 来查看命令的帮助。

使用shell命令
      在gdb环境中,你可以执行UNIX的shell的命令,使用gdb的shell命令来完成:
            shell <command string>
      调用UNIX的shell来执行,环境变量SHELL中定义的UNIX的shell将会被用来执行,如果SHELL没有定义,那就使用UNIX的标准shell:/bin/sh。(在Windows中使用Command.com或cmd.exe)

make命令
      make <make-args>
      可以在gdb中执行make命令来重新build自己的程序。这个命令等价于“shell make ”

按回车会直接执行上一条命令
r用来运行程序,如果设置了断点,将会在断点处停止。(running的缩写)
p i显示变量i的当前值,print的缩写

gdb跟踪core
      当我们发生段错误之后不要慌,可以通过该方式来直接定位段错误发生的位置,生成的core相当于案发现场,就好比出车祸了,警察过来记录一样。
      步骤如下:

  1. ulimit -c查看core文件大小
  2. 设置生成core:ulimit -c unlimited
  3. 取消生成core:ulimit -c 0
  4. 打开方式 gdb app core
  5. 打开后会直接显示错误地点,如果没有,可以使用where来告诉错误在哪里

      这里我们会发现一个问题,就是所有生成的core文件都叫做“core”,我们可不可以修改呢?答案是肯定的,方式如下:设置core文件格式:/proc/sys/kernel/core_pattern 文件不能用vi,可以用后面的套路 echo “/corefile/core-%e-%p-%t”>core_pattern
查看出现段错误时函数的调用过程(轨迹)backtrace

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值