vscode + ssh remote + gdb 远程断点调试Linux上的应用程序

1,190 阅读6分钟

为什么用GDB + GUI 的方式进行远程断点调试

在Linux上使用GDB命令调试的各种痛点

在Linux上使用GDB断点调试,原本不是啥新技术,20多年前就有了,以前在学校做单片机开发,也喜欢在windows的IDE上用Jtag/Jlink 仿真器远程单步断点调试单片机上的程序。 但是转行做Linux后,实际工作中,发现同事们很少使用GDB远程调试,都喜欢加一点print打印,重新编译看运行log。 为什么有GDB这种功能丰富强大的工具不用,而选择加打印这种简单粗暴,还需要浪费编译等待时间的方式呢?我一直百思不得其解,直到2020年之后,vscode ssh 远程登录编辑器出现,与GDB结合,完美解决这一痛点,才想明白这问题的逻辑。 最大痛点:不常用的工具,不应该做成复杂的命令行配置,应该做成傻瓜式的GUI,点击鼠标,开箱即用。 Linux 上的GDB最大的问题就是设计过于命令行极客化,不注重打磨用户交互体验,这也是GNU Linux系统上软件的通病,大部分软件是给专业程序员用的,而不是普通用户或者入门者,假定每个用户遇到问题都能靠搜索自己解决。 相对而言单片机 Windows IDE Jtag/JLink远程断点调试就简单易用得多,很多单片机工程师在这套开发环境下,都不需要加打印,可以直接通过仿真模式随意观察任何变量。 当然,有了vscode ssh remote + Linux GDB 这种解决方案以后,我们就可以在Windows 上打开vscode 的界面,用傻瓜化GUI, 远程GDB断点调试Linux 上的程序,而不是一用GDB, 就得去搜索各种命令,配置环境折腾半天。有了它,我就可以把收藏夹中珍藏的100条GDB命令调试小技巧扔进垃圾箱了O(∩_∩)O哈哈~

将注意力集中在代码上而不是各种命令查找环境配置上

对比一下Linux 上命令行gdb 与 vscode ssh remote + linux GDB 的用户体验,就能发现这些问题。

  • Linux 上原生的GDB 命令行操作

linux_gdb_cli.PNG

  • Windows VSCode上傻瓜式GUI的 remote ssh + Linux GDB调试界面

vscode_ssh_gdb.PNG

  • 用户体验对比
    • Linux 上的GDB每次使用都需要去搜索各种命令和参数的用法,用完即忘,下次又得搜,每次使用,首先就把注意力放到了命令查找和环境配置上
    • Windows VScode 上自带GDB 的操作界面,点点GUI 按钮就能执行断点设置,添加变量观察窗,查看栈,单步执行,dump 寄存器等高级操作
    • Linux 上的GDB 命令行, 调试界面和代码界面是分离的,使得用户没法集中注意力,快速定位到关键的代码,需要各种查找,敲入命令才能在相应的代码行打上断点。所以很多老工程师更喜欢在代码里加print打印再重新编译运行,因为这种操作的体验让他们更专注于分析调试代码,而不是搜索各种不熟悉的命令和参数
    • Windows VSCode上的 remote ssh GDB利用了 Windows上优秀的GUI设计体验,让代码和GDB调试在同一个窗口,随时可以点击跳转,查看代码,读取变量的动态值,让工程师更加专注在被调试的代码上,而不是分散注意力去查各种命令参数

综合了用户体验上对比,相信读者也能理解,为什么很多老工程师不喜欢在Linux 上用GDB调试, 宁可加打印print重新编译运行。不是因为Linux GDB本身技术不够强大,而是用户体验反人类,如果好好打磨用户体验,确实是非常强大的调试工具。

使用带GUI的GDB调试的好处

个人认为最大的好处是将Windows IDE + 断点单步远程调试单片机的习惯无缝平移到Linux 嵌入式开发上,更快地上手Linux 开发调试。 在GDB上,可以使用断点,单步等方式调试程序,随时读取或者修改各种变量,观察Stack和CPU各种寄存器的动态状态,适合非常深层的复杂问题debug,不需要加打印重新编译代码,节约了编译拷贝的时间。 Linux GDB 有个 Windows VSCode 的GUI作为强大用户操作前端,解决了用户体验问题,才能让用户更快熟悉上手,提升我们的调试和使用效率,发挥其强大的调试功能。这也是Linux 和 Windows 系统各取所长的一个模范案例。

VSCode Remote ssh + Linux GDB 调试C/C++程序的基本原理

如何配置 VSCode Remote ssh + Linux GDB 调试环境细节网上可以搜到。就不赘述了。

大概环境配置

  • Windows VSCode 上要安装 Remote ssh 和 C++ intelliSense 插件。 C++ intelliSense本身自带一些断点debug等功能,所以不需要配置额外的GDU插件。
  • Linux 上需要安装gdb 或者 gdbserver 调试器
  • VSCode 上需要配置launch.json的远程调试文件,该文件会用模板自动生成,只需要修改调试程序的路径,参数,Linux 上使用的gdb 调试器参数, gdbserver的IP地址端口(可选,只有使用gdbserver才需要)

大概工作原理:

  • VSCode 会以ssh 方式远程登录Linux, 然后使用命令行的方式远程操作Linux 上的本地GDB
  • VSCode GUI起到一个前端的作用,相当于把用户的界面点击操作,转换成GDB命令,用ssh发送给远程Linux 上的GDB执行,封装了用户查找命令的多余操作。

注意事项:

  • 对于嵌入式ARM Linux开发板,应该用VSCode ssh remote 远程登录到ARM Linux开发板上(而不是X86开发机器),并且ARM开发板上本地安装了GDB才能进行调试
  • 可以将X86 Linux开发主机上的代码目录通过NFS的方式导出,ARM Linux 开发板用NFS mount到对应的目录,VSCode ssh remote 登录到ARM Linux开发板,打开相应的NFS Mount目录,就能GUI看代码,GDB调试ARM Linux开发板上的程序了