1个不稳定版本

0.2.0 2022年9月7日
0.1.1 2022年9月7日
0.0.1 2022年9月7日

#382 in 调试

MIT/Apache

33KB
402

Smartalloc-rs

Build no std crates.io docs.rs

此crate提供了对smartallocno_std惯用Rust绑定,用于检测孤儿缓冲区分配,这是一种程序已失去对其所有访问权的堆内存泄漏类型。主要用例是作为编写不安全代码时的调试工具,在这种情况下,正常的Rust静态检查不可用。最好与SANs一起使用,其中仅使用SANs既无法检测,又难以处理其输出。为了获得最佳体验,使用RUSTFLAGS=-Zsanitizer=leak并包含在.cargo/config.toml中。

用法

[dev-dependencies]
smartalloc = "0.2"

实际上,在#![cfg(debug_assertions)]下,crate在--release模式下不会编译,从而防止了任何意外使用。此crate需要nightly Rust工具链(MSRV 1.65)。

示例

在调试期间,将SmartAlloc配置为全局分配器。然后在不安全代码块的末尾包含sm_dump(true)。这里是examples/orphan.rs

use core::alloc::{GlobalAlloc, Layout};

use smartalloc::{sm_dump, SmartAlloc};

#[global_allocator]
static GLOBAL: SmartAlloc = SmartAlloc;

fn main() {
    unsafe {
        let alloc = SmartAlloc;
        let layout = Layout::from_size_align(8, 8).unwrap();
        alloc.alloc(layout); // orphaned memory leak as it's pointer is lost
                             // and there's no alloc.dealloc(ptr, layout)
        sm_dump(true);
    }
}

输出

Orphaned buffer:       8 bytes allocated at line 12 of examples/orphan.rs

注意检测器抛出

Orphaned buffer:       5 bytes allocated at line 5 of examples/orphan.rs
Orphaned buffer:      48 bytes allocated at line 5 of examples/orphan.rs

这指的是#[global_allocator]本身,可以忽略。

功能

检测器可以使用 sm_static(true) 关闭,并使用 sm_static(false) 重新开启,以处理通过 std 或安全方式(例如 examples/native.rs)进行的分配。更多详情请查阅原始 文档

难道SANs本身不应该检测此类错误吗?

这两个 leak/address/memory sanitizer 都不足以检测此类错误,而且可以轻松地检测到。事实上,运行

RUSTFLAGS="-Zsanitizer=leak" cargo +nightly run --example undetected
// OR
RUSTFLAGS="-Zsanitizer=address" cargo +nightly run --example undetected

examples/undetected.rs

unsafe {
    let alloc = SmartAlloc;
    let layout = Layout::from_size_align(8, 8).unwrap();
    alloc.alloc(layout);
}

没有 sm_dump(true) 在最后),不会显示任何内容,主要是因为我们指定了

[profile.dev]
opt-level = 0

让 SmartAlloc 与内省一起工作,而不是这里建议包含的内容(至少 opt-level=1),这里是为了规避这样的限制,但执行完毕后上下文会被销毁。还有

RUSTFLAGS="-Zsanitizer=memory -Zsanitizer-memory-track-origins" cargo +nightly run --example undetected

无法编译,并且抛出无用的消息

error: failed to run custom build command for `libc v0.2.132`

Caused by:
  process didn't exit successfully: `/home/workspace/smartalloc-rs/target/debug/build/libc-02d4e594eff5723f/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-changed=build.rs

  --- stderr
  ==186416==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x56367729226c  (/home/workspace/smartalloc-rs/target/debug/build/libc-02d4e594eff5723f/build-script-build+0x7a26c) (BuildId: ff090caba1904387acf3f0fecb58801c6fa5caed)
    #1 0x56367728e95d  (/home/workspace/smartalloc-rs/target/debug/build/libc-02d4e594eff5723f/build-script-build+0x7695d) (BuildId: ff090caba1904387acf3f0fecb58801c6fa5caed)
    ...
    Uninitialized value was created by an allocation of '_2' in the stack frame of function '_ZN18build_script_build19rustc_minor_nightly17hfbf53e202478a57bE'
      #0 0x563677291e70  (/home/workspace/smartalloc-rs/target/debug/build/libc-02d4e594eff5723f/build-script-build+0x79e70) (BuildId: ff090caba1904387acf3f0fecb58801c6fa5caed)

    SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/workspace/smartalloc-rs/target/debug/build/libc-02d4e594eff5723f/build-script-build+0x7a26c) (BuildId: ff090caba1904387acf3f0fecb58801c6fa5caed)
    Exiting

所以还需要做更多的工作!

已知问题

smartalloc-sys/csrc/smartall.c 将写入传递的文件名指针,该指针由 #[track_caller](不可变)跟踪,这是UB,可能导致使用此绑定在报告的文件名后显示更多垃圾。

许可证

根据您的意愿,许可协议为

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在您的工作中的任何贡献,都应双许可如上所述,不附加任何额外条款或条件。

依赖项

~180KB