• gdb学习笔记


    设置断点

    b main; 在main()入口处  

    b 148; 在第148行

    查看断点

    info b

    运行程序

    r

    单条语句执行

    n

    继续运行程序

    c

    打印变量i的值

    p i

    查看函数堆栈

    bt

    退出函数 

    finish

    help命令只是例出gdb的命令种类,如果要看种类中的命令,可以使用help <class> 命令,如:help breakpoints,查看设置断点的所有命令。也可以直接help <command>来查看命令的帮助。

    TAB可补全函数名,命令名

    在gdb中,我们可以有以下几种暂停方式:断点(BreakPoint)、观察点(WatchPoint)、捕捉点(CatchPoint)、信号(Signals)、线程停止(Thread Stops)。如果要恢复程序运行,可以使用c或是continue命令。


    一、设置断点(BreakPoint)
        
        我们用break命令来设置断点。正面有几点设置断点的方法:
        
        break <function> 
            在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名。

        break <linenum>
            在指定行号停住。

        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] 
       

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


    三、设置捕捉点(CatchPoint)

        你可设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:
        
        catch <event>
            当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 <libname> 载入共享库(动态链接库)时。(load为关键字,目前此功能只在HP-UX下有用)
            7、unload 或 unload <libname> 卸载共享库(动态链接库)时。(unload为关键字,目前此功能只在HP-UX下有用)

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

    四、维护停止点

    上面说了如何设置程序的停止点,GDB中的停止点也就是上述的三类。在GDB中,如果你觉得已定义好的停止点没有用了,你可以使用delete、clear、disable、enable这几个命令来进行维护。

        clear
            清除所有的已定义的停止点。

        clear <function>
        clear <filename:function>
            清除所有设置在函数上的停止点。

        clear <linenum>
        clear <filename:linenum>
            清除所有设置在指定行上的停止点。

        delete [breakpoints] [range...]
            删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d。


    比删除更好的一种方法是disable停止点,disable了的停止点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。

        disable [breakpoints] [range...]
            disable所指定的停止点,breakpoints为停止点号。如果什么都不指定,表示disable所有的停止点。简写命令是dis.

        enable [breakpoints] [range...]
            enable所指定的停止点,breakpoints为停止点号。

        enable [breakpoints] once range...
            enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动disable。

        enable [breakpoints] delete range...
            enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动删除。

    查看栈信息
    —————

    当程序被停住了,你需要做的第一件事就是查看程序是在哪里停住的。当你的程序调用了一个函数,函数的地址,函数参数,函数内的局部变量都会被压入“栈”(Stack)中。你可以用GDB命令来查看当前的栈中的信息。

    下面是一些查看函数调用栈信息的GDB命令:

        backtrace 
        bt 
            打印当前的函数调用栈的所有信息。如:
            
            (gdb) bt
            #0  func (n=250) at tst.c:6
            #1  0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30
            #2  0x400409ed in __libc_start_main () from /lib/libc.so.6
            
            从上可以看出函数的调用栈信息:__libc_start_main --> main() --> func()
            

    一、显示源代码

        GDB 可以打印出所调试程序的源代码,当然,在程序编译时一定要加上-g的参数,把源程序信息编译到执行文件中。不然就看不到源程序了。当程序停下来以后,GDB会报告程序停在了那个文件的第几行上。你可以用list命令来打印程序的源代码。还是来看一看查看源代码的GDB命令吧。
        
        list <linenum>
            显示程序第linenum行的周围的源程序。
        
        list <function> 
            显示函数名为function的函数的源程序。
            
        list 
            显示当前行后面的源程序。
        
        list - 
            显示当前行前面的源程序。

    五、强制调用函数

        call <expr>
        表达式中可以一是函数,以此达到强制调用函数的目的。并显示函数的返回值,如果函数返回值是void,那么就不显示。
        
        另一个相似的命令也可以完成这一功能——print,print后面可以跟表达式,所以也可以用他来调用函数,print和call的不同是,如果函数返回void,call则不显示,print则显示函数返回值,并把该值存入历史数据中。

    一、修改变量值

        修改被调试程序运行时的变量值,在GDB中很容易实现,使用GDB的print命令即可完成。如:
        
            (gdb) print x=4
        
        x=4这个表达式是C/C++的语法,意为把变量x的值修改为4,如果你当前调试的语言是Pascal,那么你可以使用Pascal的语法:x:=4。

  • 相关阅读:
    VS Code中Vetur与prettier、ESLint联合使用
    export 和 export default 的区别,exports 与 module.exports的区别
    css clearfix实现
    通过表单自动提交,实现页面转发
    .net webapi后台返回pdf文件流,前端ajax请求下载,空白pdf排错经历
    MS Sql Service 记一次in查询的优化
    MS SQL Service 查看执行计划
    ContOS7挂载硬盘
    centos命令行连接redis服务器
    如何造轮子
  • 原文地址:https://www.cnblogs.com/qqcwannagraduate/p/4683476.html
Copyright © 2020-2023  润新知