1 个不稳定版本

0.1.0 2020年11月14日

#42#global-allocator

Download history 28/week @ 2024-03-11 19/week @ 2024-03-18 27/week @ 2024-03-25 55/week @ 2024-04-01 21/week @ 2024-04-08 44/week @ 2024-04-15 32/week @ 2024-04-22 9/week @ 2024-04-29 57/week @ 2024-05-06 62/week @ 2024-05-13 33/week @ 2024-05-20 45/week @ 2024-05-27 30/week @ 2024-06-03 39/week @ 2024-06-10 20/week @ 2024-06-17 21/week @ 2024-06-24

114 每月下载量
6 个crate中使用了 (通过 mockalloc)

MIT/Apache

3KB

mockalloc

Mockalloc 是一个允许测试使用全局分配器的代码的crate。它使用概率算法来检测和区分几种与分配相关的错误

  • 内存泄漏
  • 重复释放
  • 无效释放(坏指针)
  • 无效释放(坏大小)
  • 无效释放(坏对齐)

使用方法

典型用法是在测试期间启用 Mockalloc 分配器,例如

#[cfg(test)]
mod tests {
    use std::alloc::System;
    use mockalloc::Mockalloc;

    #[global_allocator]
    static ALLOCATOR: Mockalloc<System> = Mockalloc(System);
}

一旦分配器被启用,您有几种方法可以在测试中使用它。

最简单的方法是在您的测试上使用 #[mockalloc::test] 属性,而不是通常的 #[test] 属性

    #[mockalloc::test]
    fn it_works() {
        // Some code which uses the allocator
    }

如果检测到上述任何分配错误,则测试将失败。如果没有检测到分配,则测试也将因为 NoData 错误而失败,这样您就可以确信 Mockalloc 分配器处于活动状态。

您还可以使用 mockalloc 使用 assert_allocs 函数来测试代码的特定部分是否存在内存问题,而无需检查整个测试。

前面示例中的 #[mockalloc::test] 属性只是一个简写,相当于

    #[test]
    fn it_works() {
        mockalloc::assert_allocs(|| {
            // Some code which uses the allocator
        });
    }

您还可以进行更详细的断言:例如,您可能想要断言某段代码执行了特定数量的分配。为此,您可以使用 record_allocs 函数

    #[test]
    fn it_works() {
        let alloc_info = mockalloc::record_allocs(|| {
            // Some code which uses the allocator
        });

        assert_eq!(alloc_info.num_allocs(), 2);

        // This is what `assert_allocs` does internally:
        alloc_info.result().unwrap()
    }

限制

分配为每个线程分别跟踪。这允许并行运行测试,但这也意味着如果某个线程分配的指针后来被另一个线程释放,库将报告错误。

算法无法检测错误的位置,它只能指示存在哪种类型的错误。

工作原理

分配器在自身不分配任何内存的情况下进行跟踪。它使用一种概率算法,通过散列有关分配和释放的各种元数据,然后通过交换操作累积这些数据,以确保顺序不会影响结果。

根据这些累积器中哪一个在测试区域结束时返回零,可以区分不同的分配错误。

以下元数据被散列和累积

  • 指针
  • 大小 & 指针
  • 对齐 & 指针

除了跟踪分配和释放的总数。

通过查找分配和释放的总数之间的差异,我们可以检测内存泄漏和重复释放。

否则,如果指针累积器没有返回零,我们知道释放了一个无效的指针。

否则,我们知道正确地释放了指针,但可能大小和/或对齐方式不正确,我们可以通过其他两个累积器来检测。

如果所有累积器都返回零,那么我们知道一切正常。

每个累积器和散列都是128位,以基本消除冲突的可能性。

依赖项

~1.5MB
~35K SLoC