【问题标题】:Use valgrind with `R CMD check`将 valgrind 与 `R CMD check` 一起使用
【发布时间】:2023-12-10 10:51:01
【问题描述】:

我想在我的包的测试、示例和小插曲上运行 valgrind。各种消息来源暗示这样做的方法应该是:

R CMD build my-pkg
R CMD check --use-valgrind my-pkg_0.0.tar.gz

R CMD check 似乎运行良好,但没有显示 valgrind 输出的证据,即使在设置环境变量 VALGRIND_OPTS: --memcheck:leak-check=full 之后也是如此。我找到了暗示 R 需要以交互方式运行以使 valgrind 显示输出的来源,但 R -d CMD check(或 R -d "CMD check")似乎是错误的格式。

R -d "valgrind --tool=memcheck --leak-check=full" --vanilla < my-pkg.Rcheck/my-pkg-Ex.R 确实有效,但仅适用于示例文件;我看不到一种简单的方法来针对我的小插曲运行它并测试该测试。

通过 valgrind 运行所有相关脚本的最佳方式是什么?无论如何,我们的目标是将其集成到 GitHub 操作脚本中。

【问题讨论】:

    标签: r unit-testing package valgrind


    【解决方案1】:

    2022 年 3 月编辑:R CMD check 的情况实际上更简单,运行 R CMD check --use-valgrind [other options you may want] 将运行 valgrind 下的测试和示例,然后 附加 标准 valgrind示例输出末尾的摘要( pkg.Rcheck/pkg-Ex.Rout)和测试输出( pkg.Rcheck/tinytest.Rout,因为我使用tinytest)_。现在让我感到困惑的是,valgrind 检测到的错误似乎并没有通过测试。

    分隔符下方的原始答案。


    还有更多内容:您帮助确保 R 构建针对它进行了检测。见Section 4.3.2 of Writing R Extensions

    在安装了 valgrind 的平台上,您可以构建带有额外检测的 R 版本,以帮助 valgrind 检测从 R 堆分配的内存使用中的错误。配置选项是 --with-valgrind-instrumentation=level,其中 level 是 0、1 或 2。Level 0 是默认值,不添加任何内容。级别 1 将检测到未初始化内存的一些使用 117,并且对速度的影响很小(与级别 0 相比)。级别 2 将检测许多其他内存使用错误 118,但在 valgrind 下运行时会使 R 慢得多。将它与 gctorture 结合使用会更有效(甚至更慢)。

    因此,您可能希望自己构建一个 Docker 化的 R 版本,以便从您的 GitHub Action 中调用。我认为 Winston 出色的“相扑”容器也具有 valgrind 构建,因此您也可以尝试一下。超过 4GB 非常大:

    edd@rob:~$ docker images| grep wch     # some whitespace edit out
    wch1/r-debug       latest     a88fabe8ec81      8 days ago     4.49GB
    edd@rob:~$ 
    

    当然,如果你测试依赖包,你也必须让它们进入 valgrind 会话......

    【讨论】:

    • 感谢您的建议。我难以理解的是为什么R -d valgrind 确实能够报告错误,而R CMD check --use-valgrind 却没有。如果 R 使用 --with-valgrind-inst...=2 编译,后者是否能够检测到前者遗漏的错误?
    【解决方案2】:

    不幸的是,根据@dirk-eddelbuettel's suggestion,我发现在 GitHub 操作中对 R 进行 docker 化的学习曲线太陡峭了。

    我想出了将文件 memcheck.R 添加到包含内容的包的根目录的 hacky 方法

    devtools::load_all()
    devtools::run_examples()
    devtools::build_vignettes()
    devtools::test()
    

    (记得添加到.Rbuildignore)。

    然后运行 ​​R -d "valgrind --tool=memcheck --leak-check=full" --vanilla < memcheck.R 似乎可以工作,尽管报告了一些似乎是误报的问题,或者至少是 CRAN 的 valgrind 实施未发现的问题。

    这是一个 example 在 GitHub 操作脚本中的操作。

    (请知道自己在做什么的读者在 cmets 中提出这种方法的缺点!)

    【讨论】:

      最近更新 更多