• gdb调试命令


    # 重要说明

    (1)  使用GCC进行编译时,需在编译选项中加入"-g"参数

           cc -g main.c -o main
           g++ -g main.cpp -o main

    (2)  使用GCC进行编译时,为了能使指令与源代码对应上,编译选项中不要加入启用优化的"-O"参数

    (3)  使用gdb调试前,要先进入待调试模块所在目录(使得能正确关联到源代码文件)

    (4)  进入gdb调试状态,直接回车表示"重复上一次命令"

    (5)  按上下方向键可以浏览和选择以前输入过的命令

    (6)  gdb中,输入命令时,可以不用打全命令,只用打命令的前几个字符就可以了,当然,命令的前几个字符应该要标志着一个唯一的命令。

          在Linux下,你可以敲击两次TAB键来补齐命令的全称,如果有重复的,那么gdb会把其列出来

    (7)  可从这儿下载最新的gdb [http://www.gnu.org/software/gdb/download/

    # 调试进程

    gdb test         // 调试当前目录下的名为test的可执行程序    输入r,运行程序

    gdb -p PID     // 勾住目标进程进行调试  PID为目标进程ID,可通过ps -ux来查看当前运行的进程

    attach 2146   // 附加到PID为2146的进程上

    detach 2146  // 释放对PID为2146进程的调试

    q                 // 结束gdb调试 [quit]

    # 启动额外参数

    -se symbolfile    // 从指定文件中读取符号表信息,并用在可执行文件中

    -c corefile      // 调试core dump的core文件

    如:gdb gamesvrd.0 -c /data/corefile/core_gamesvrd.0_11833_1358767740  // 需要进入gamesvrd.0的目录

    -d directory    // 加入一个源文件的搜索路径   默认搜索路径是环境变量中PATH所定义的路径

    若当前调试进程的可执行文件目录中有名为.gdbinit文件,在启动调试时会执行该脚本(下面为一个文件内容示例)

    --------------
    b YXSCubeData.cpp : 2653
    c
    --------------

    # 调试

    0. 程序参数

    set args -b -x  // 修改发送给程序的参数,将-b和-x参数发送给程序

    show args       // 显示程序当前的参数

    1. 设置断点  [break]

    b worker.cpp : 45   // 在worker.cpp文件的45行处设置一个断点

    b 45   // 在当前文件的45行处设置一个断点

    b worker.cpp : CWorker::DoWork  // 在worker.cpp文件的DoWork函数起始处设置一个断点

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

    若有命名空间,还应带上命名空间  b worker.cpp : MYPRJ::CWorker::DoWork

    若函数被重载,还应带上参数类型  b worker.cpp : CWorker::DoWork(bool)

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

    b +5  // 在距离当前位置的后5行处设置一个断点

    b -6  // 在距离当前位置的前6行处设置一个断点

    b ... if <条件>  // 条件断点

    例:b worker.cpp : 45 if workerNum==5 

    例:b worker.cpp : CWorker::DoWork if workerNum==5

    2. 查看断点   [info breakpoints]

    i b    // 查看当前所有断点(每个断点都有一个编号)

    3. 禁用/启用断点

    disable 1  // 禁用编号为1的断点

    enable 1   // 启用编号为1的断点

    disable     // 禁用所有断点

    enable      // 启用所有断点

    4. 删除断点  [delete breakpoints]

    d 1   // 删除编号为1的断点

    d      // 删除所有断点

    5. 调试执行控制

    r  // 调试启动进程 [run]

    k  // 结束当前调试的进程 [kill]

    c  // 继续运行 [continue]   相当于vc中的F5

    ctrl+c  // 暂停程序运行

    n  // 单步执行 [next] 相当于vc中的F10

    n 2  // 2为步进数目

    s  // step into到函数内部 相当于vc中的F11

    finish/fin  // step out出函数 相当于vc中的shift+F11

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

    u 145  //执行至145行代码停下 

    6. 查看变量  [print]

    p nSum   // 打印nSum变量的值 

    p /fmt nSum  // 按指定格式打印nSum变量的值

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

    fmt为以下值
    x 十六进制  d 十进制
    u 无符号数  o 八进制
    t 二进制     a 十六进制打印【地址】
    c 字符格式  f 浮点数   s 字符串

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

    p h@10  // 查看数组h的前10个值

    p *bar  // 查看指针bar所指对象内容

    whatis nSum  // 查看变量nSum的类型

    ptype foo   // 查看foo的类型定义

    w exp  // 查看表达式exp的值 [watch]

    7. 修改变量

    p x=4    // 将x的值修改为4

    8. 查看内存

    x/<n/f/u> <addr>

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

    如:x/3uh 0x54320EED

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

    9. 其他调试信息查看

    bt  // 查看堆栈调用 [backtrace]

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

    有时我们通过bt命令,看到的堆栈信息是错乱的(一堆的???),如下:

    针对这种情况,可以采用以下方法来查看堆栈:
    (1) 从ebp获取函数调用堆栈的head指针

    (2) 显示堆栈的heard指针内存块的内容

    (3) 对当前函数返回地址执行info symbol命令,打印出当前函数栈帧信息(含函数名)

    ## 完整的例子:

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

    frame 3  // 跳转到函数堆栈中索引为3的函数上下文

    i reg // 显示寄存器信息 [info]

    i func  // 显示所有的函数名

    i local  // 显示当前函数的所有局部变量的信息

    i prog  // 显示调试程序的执行状态

    10. 代码载入  [程序必须被断点断住]

    Ctrl+ x  Ctrl + a  // 将代码载入到命令行中进行调试

    l  // 载入当前代码行的前后各4行代码 [list]

    l 45  // 显示当前文件按第45行的周围代码

    l worker.cpp : 70 // 显示work.cpp第70行的周围代码

    l worker.cpp : sum // 显示work.cpp中sum函数的周围代码

    l CWorker::DoWork(bool)  // 显示函数名为CWorker::DoWork(bool)的函数的代码

    l 0xabcd1234  //  查看地址为0xabcd1234的周围的代码

    11. 多线程

    i threads  // 显示线程信息

    thread 2   // 切换到线程表中索引为2的线程

    b foo 2  // 在函数foo设置断点,并且只在索引为2的线程中命中

    12. 强制操作

    call A(1,2)  // 强制调用函数A,并输出其返回值

    return   // 使用return命令取消当前函数的执行,并立即返回

    return exp  // 如果指定了exp,那么该表达式的值会被认作函数的返回值

     

    更详细请参考:用GDB调试程序(一)   用GDB调试程序(二)   用GDB调试程序(三)

                       用GDB调试程序(四)    用GDB调试程序(五)   用GDB调试程序(六)  用GDB调试程序(七)

  • 相关阅读:
    20180818
    20200817
    [mac操作]程序运行技巧与注意事项
    [py编程]小白新奇的技巧
    [命令]使用的conda命令大全
    【编程】python文件读写
    latex学习
    [记录]菜鸡划水记录
    【pytorch】pytorch入门学习
    pycharm中出现unresolved reference的解决办法
  • 原文地址:https://www.cnblogs.com/kekec/p/2693548.html
Copyright © 2020-2023  润新知