【问题标题】:Can we unit test memory allocation?我们可以对内存分配进行单元测试吗?
【发布时间】:2019-09-06 04:38:35
【问题描述】:

我必须测试一个提供自己的内存分配例程的库:

void* allocation_routine(size_t size) throw();

文档说明此函数至少分配 size 字节的内存(允许分配更多)。顺便说一句,该函数在内部使用 posix_memalign,但实现可能会发生变化。

我想知道是否可以为这种功能编写单元测试?我们如何测试是否分配了所需的内存量?

更新:

如果我们不能编写单元测试,那么最接近的解决方案是什么?

【问题讨论】:

  • 您需要选择 C ​​或 C++ 标签。这些语言在异常处理方面有很大不同,请参阅 How to throw an exception in C?throw expression - cppreference.com
  • 我建议模拟标准的内存分配函数来检查它们是否被调用(以及调用的大小)。大多数实现相对容易实现这一点。如需具体帮助,您需要提供您正在使用的具体实现,并(正如 David C. Rankin 所要求的)指定您使用的语言(C 和 C++ 是不同的语言)。
  • 例如在 gcc (C) 中,你可以使用memory allocation hooks
  • @DavidC.Rankin 此例程来自 .cpp 文件。但是代码非常C风格。我认为 C 解决方案在那里更合适。

标签: c++ c linux unit-testing memory-management


【解决方案1】:

这不是单元测试,但您可以使用 Valgrind 获取有关内存的不同信息。

  • 内存泄漏(不是免费的)
  • 内存问题

它主要用于调试,但如果分配不当,它会警告你。

【讨论】:

    【解决方案2】:

    你不能为这个函数编写单元测试,因为你不能在没有系统调用的情况下在堆上分配内存。因此,这是一个集成测试,因为您无法将被测单元与操作系统隔离开来。

    我将创建一个新的小型可执行文件,它调用allocation_routine 以获得n 字节。根据allocation_routine 应该返回的内容,您可以断言它不是nullptr。然后,将n 字节写入此内存区域。使用 address sanitizer 编译和链接它(gccclang 都可用),然后尝试将其集成到应用程序的测试运行程序中(ctest 等)。

    您可能还想通过 POSIX setrlimit 限制可用堆,以在分配失败时验证行为。

    【讨论】:

    • 另外我建议用一些伪随机序列填充每个分配的块(例如,您可以使用基于 xoroshiro 哈希的 PRNG 生成器)。您可以存储种子值并稍后播放相同的序列并检查内存块的正确性。或者你可以用随机值填充内存块,计算并存储它的哈希值,然后再检查它(但是当你使用第一种方法时,你可以找到确切损坏的字节)。
    • 作为基本测试,在每一步(数千个)中,您可以执行以下操作之一(随机选择): 1)分配随机大小的内存块,用 PRNG 值填充它;或者 2) 检查一些随机选择的块的正确性并释放它。
    • 谢谢!我是 linux 新手。你能解释一下地址消毒剂是什么意思吗?我目前正在使用 Intel C/C++ 编译器和 LLVM 的 lit 来运行测试。我想避免使用外部程序。
    • 看看the docs。从给出的示例开始,熟悉命令行标志。 gcc 有一个非常相似的消毒剂/标志,对于 icc 我不知道。地址清理器添加了运行时检查,这些检查将报告内存违规,如越界访问、溢出等。
    • 另外,每次选择下一个分配的内存块的随机大小时,可以稍微增加这个大小。所以块大小会随着时间的推移而增长。我通过这种方式测试将向您展示自定义分配器如何防止碎片化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多