使用 Valgrind 调试 Firefox

此页面是从 MDN 导入的,内容可能已过时

此页面描述了如何使用 Valgrind(特别是其 Memcheck 工具)查找内存错误。

支持的平台

Valgrind 在 Linux 上可以很好地运行桌面版 Firefox,尤其是在 x86 和 x86-64 上。Android 版 Firefox 和 ARMv7 上的 Firefox OS 也应该可以运行,尽管可能不太流畅。理论上,Valgrind 在 Linux 上支持的其他架构(AARCH64、PPC{32,64}、MIPS{32,64}、S390X)也应该可以工作。

MacOS X 10.10(Yosemite),仅限 64 位,可以工作,尽管可能有点不稳定。

  • 预计性能会降低,并且误报错误率会比 Linux 高一些。

  • Valgrind 在 Yosemite 上处理 malloc 区域的方式并不完美。谨慎对待泄漏报告。

  • 已知 Valgrind 会导致内核崩溃,原因不明。

从哪里获取 Valgrind

Linux:直接下载 Valgrind,或使用您发行版的包管理器(如果它有足够新的版本)。

MacOSX:从 SVN 获取 Valgrind 主干 并构建它。不要使用 3.10.x 或任何其他压缩包。

确保您使用的是 Valgrind 3.14 或更高版本,已知版本 3.16.1 可以工作,3.13.0 则不行。较新版本往往与 Firefox 的 JIT 和较新的工具链组件(编译器、libc 和链接器版本)具有更好的兼容性。

基础知识

构建

使用以下选项构建 Firefox,这些选项可以最大限度地提高速度和准确性。

ac_add_options --disable-jemalloc
ac_add_options --disable-strip
ac_add_options --enable-valgrind
ac_add_options --enable-optimize="-g -O2"
ac_add_options --disable-sandbox

运行

请注意,在 Valgrind 下运行的程序比在本地运行的速度慢得多。20 倍或 30 倍的减速并不出奇,而且在 Mac 上比在 Linux 上慢。不要在性能较低的机器上尝试。

Linux

在 Linux 上,使用以下选项运行 Valgrind。

--smc-check=all-non-file --vex-iropt-register-updates=allregs-at-mem-access --show-mismatched-frees=no --read-inline-info=yes

--smc-check--vex-iropt-register-updates 选项是避免 JIT 生成的代码崩溃所必需的。

--show-mismatched-frees 选项是由于 newdelete 的内联不一致(即一个被内联而另一个没有)导致误报的不匹配释放错误所必需的。

--read-inline-info 选项在内联存在的情况下提高了堆栈跟踪的可读性。

此外,请设置以下环境变量。

G_SLICE=always-malloc

这对于使 Gnome 系统库使用普通的 malloc 而不是池分配器是必要的。

Mac

在 Mac 上,使用以下选项运行 Valgrind。

--smc-check=all-non-file --vex-iropt-register-updates=allregs-at-mem-access --show-mismatched-frees=no --dsymutil=yes

--dsymutil 选项可确保堆栈跟踪中存在行号信息。

高级用法

共享抑制文件

/build/valgrind/ 包含 Treeherder 上定期 Valgrind 作业使用的抑制文件。其中一些文件是特定于平台的。

在 Valgrind 下运行 mochitests?

要在 Valgrind 下运行 mochitest,请使用以下命令。

$ ./mach mochitest-plain --debugger="valgrind" --debugger-args="$VALGRIND_OPTIONS" relative/path/to/tests

其中 $VALGRIND_OPTIONS上面描述的选项。您可能还需要 --trace-children=yes 来跟踪子进程。

截至 2014 年 12 月,可以在 Valgrind 上大约 8 个 CPU 小时内完成 mochitests-plain 的完整运行,机器为 Core i4910(Haswell)。最大进程大小为 5.4G,其中约 80% 位于内存中。少量 mochitests 的运行需要更少的内存。

零碎信息

对于未发布的 Linux 发行版(Fedora Rawhide 等),您需要使用 Valgrind 主干构建版本,因为针对最新 gcc 和 glibc 版本的修复程序首先出现在那里。如果没有它们,Memcheck 会出现大量的误报,并且会出现调试信息读取问题。

在 Linux 上,LLVM 在高优化级别下编译的代码会导致 Memcheck 报告错误的未初始化值错误。请参阅 此处 以了解简单的解决方法。在 Mac 上,Valgrind 内置了此解决方法。

您可以通过要求提供相对于源代码树根目录的源文件名来使堆栈跟踪更易于阅读。为此,请使用 --fullpath-after= 指定您不想看到的绝对路径的最右侧部分。例如,如果您的源代码树根目录位于 /home/sewardj/MC-20-12-2014,请使用 --fullpath-after=2014/ 以获取相对于源目录的路径名。

--track-origins=yes 会大大降低 Valgrind 的速度,因此除非您要查找特定的未初始化值错误,否则不要使用它。但是,如果您正在查找此类错误,它非常有用,并且值得等待。

其他帮助

Valgrind 快速入门指南 简短易懂,值得一读。用户手册 也很有用。

如果 Valgrind 断言、崩溃、无法按预期工作或出现其他问题,首先请阅读此页面并确保 Firefox 和 Valgrind 都已正确配置。如果一切正常,请尝试使用 SVN 中的 Valgrind 主干。通常,错误会在大多数用户遇到它们之前在主干中得到修复。如果这不起作用,请考虑 提交错误报告,或给 Julian Seward 或 Nick Nethercote 发送邮件。