【问题标题】:Memory/Address Sanitizer vs Valgrind内存/地址消毒剂与 Valgrind
【发布时间】:2023-03-23 01:25:01
【问题描述】:

我想要一些工具来诊断释放后使用错误和未初始化错误。我正在考虑消毒剂(内存和/或地址)和 Valgrind。但我对它们的优缺点知之甚少。谁能说出 Sanitizer 和 Valgrind 的主要特点、区别和优缺点?

编辑:我发现了一些比较,例如:Valgrind 使用 DBI(动态二进制检测)和 Sanitizer 使用 CTI(编译时检测)。无论 Sanitizer 运行速度比 Valgrind (2x) 快得多,Valgrind 都会使程序慢得多 (20x)。如果有人能给我一些更重要的考虑,那将是一个很大的帮助。

【问题讨论】:

    标签: valgrind address-sanitizer memory-sanitizer


    【解决方案1】:

    我想你会发现这个wiki 很有用。

    TLDR 消毒剂的主要优点是

    • 更小的 CPU 开销(Lsan 几乎是免费的,UBsan 是 1.25 倍,Asan 和 Msan 对于计算密集型任务是 2-4 倍,对于 GUI 是 1.05-1.1 倍,Tsan 是 5-15 倍)
    • 检测到的错误类别更广泛(堆栈和全局溢出、返回后使用)
    • 完全支持多线程应用程序(Valgrind 对多线程的支持是个笑话)
    • 内存开销小得多(Asan 最高 2 倍,Msan 最高 3 倍,Tsan 最高 10 倍,比 Valgrind 好得多)

    缺点是

    • 更复杂的集成(您需要教您的构建系统了解 Asan,有时还需要解决 Asan 本身的限制/错误,您还需要使用相对较新的编译器)
    • MemorySanitizer 目前并不容易使用,因为它需要重建 Msan 下的所有依赖项(包括所有标准库,例如 libstdc++);这意味着普通用户只能使用 Valgrind 来检测未初始化的错误
    • 消毒剂通常不能相互组合(唯一支持的组合是 Asan+UBsan+Lsan),这意味着您必须进行单独的 QA 运行才能捕获所有类型的错误

    【讨论】:

    • 请注意,valgrind 正确支持多线程应用程序。但是,只有一个线程同时执行(如此有效,在 valgrind 下运行的应用程序运行起来就像在单核上一样)
    • @phd 是的,这就是我的意思,它们实际上是单线程的。在许多情况下,这是一个性能杀手。
    • 关于 Sanitizer 中的线程安全,我找到了 ThreadSanitizer : clang.llvm.org/docs/ThreadSanitizer.html 。处理多线程执行是否足够好?我可以将 ThreadSanitizer 与其他消毒剂一起使用,例如:MemorySanitizer?
    • @kayas 关于 TSan - 是的,所有消毒剂都完全支持多线程。但请注意,TSan 的开销要高得多(8x CPU),而且它只适用于 x86_64 Linux。
    • @kayas 关于组合消毒剂 - 唯一支持的组合是 ASan+UBSan+LSan。通常人们在每种消毒剂下独立运行他们的软件。这是一个重要的缺点,我会将其添加到列表中。
    【解决方案2】:

    一个很大的区别是包含 LLVM 的 memorythread 清理程序隐式映射大量地址空间(例如,通过在 x86_64 环境中跨 TB 的地址空间调用 mmap(X, Y, 0, MAP_NORESERVE|MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE, -1, 0))。即使它们不一定分配该内存,映射也会对限制性环境造成严重破坏(例如,对 ulimit 值进行合理设置的环境)。

    【讨论】:

    • “浩劫”可能太强了。应用程序会在开始时中止,并显示易于搜索的错误消息,建议用户重置 ulimit
    • @yugr 更改ulimit 有时说起来容易做起来难(尤其是在不受您直接控制的分布式测试环境中);此外,还有其他(可能是病态的情况)希望在valgrind 下运行带有消毒剂的二进制文件,其中测试工具将对该未使用空间的引用视为实际使用(因此需要分配会计空间)。更不用说看到topps 显示124.2t 的进程大小也令人不安/困惑...
    • 嗯,分布式测试环境对于 Valgrind 或任何其他动态工具(是的,我都试过了)来说总是很重要的,所以我不确定消毒剂比其他的更糟糕。清理过的应用程序无法在 valgrind 下运行(存在一些内存冲突)。
    猜你喜欢
    • 2021-03-06
    • 2016-07-28
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 2021-03-07
    • 2021-02-08
    相关资源
    最近更新 更多