Debugging 使用valgrind为gdb提供便捷的工作流程

Debugging 使用valgrind为gdb提供便捷的工作流程,debugging,gdb,valgrind,Debugging,Gdb,Valgrind,我正在重新编译调试周期中进行调试,如下所示: 编译二进制文件 运行调试器gdb prog 查找错误并修复源代码 按ctrl+d或键入quit退出调试器 我想在工作流中添加Valgrind,以便在遇到不正确的内存读取或写入超出范围时立即中断。我发现,如果我遵循使用gdb运行Valgrind的过程,我必须执行更多耗时的步骤 编译二进制文件 运行valgrindvalgrind--vgdb=yes--vgdb error=0 prog 打开新终端窗口并键入gdb prog 运行target re

我正在重新编译调试周期中进行调试,如下所示:

  • 编译二进制文件
  • 运行调试器
    gdb prog
  • 查找错误并修复源代码
  • ctrl+d
    或键入
    quit
    退出调试器
我想在工作流中添加Valgrind,以便在遇到不正确的内存读取或写入超出范围时立即中断。我发现,如果我遵循使用gdb运行Valgrind的过程,我必须执行更多耗时的步骤

  • 编译二进制文件
  • 运行valgrind
    valgrind--vgdb=yes--vgdb error=0 prog
  • 打开新终端窗口并键入
    gdb prog
  • 运行
    target remote | vgdb
    (或者,更糟糕的是,如果我正在运行多个调试会话,请为valgrind窗口中打印的连接复制粘贴命令)
  • 查找错误并修复源代码
  • 退出调试器
  • 使用valgrind流程杀死应用程序,使用
    Kill-9
如何使这3个额外步骤自动化?理想情况下,我希望有一个像
mygdb
这样的命令作为
gdb
的替代品,该命令在引擎盖下运行Valgrind,可能调试速度较慢,但一旦Valgrind检测到错误就会中断。

--vgdb error=0指示Valgrind在开始执行程序之前停止,这样您就可以连接到GDB,例如放置断点

但是,如果您只想在检测到错误后进行调试,请给出--vgdb error=1


这样,只要valgrind报告没有错误,就不需要执行粗体的3个步骤,因为valgrind将运行您的程序直到结束并退出

当valgrind遇到错误时停止,您必须启动gdb。 您可以编写一个shell脚本来自动化其他命令的一部分,例如

gdb -ex 'target remote | vgdb'
此脚本可以从日志文件输出或任何其他方式提取vgdb命令

您还可以在.gdbinit中定义一个命令,例如

define vquit
  kill
  quit
end
并使用vquit而不是quit

您还可以定义一个gdb命令,在valgrind下直接启动应用程序并将gdb连接到它,例如:

define vrun
  shell valgrind --vgdb-error=0 $arg0 &
  target remote | vgdb --wait=10
  continue
end
然后在gdb中,您可以执行以下操作:

(gdb) vrun your_application
如何使这3个额外步骤自动化

不是对你的问题的直接回答,但你的整个方法可能是错误的

您不应该使用调试器告诉您错误;改用单元测试。您的周期应该是
make&&make check

它还有助于在实现任何新功能之前编写测试(请参见测试驱动开发)。测试将失败,然后您将通过实现新特性使其成功

此外,您应该养成使用地址和内存清理器运行所有测试的习惯(它们一起捕获的bug比valgrind多得多)


最后,
valgrind
报告本身通常提供足够的信息来理解bug。Valgrind与GDB的集成适用于极少数情况,在这种情况下,如果不查看局部变量、参数等的值,就很难理解错误报告。

“只要Valgrind报告没有错误”,这可能永远不会发生,因为在这种情况下我根本不会使用Valgrind。是否也可以使用
vquit
覆盖
ctrl+d
?避免为gdb打开单独的窗口也很好。编辑答案以提供“vrun”gdb用户定义的功能,从单个窗口启动和调试。当然,您可能希望扩展启动应用程序的方式,例如重定向输出和/或输入。我有单元测试,但它们会因segfault而失败。这就是我决定使用valgrind的原因