Valgrind

Valgrind 是一个程序员工具,可以跟踪 C 和 C++ 程序中的内存相关错误。

提示

您可以在 Valgrind 网站上阅读完整介绍

此页面包含有关如何在 GTK/GNOME 程序中熟练使用 valgrind 的一些技巧。 欢迎添加您自己的技巧或扩展页面以提供更详细的说明。

Memcheck

Memcheck 是主要的 valgrind 工具,它允许检测内存泄漏和其他内存管理错误。 要在 memcheck 下运行一个 gnome 程序,请运行

valgrind \
  --leak-check=full \
  --num-callers=20 \
  --log-file=vgdump.txt\
  your-program

如果您调试的程序使用带有 GModule 的动态加载模块(例如,它具有基于 GModule 的插件系统),您应该使用 G_DEBUG=resident-modules 来确保模块不会被卸载,并且 valgrind 可以在写入其日志时检索函数名称

G_DEBUG=resident-modules valgrind \
  --leak-check=full \
  --num-callers=20 \
  --log-file=vgdump.txt \
  your-program

注意

如果您仍然使用 Autotools 作为您的构建系统,您的二进制文件实际上是一个 libtool 生成的临时包装器,上述命令行将会在您的 shell 上运行 valgrind,这可能不是您想要的。 您需要使用 libtool --mode=execute valgrind ... 代替。

运行程序后,您可以检查 vgdump 文件中的日志。 日志包含与内存相关的问题列表,特别是内存泄漏。 内存泄漏以三种方式标记:确定丢失、可能丢失和仍然可访问。 首先,集中精力处理确定丢失的那些,它们是肯定泄漏的内存——您可以通过传递 --show-leak-kinds=definite 来过滤它们。 对于每个泄漏,valgrind 都会提供一个回溯,让您可以准确地确定泄漏发生的位置,特别是如果您的程序使用调试符号编译,valgrind 会告诉您泄漏的确切行和文件。

抑制文件

GLib 和其他库经常进行一次性分配,这些分配的目的是在您的应用程序的整个生命周期中存在。 这些不是泄漏,但 Valgrind 会将它们标记为泄漏。 为了避免使您的报告混乱,您可以使用“抑制文件”来告诉 Valgrind 消除已知的的一次性分配。 GLib 和 GTK 提供了您可以使用的抑制文件。

假设您的 GLib 和 GTK 安装在 /usr 下,Valgrind 抑制文件位于此处

  • /usr/share/glib-2.0/valgrind/glib.supp

  • /usr/share/gtk-4.0/valgrind/gtk.supp

您可以使用 --suppressions 参数为 memcheck 工具,例如:

valgrind \
  --suppressions=/usr/share/glib-2.0/valgrind/glib.supp \
  --suppressions=/usr/share/gtk-4.0/valgrind/gtk.supp \
  your-gtk-app

提示

您可以使用多个 --suppressions 参数,每个抑制文件一个。

如果您的项目有您希望抑制的自己的一次性分配,您可以按照 Valgrind 文档中的说明编写自己的抑制文件。