1 个不稳定版本
0.1.0 | 2020年11月14日 |
---|
#42 在 #global-allocator
114 每月下载量
在 6 个crate中使用了 (通过 mockalloc)
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