[linux]gdb调试

 ---------------------------------------------------

快速入门:

ps aux|grep programname '查看进程ID(pid)

gdb programname

attach pid

b a.cpp:120 '设置断点

c '让程序继续运行

(gdb) shell '切换到shell界面

#exit '重新回到gdb模式

----------------------------------------------------

 一、加载文件

启动GDB的方法有以下几种:

1、>gdb [exe]
2、>gdb pid [pid]
GDB启动时,可以加上一些GDB的启动开关,详细的开关可以用gdb -help查看。我在下面只例举一些比较常用的参数:
        -symbols
         -s
          从指定文件中读取符号表。
         -se file
         从指定文件中读取符号表信息,并把他用在可执行文件中。
        -core
        -c
        调试时core dump的core文件。
        -directory
        -d
        加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。

   二、运行命令

        当以gdb 方式启动gdb后,gdb会在PATH路径和当前目录中搜索的源文件。
        在gdb中,运行程序使用r或是run命令。程序的运行,你有可能需要设置下面四方面的事。

1、程序运行参数。
set args 可指定运行时参数。(如:set args 10 20 30 40 50)
show args 命令可以查看设置好的运行参数。

2、运行环境。
path
可设定程序的运行路径。
show paths 查看程序的运行路径。
set environment varname [=value] 设置环境变量。如:set env USER=hchen
show environment [varname] 查看环境变量。

3、工作目录。
cd
相当于shell的cd命令。
pwd 显示当前的所在目录。

4、程序的输入输出。
info terminal 显示你程序用到的终端的模式。
使用重定向控制程序输出。如:run > outfile
tty命令可以指写输入输出的终端设备。如:tty /dev/ttyb

    三、断线(break / b)

    我们用break命令来设置断点。正面有几点设置断点的方法:
    >break +offset / break -offset 在当前行号的前面或后面的offset行停住。offiset为自然数。
    >break filename:linenum 在源文件filename的linenum行处停住。
    >break filename:function 在源文件filename的function函数的入口处停住。
    >break *address 在程序运行的内存地址处停住。
    >break break命令没有参数时,表示在下一条指令处停住。
    >break ... if 在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。
    查看断点时,可使用info命令,如下所示:(注:n表示断点号)
    >info breakpoints [n]
    >info break [n]

    四、设置观察点(WatchPoint)

     观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:

    watch
    为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。

    rwatch
   当表达式(变量)expr被读时,停住程序。

    awatch
    当表达式(变量)的值被读或被写时,停住程序。

    info watchpoints
    列出当前所设置了的所有观察点。


    五、设置捕捉点(CatchPoint)

    你可设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:

    catch
    当event发生时,停住程序。event可以是下面的内容:
    1、throw 一个C++抛出的异常。(throw为关键字)
    2、catch 一个C++捕捉到的异常。(catch为关键字)
    3、exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用)
    4、fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用)
    5、vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用)
    6、load 或 load 载入共享库(动态链接库)时。(load为关键字,目前此功能只在HP-UX下有用)
    7、unload 或 unload 卸载共享库(动态链接库)时。(unload为关键字,目前此功能只在HP-UX下有用)

   tcatch
   只设置一次捕捉点,当程序停住以后,该点被自动删除。

   六、断点条件(condit)

    在设置断点时,我们提到过可以设置一个条件,当条件成立时,程序自动pause。一般来说,为断点设置一个条件,我们使用if关键词,后面跟其断点条件。 并且,条件设置好后,我们可以用condition命令来修改断点的条件。(只有break和watch命令支持if,catch目前暂不支持if)

    condition [brknum] [expr]
   修改断点号为bnum的停止条件为expression,或者清除断点号为bnum的停止条件。


   还有一个比较特殊的维护命令ignore,你可以指定程序运行时,忽略停止条件几次。
   ignore [brknum] [count]
   表示忽略断点号为bnum的停止条件count次。

   GDB还提供的command命令来设置停止点的运行命令。利用它可以在断点条件达到时批处理一些命令,这对基于GDB的自动化调试是一个强大的支持。

    commands [bnum]
     ... command-list ...
    end

例如:

    break foo if x>0
    commands
        printf "x is %d ",x
       continue
     end
    断点设置在函数foo中,断点条件是x>0,如果程序被断住后,也就是,一旦x的值在foo函数中大于0,GDB会自动打印出x的值,并继续运行程序。

    七、单步调试

    当程序被停住了,你可以用continue命令恢复程序的运行直到程序结束,或下一个断点到来。也可以使用step或next命令单步跟踪程序。
   continue [ignore-count]
   c [ignore-count]
   fg [ignore-count]
恢复程序运行,直到程序结束,或是下一个断点到来。ignore-count表示忽略其后的断点次数。continue,c,fg三个命令都是一样的意思。


    step [count]
单步跟踪,很像.net等工具中的step in。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。

    next [count]
同样单步跟踪,如果有函数调用,他不会进入该函数。很像VC等工具中的step over。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。

   set step-mode
   set step-mode on
打开step-mode模式,于是,在进行单步跟踪时,程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。

    set step-mod off
关闭step-mode模式。

    finish
运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。

    until 或 u
当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。

   stepi 或 si
    nexti 或 ni
单步跟踪一条机器指令。一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令。与之一样有相同功能的命令是 “display/i $pc” ,当运行完这个命令后,单步跟踪会在打出程序代码的同时打出机器指令(也就是汇编代码)

原文地址:https://www.cnblogs.com/linn/p/1490974.html