【问题标题】:Convenient workflow for gdb with valgrind使用 valgrind 实现 gdb 的便捷工作流程
【发布时间】:2021-05-20 12:35:34
【问题描述】:

我正在重新编译-调试循环中进行调试,如下所示:

  • 编译二进制
  • 运行调试器gdb prog
  • 查找错误并修复源
  • ctrl+d 或键入quit 退出调试器

我想在工作流中添加 Valgrind,以便在我遇到不正确的超出范围的内存读取或写入时立即中断。我发现如果我按照officially documented 使用 gdb 运行 Valgrind 的过程,我必须执行更多耗时的步骤。

  • 编译二进制
  • 运行 valgrind valgrind --vgdb=yes --vgdb-error=0 prog
  • 打开新的终端窗口并输入gdb prog
  • 运行target remote | vgdb(或者,更糟糕的是,如果我正在运行多个调试会话,则在 valgrind 窗口中打印的连接的复制粘贴命令)
  • 查找错误并修复源
  • 退出调试器
  • 使用kill -9 使用valgrind 进程终止应用程序 (because Valgrind doesn't stops it on gdb exit)

如何自动执行这 3 个额外步骤?理想情况下,我希望有一个像mygdb 这样的命令作为gdb 的直接替代品,它在后台运行Valgrind,可能调试速度较慢,但​​一旦Valgrind 检测到错误就会中断。

【问题讨论】:

    标签: debugging gdb valgrind


    【解决方案1】:

    --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
    

    【讨论】:

    • “只要 valgrind 没有报告错误”这可能永远不会发生,因为在这种情况下我根本不会使用 Valgrind。是否也可以用vquit 覆盖ctrl+d
    • 最好避免为 gdb 打开单独的窗口。
    • 编辑了答案以提供“vrun”gdb 用户定义的函数来从单个窗口启动和调试。当然,您可能希望扩展启动应用程序的方式,例如重定向输出和/或输入。
    【解决方案2】:

    如何自动化这 3 个额外步骤?

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

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

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

    此外,您应该养成使用 Address 和 Memory Sanitizers 运行所有测试的习惯(它们一起比 valgrind 捕获更多的错误)。

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

    【讨论】:

    • 我有单元测试,但它们因段错误而失败。这就是我决定使用 valgrind 的原因
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    • 2012-12-13
    • 1970-01-01
    相关资源
    最近更新 更多