• GDB 常用选项和调试技巧


    GDB 是一个很好的命令行调试工具,这里对其用法做一些总结,方便查询,不定时更新。

    1.启动 GDB:

    首先使用 gcc 编译源文件时需要添加 -g 或者 -ggdb 选项,假设生成最终的应用程序 test, 启动 gdb 并打开应用程序 test:

    gdb test
    

      或者

    gdb
    #进入gdb 命令行
    (gdb) file test

    2.开启 tui 图形调试模式 (也可直接输入 start 或者 run 启动调试);

      layout src 显示源文件窗口;

      layout asm 显示汇编窗口;

      layout split 显示源代码和汇编窗口;

      layout regs 显示寄存器窗口;

      Ctrl + L 刷新窗口;

      Ctrl + x,再按 1:显示单窗口;

      Ctrl + x,再按 2:显示源代码和汇编窗口;

      Ctrl + x,再按 a:恢复原状;

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

      这里要说明,用 tui 模式调试时如果遇到通过标准输入输出交互的应用程序时,窗口显示会发生错乱,经从网上查找资料得知有如下解决

    方案(引用自 https://bbs.csdn.net/topics/392033826,见 nswcfd 的回答 ):

      (1)首先新打开一个终端,用 tty 命令查看当前终端设备名字,比如 /dev/pts/1;

      (2)然后在 gdb 里面,在使用 run/start 命令运行程序之前,使用 tty <终端名> 设置程序的输出(例如 /dev/pts/1);

      (3)运行程序,这样程序的输出就不会送到 gdb/tui 所在的终端,而是新打开的终端;

      (4)如果程序还需要从标准输入读,注意这会跟 /dev/pts/1 终端的 bash 冲突(因为 bash 也在等待新的命令输入),解决办法是:终端

    /dev/pts/1 里先执行 sleep 10000,让 bash 进程阻塞在 sleep 程序里,这样就可以为 gdb 的程序提供输入了;

      (5)注意,(4)有个缺点, /dev/pts/1 的终端控制信号(例如Ctrl + C)会终止 sleep,却不会终止被 gdb 的程序,要终止该程序需要回到

    gdb 命令行界面输入 quit 命令或者继续执行调试程序直到退出。

      关于这个问题在 https://blog.csdn.net/RichardYSteven RichardYSteven 的文章中有一篇名为 《gdb 重定向标准输出 -- 调试ncurse比较有用

    也有类似解决的方案(文中描述“gdb提供了重定向的方法”,当然是否是 gdb 官方给出的解决方案,我这里查了好久也没有找到官方网站上的原文)。

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

    3.格式化显示结构体

    set print pretty on
    

     然后可以通过 “p” 或者 “print” 来查看结构体,如果是结构体指针,需要在变量前面加取值运算符 “*”。

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

    4.VS Code 调试 C/C++ 时 GDB 的配置方法(确保系统支持 vscode,并且安装 gcc 、gdb,编译链接的 makefile 可以自己写):

    (1) 点击菜单中的“运行”->“打开配置”,打开 launch.json;

    (2) 配置 “ launch.json” 文件,主要是配置 “program” 一项为目标 target 的绝对路径,当然编译的时候肯定要添加 -g 选项;

    (3) 配置 “launch.json” 文件中的 “miDebuggerPath” 为 gdb 的绝对路径,“preLaunchTask” 项为程序执行前的选项;

    (4) 在 “launch.json” 同一目录下建立一个 “tasks.json” ,配置其 “type ” 为 “shell”,“option/cwd” 为 Makefile 所在的目录,

    同时,更改 “label ” 标签名称作为任务名称(这个随意指定);

    (5) 返回 “launch.json” 编辑 “preLaunchTask” 为第 4 步编辑的 “label” 名称。

    此时,按下 F5 之后,程序会先执行 preLaunchTask 指定的这个任务(也就是 tasks.json 配置的 shell 命令),然后

    再启动调试程序。

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

    这里要注意 VSCode 比较新的版本在远程调试连接服务器的时候经常会被qiang,导致无法在目标机器上下载更新包,这里提供一个方法:

    (1) 首先找到vscode输出日志,并将 commit id 拷贝一下(id应该是一串 SHA256 的摘要值);

    (2) 直接在浏览器输入 https://update.code.visualstudio.com/commit:${commit_id}/server-linux-x64/stable,把 ${commit_id} 替换成你自己

    拷贝的 id,然后敲回车,不出意外浏览器应该会下载一个vscode-server-linux-x64.tar.gz的包,下载完毕后将其拷贝到服务器的当前用户

    目录/.vscode-server/bin下,这个目录下面会有几个${commit_id}命名的目录,找到你自己的 ${commit_id}(没有的话手动建立一个目录)

    然后将压缩包解压到${commit_id}/目录下即可,解压完毕后的目录结构是这样的

    .vscode-server

     |---- bin

            |------2d23c42a936dbccab3b06f918cdedd361cc47cd6

        |-------bin

        |-------extensions

        |-------node_modules

        |-------out

        .....

    5.GDB 调试 jni 程序(attach java

    (1) 启动 gdb,然后打开 /usr/bin/java;

    (2) 启动 java 程序,然后在 gdb 中输入 attach xxx(这个进程号);

    (3) 然后在 gdb 中设置 jni 程序中的断点,继续运行 java 程序(此时有可能java程序被阻塞,需要 gdb 运行 continue 命令);

    (4) 运行到断点处时,gdb 会自动命中断点,此时按照常规方式来调试即可。

  • 相关阅读:
    词法分析
    HTTP学习笔记
    Servlet入门
    UDP与TCP的区别
    C语言实现血型查询系统
    Mysql的索引、回表查询及覆盖索引浅析
    ReentranLock浅析
    CAS是个什么鬼?
    synchronize和volatile 小知识点总结
    写一个简单的阻塞队列
  • 原文地址:https://www.cnblogs.com/huowenjie/p/13755722.html
Copyright © 2020-2023  润新知