diff options
Diffstat (limited to 'third_party/rust/minidump-writer/README.md')
-rw-r--r-- | third_party/rust/minidump-writer/README.md | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/third_party/rust/minidump-writer/README.md b/third_party/rust/minidump-writer/README.md new file mode 100644 index 0000000000..20962c913f --- /dev/null +++ b/third_party/rust/minidump-writer/README.md @@ -0,0 +1,155 @@ +<div align="center"> + +# `minidump-writer` + +**Rust rewrite of Breakpad's minidump_writer (client)** + +[![Rust CI](https://github.com/rust-minidump/minidump-writer/actions/workflows/ci.yml/badge.svg)](https://github.com/rust-minidump/minidump-writer/actions/workflows/ci.yml) +[![crates.io](https://img.shields.io/crates/v/minidump-writer.svg)](https://crates.io/crates/minidump-writer) +[![docs.rs](https://docs.rs/minidump-writer/badge.svg)](https://docs.rs/minidump-writer) + +</div> + +This project is currently being very actively brought up from nothing, and is really ultimately many separate client implementations for different platforms. + +## Usage / Examples + +The primary use case of this crate is for creating a minidump for an **external** process (ie a process other than the one that writes the minidump) as writing minidumps from within a crashing process is inherently unreliable. That being said, there are scenarios where creating a minidump can be useful outside of a crash scenario thus each supported platforms has a way to generate a minidump for a local process as well. + +For more information on how to dump an external process you can check out the documentation or code for the [minidumper](https://docs.rs/minidumper/latest/minidumper/) crate. + +### Linux + +#### Local process + +```rust +fn write_minidump() { + // At a minimum, the crashdump writer needs to know the process and thread that you want to dump + let mut writer = minidump_writer::minidump_writer::MinidumpWriter::new( + std::process::id() as _, + // This gets the current thread, but you could get the id for any thread + // in the current process + unsafe { libc::syscall(libc::SYS_gettid) } as i32 + ); + + // 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"); +} +``` + +#### External process + +```rust +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 + +#### Local process + +```rust +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");; +} +``` + +#### External process + +```rust +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 + +#### Local process + +```rust +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"); +} +``` + +#### External process + +```rust +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"); +} +``` + +## Client Statuses + +- ✅ Usable, but care should be taken in production environments +- ⚠️ Implemented (ie compiles), but untested and needs more work to be usable +- ⭕️ Unimplemented, but could be implemented in the future +- ❌ Unimplemented, and unlikely to ever be implemented + +| Arch | unknown-linux-gnu | unknown-linux-musl | linux-android | pc-windows-msvc | apple-darwin | apple-ios | +----------- | ----------------- | ------------------ | ------------- | --------------- | ------------ | --------- | +`x86_64` | ✅ | ✅ | ⚠️ | ✅ | ✅ | ⭕️ | +`i686` | ✅ | ✅ | ❌ | ⭕️ | ❌ | ❌ | +`arm` | ⚠️ | ⚠️ | ⚠️ | ⭕️ | ❌ | ❌ | +`aarch64` | ⚠️ | ⚠️ | ⚠️ | ⭕️ | ✅ | ⭕️ | +`mips` | ⭕️ | ⭕️ | ❌ | ❌ | ❌ | ❌ | +`mips64` | ⭕️ | ⭕️ | ❌ | ❌ | ❌ | ❌ | +`powerpc` | ⭕️ | ⭕️ | ❌ | ❌ | ❌ | ❌ | +`powerpc64` | ⭕️ | ⭕️ | ❌ | ❌ | ❌ | ❌ | |