【问题标题】:Detect C/C++ command line memory leaks using Instruments使用 Instruments 检测 C/C++ 命令行内存泄漏
【发布时间】:2020-04-23 23:44:23
【问题描述】:

我正在尝试检测 macOS 上 C(和 C++)程序中的内存泄漏。在 Linux 和 Windows 中,我可以使用 valgrind 轻松做到这一点,但不幸的是,它在 macOS 上不可用。

由于我有 ObjC 和 iOS 开发的背景经验,我想使用 Instruments 来进行内存泄漏检查。乍一看,这听起来很适合这项工作。

我写了这个非常简单的泄露程序:

#include <stdlib.h>
#include <stdio.h>

int* allocSomething() {
  return malloc(sizeof(int));
}

int main(int argc, const char * argv[]) {
  int* p = allocSomething();
  *p = 5;
  printf("*p = %d\n", *p);
  p = NULL;
  return 0;
}

我通过 Clang Static Analyzer 运行它,它完成了这项工作,但我希望它也能在 Instruments 中被捕获,因为我正在寻找合适的 Valgrind 替代品。因此:

  • 我将 Profile 架构更改为使用 Debug 而不是 Release。
  • 我确保没有优化。

但是,在使用 Instruments 之后:

如您所见,没有报告泄漏。 网上搜索后发现Can't detect C leaks in xcode 9 instruments,其中作者使用sleep,所以我想也许Instruments实际上并没有像Valgrind那样覆盖malloc,而是使用了采样技术,它并没有采样到这么短的通知,所以我把程序改成:

int main(int argc, const char * argv[]) {
  int* p = allocSomething();
  p = NULL;
  sleep(600000);
  return 0;
}

现在,我得到:

这完全没有意义,因为这是明显的内存泄漏。 我会说它必须做一些优化,但我又一次明确地禁用了它。此外,如果我malloc 更多字节,它确实会检测到它。或者可能是 Instruments 中的错误?

所以我想知道这是否是 Instruments 无法检测到小分配的问题?我必须指出,Valgrind 可以很好地处理它,所以我很惊讶。

你有什么建议吗?

【问题讨论】:

    标签: c xcode memory-leaks valgrind xcode-instruments


    【解决方案1】:

    Leaks 工具(Leaks 模板中的一种工具)的工作方式与您的预期不同。

    首先,为什么它不会检测任何短期进程:它是基于计时器的。它每隔一段时间就会停止该过程并检查它是否存在泄漏。对于短暂的进程,在进程退出之前不会进行检查。

    其次,为什么它会漏掉一些漏洞:它检查所有线程的堆栈、所有线程的寄存器,以及寻找分配地址的全局变量。如果在其中任何一个地方找到分配的地址,则不会认为该分配已泄漏。

    在您的情况下,分配的地址可能仍在寄存器或堆栈内存中。在“真实”程序中,堆栈和寄存器最终会被重用,而这些陈旧的数据将被消除。

    Allocations 工具会跟踪所有分配和解除分配(假设该过程是由 Instruments 启动的)。您泄露的分配在分配列表中,并且仍然列为“实时”(又名创建和持久)。问题是 Allocations 工具没有明确地将此类分配称为泄漏。

    此外,系统库还进行了分配,这些分配旨在在进程退出之前一直存在并且没有明确清理。因此,您的泄漏有点隐藏在不相关的信息中。您可以对分配列表进行过滤和排序以发现泄漏,但这需要一些工作。

    在更真实的程序的上下文中,Instruments 非常擅长发现泄漏。

    显然,Clang 支持 LeakSanitizer,作为 AddressSanitizer 的一部分或独立。这可能需要一个比 Apple 作为 Xcode 和/或 Catalina 的一部分发布的版本更新的 Clang 版本。 (我在 Mojave 上使用 Xcode 11.3.1 进行了测试。它不支持 -fsanitize=leak 选项,也不支持 ASAN_OPTIONS=detect_leaks=1。)假设你可以让它工作,它的行为可能更像你所期望的.

    【讨论】:

    • 感谢您的详细解释!我会使用 Clang 消毒剂!
    猜你喜欢
    • 2011-06-07
    • 2011-02-18
    • 2021-09-01
    • 2010-09-08
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    相关资源
    最近更新 更多