#minidump #breakpad #process #crash #rewrite #platform #dump

bin+lib minidump-writer

Breakpad 的 minidump_writer 的 Rust 重新编写

21 个版本

新版本 0.10.0 2024 年 8 月 20 日
0.9.0 2024 年 7 月 20 日
0.8.9 2024 年 4 月 1 日
0.8.8 2024 年 3 月 21 日
0.4.0 2022 年 7 月 21 日

#24调试

Download history 4416/week @ 2024-05-03 4959/week @ 2024-05-10 5259/week @ 2024-05-17 4168/week @ 2024-05-24 5070/week @ 2024-05-31 5506/week @ 2024-06-07 6975/week @ 2024-06-14 6031/week @ 2024-06-21 7556/week @ 2024-06-28 7932/week @ 2024-07-05 7296/week @ 2024-07-12 10491/week @ 2024-07-19 8306/week @ 2024-07-26 8236/week @ 2024-08-02 7926/week @ 2024-08-09 8759/week @ 2024-08-16

34,878 每月下载量
用于 11 库(4 个直接使用)

MIT 许可证

390KB
8K SLoC

minidump-writer

Breakpad 的 minidump_writer(客户端)的 Rust 重新编写

Rust CI crates.io docs.rs

该项目目前正在从无到有地积极发展,最终将成为针对不同平台的多个客户端实现。

使用方法/示例

该库的主要用途是为外部进程创建 minidump(即不是写入 minidump 的进程),因为在崩溃进程内编写 minidump 本身是不可靠的。尽管如此,在非崩溃场景中创建 minidump 也可能很有用,因此每个支持的平台都有一种方法可以生成本地进程的 minidump。

有关如何转储外部进程的更多信息,您可以在 minidumper 库的文档或代码中进行查看。

Linux

本地进程

Linux 实现使用 ptrace 在为进程编写 minidump 时收集有关进程的信息,这不能从进程本身完成。您可以从该进程的克隆中克隆进程并从该克隆中转储当前进程,但这超出了示例的范围。

外部进程

fn write_minidump(crash_context: crash_context::CrashContext) {
    // At a minimum, the crashdump writer needs to know the process and thread that the crash occurred in
    let mut writer = minidump_writer::minidump_writer::MinidumpWriter::new(crash_context.pid, crash_context.tid);

    // If provided with a full [crash_context::CrashContext](https://docs.rs/crash-context/latest/crash_context/struct.CrashContext.html),
    // the crash will contain more info on the crash cause, such as the signal
    writer.set_crash_context(minidump_writer::crash_context::CrashContext { inner: crash_context });

    // Here we could add more context or modify how the minidump is written, eg
    // Add application specific memory blocks to the minidump
    //writer.set_app_memory()
    // Sanitize stack memory before it is written to the minidump by replacing
    // non-pointer values with a sentinel value
    //writer.sanitize_stack();

    let mut minidump_file = std::fs::File::create("example_dump.mdmp").expect("failed to create file");
    writer.dump(&mut minidump_file).expect("failed to write minidump");
}

Windows

本地进程

fn write_minidump() {
    let mut minidump_file = std::fs::File::create("example_dump.mdmp").expect("failed to create file");
    
    // Attempts to the write the minidump
    minidump_writer::minidump_writer::MinidumpWriter::dump_local_context(
        // The exception code, presumably one of STATUS_*. Defaults to STATUS_NONCONTINUABLE_EXCEPTION if not specified
        None,
        // If not specified, uses the current thread as the "crashing" thread,
        // so this is equivalent to passing `None`, but it could be any thread
        // in the process
        Some(unsafe { windows_sys::Win32::System::Threading::GetCurrentThreadId() }),
        &mut minidump_file,
    ).expect("failed to write minidump");;
}

外部进程

fn write_minidump(crash_context: crash_context::CrashContext) {
    use std::io::{Read, Seek};

    // Create the file to write the minidump to. Unlike MacOS and Linux, the
    // system call used to write the minidump only supports outputting to a file
    let mut minidump_file = std::fs::File::create("example_dump.mdmp").expect("failed to create file");
    // Attempts to the write the minidump for the crash context
    minidump_writer::minidump_writer::MinidumpWriter::dump_crash_context(crash_context, &mut minidump_file).expect("failed to write minidump");;

    let mut minidump_contents = Vec::with_capacity(minidump_file.stream_position().expect("failed to get stream length") as usize);
    minidump_file.rewind().expect("failed to rewind minidump file");

    minidump_file.read_to_end(&mut minidump_contents).expect("failed to read minidump");
}

MacOS

本地进程

fn write_minidump() {
    // Defaults to dumping the current process and thread.
    let mut writer = minidump_writer::minidump_writer::MinidumpWriter::new(None, None)?;

    let mut minidump_file = std::fs::File::create("example_dump.mdmp").expect("failed to create file");
    writer.dump(&mut minidump_file).expect("failed to write minidump");
}

外部进程

fn write_minidump(crash_context: crash_context::CrashContext) {
    let mut writer = minidump_writer::minidump_writer::MinidumpWriter::with_crash_context(crash_context)?;

    let mut minidump_file = std::fs::File::create("example_dump.mdmp").expect("failed to create file");
    writer.dump(&mut minidump_file).expect("failed to write minidump");
}

客户端状态

  • ✅ 可用,但在生产环境中应谨慎使用
  • ⚠️ 实现(即编译),但未经测试,需要更多工作才能使用
  • ⭕️ 未实现,但将来可能实现
  • ❌ 未实现,且不太可能实现
架构 unknown-linux-gnu unknown-linux-musl linux-android pc-windows-msvc apple-darwin apple-ios
x86_64 ⚠️ ⭕️
i686 ⭕️
arm ⚠️ ⚠️ ⚠️ ⭕️
aarch64 ⚠️ ⚠️ ⚠️ ⭕️ ⭕️
mips ⭕️ ⭕️
mips64 ⭕️ ⭕️
powerpc ⭕️ ⭕️
powerpc64 ⭕️ ⭕️

依赖

~4–13MB
~179K SLoC