Using Valgrind with Julia
Valgrind 是一个用于内存调试、内存泄漏检测和性能分析的工具。本节描述了在使用 Valgrind 调试 Julia 的内存问题时需要注意的事项。
General considerations
默认情况下,Valgrind 假设它运行的程序中没有自我修改的代码。这个假设在大多数情况下都能正常工作,但对于像 julia
这样的即时编译器来说却失败得很惨。因此,向 valgrind
传递 --smc-check=all-non-file
是至关重要的,否则代码可能会崩溃或表现出意外的行为(通常是微妙的方式)。
在某些情况下,为了更好地使用 Valgrind 检测内存错误,禁用内存池编译 julia
可能会有所帮助。编译时标志 MEMDEBUG
在 Julia 中禁用内存池,而 MEMDEBUG2
在 FemtoLisp 中禁用内存池。要使用这两个标志构建 julia
,请将以下行添加到 Make.user
:
CFLAGS = -DMEMDEBUG -DMEMDEBUG2
另一个需要注意的事项是:如果您的程序使用多个工作进程,您可能希望所有这些工作进程都在 Valgrind 下运行,而不仅仅是父进程。要做到这一点,请将 --trace-children=yes
传递给 valgrind
。
另一个需要注意的事项是:如果使用 valgrind
时出现 Unable to find compatible target in system image
错误,请尝试使用目标 generic
重新构建 sysimage 或使用 JULIA_CPU_TARGET=generic
重新构建 julia。
Suppressions
Valgrind 通常会在运行时显示虚假警告。为了减少此类警告的数量,向 Valgrind 提供一个 suppressions file 是有帮助的。一个示例抑制文件包含在 Julia 源代码分发中的 contrib/valgrind-julia.supp
。
抑制文件可以从 julia/
源目录使用,如下所示:
$ valgrind --smc-check=all-non-file --suppressions=contrib/valgrind-julia.supp ./julia progname.jl
任何显示的内存错误应被报告为错误或作为额外的抑制进行贡献。请注意,某些版本的 Valgrind 是 shipped with insufficient default suppressions,因此在提交任何错误之前,这可能是需要考虑的一件事。
Running the Julia test suite under Valgrind
可以在 Valgrind 下运行整个 Julia 测试套件,但确实需要相当长的时间(通常几个小时)。要做到这一点,请从 julia/test/
目录运行以下命令:
valgrind --smc-check=all-non-file --trace-children=yes --suppressions=$PWD/../contrib/valgrind-julia.supp ../julia runtests.jl all
如果您想查看“明确”的内存泄漏报告,请将标志 --leak-check=full --show-leak-kinds=definite
传递给 valgrind
。
Additional spurious warnings
本节涵盖了无法添加到抑制文件中的 Valgrind 警告,但这些警告仍然可以安全忽略。
Unhandled rr system calls
Valgrind 会发出警告,如果它遇到任何 system calls that are specific to rr,以及 Record and Replay Framework。特别是,当 julia 尝试检测它是否在 rr 下运行时,将显示关于未处理的 1008
系统调用的警告:
--xxxxxx-- WARNING: unhandled amd64-linux syscall: 1008
--xxxxxx-- You may be able to write your own handler.
--xxxxxx-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--xxxxxx-- Nevertheless we consider this a bug. Please report
--xxxxxx-- it at http://valgrind.org/support/bug_reports.html.
此问题 has been reported 已提交给 Valgrind 开发者,因为他们已提出请求。
Caveats
Valgrind 当前 does not support multiple rounding modes,因此在 Valgrind 下运行的调整舍入模式的代码将表现不同。
一般来说,如果在设置 --smc-check=all-non-file
后发现您的程序在 Valgrind 下运行时表现不同,您可以在进一步调查时将 --tool=none
传递给 valgrind
。这将启用最小的 Valgrind 机制,但运行速度会比启用完整内存检查器时快得多。