diff --git a/Cargo.toml b/Cargo.toml index a8eb7ce1..eab595c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,25 @@ [package] -name = "minidump_writer_linux" +name = "minidump-writer" version = "0.1.0" authors = ["Martin Sirringhaus"] -edition = "2018" +edition = "2021" license = "MIT" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +byteorder = "1.3.2" +cfg-if = "1.0" +memoffset = "0.5.1" tempfile = "3.1.0" -nix = "0.23" +thiserror = "1.0.21" + +[target.'cfg(unix)'.dependencies] libc = "0.2.74" -memoffset = "0.5.1" -byteorder = "1.3.2" -memmap2 = "0.2.2" goblin = "0.1.2" -thiserror = "1.0.21" +memmap2 = "0.2.2" + +[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] +nix = "0.23" [dev-dependencies] -minidump = {git = "https://github.com/luser/rust-minidump", rev="9652b3b" } -minidump-common = {git = "https://github.com/luser/rust-minidump", rev="9652b3b" } +minidump = { git = "https://github.com/luser/rust-minidump", rev = "9652b3b" } +minidump-common = { git = "https://github.com/luser/rust-minidump", rev = "9652b3b" } diff --git a/src/bin/test.rs b/src/bin/test.rs index 9899e8f9..15867829 100644 --- a/src/bin/test.rs +++ b/src/bin/test.rs @@ -1,13 +1,16 @@ +#![cfg(any(target_os = "linux", target_os = "android"))] + // This binary shouldn't be under /src, but under /tests, but that is // currently not possible (https://github.com/rust-lang/cargo/issues/4356) -use minidump_writer_linux::linux_ptrace_dumper::{LinuxPtraceDumper, AT_SYSINFO_EHDR}; -use minidump_writer_linux::{linux_ptrace_dumper, LINUX_GATE_LIBRARY_NAME}; -use nix::sys::mman::{mmap, MapFlags, ProtFlags}; -use nix::unistd::getppid; -use std::convert::TryInto; -use std::env; -use std::error; -use std::result; +use minidump_writer::{ + ptrace_dumper::{PtraceDumper, AT_SYSINFO_EHDR}, + LINUX_GATE_LIBRARY_NAME, +}; +use nix::{ + sys::mman::{mmap, MapFlags, ProtFlags}, + unistd::getppid, +}; +use std::{env, error, result}; type Error = Box; pub type Result = result::Result; @@ -24,13 +27,13 @@ macro_rules! test { fn test_setup() -> Result<()> { let ppid = getppid(); - linux_ptrace_dumper::LinuxPtraceDumper::new(ppid.as_raw())?; + PtraceDumper::new(ppid.as_raw())?; Ok(()) } fn test_thread_list() -> Result<()> { let ppid = getppid(); - let dumper = linux_ptrace_dumper::LinuxPtraceDumper::new(ppid.as_raw())?; + let dumper = PtraceDumper::new(ppid.as_raw())?; test!(!dumper.threads.is_empty(), "No threads")?; test!( dumper @@ -46,9 +49,9 @@ fn test_thread_list() -> Result<()> { fn test_copy_from_process(stack_var: usize, heap_var: usize) -> Result<()> { let ppid = getppid().as_raw(); - let mut dumper = linux_ptrace_dumper::LinuxPtraceDumper::new(ppid)?; + let mut dumper = PtraceDumper::new(ppid)?; dumper.suspend_threads()?; - let stack_res = LinuxPtraceDumper::copy_from_process(ppid, stack_var as *mut libc::c_void, 1)?; + let stack_res = PtraceDumper::copy_from_process(ppid, stack_var as *mut libc::c_void, 1)?; let expected_stack: libc::c_long = 0x11223344; test!( @@ -56,7 +59,7 @@ fn test_copy_from_process(stack_var: usize, heap_var: usize) -> Result<()> { "stack var not correct" )?; - let heap_res = LinuxPtraceDumper::copy_from_process(ppid, heap_var as *mut libc::c_void, 1)?; + let heap_res = PtraceDumper::copy_from_process(ppid, heap_var as *mut libc::c_void, 1)?; let expected_heap: libc::c_long = 0x55667788; test!( heap_res == expected_heap.to_ne_bytes(), @@ -68,7 +71,7 @@ fn test_copy_from_process(stack_var: usize, heap_var: usize) -> Result<()> { fn test_find_mappings(addr1: usize, addr2: usize) -> Result<()> { let ppid = getppid(); - let dumper = linux_ptrace_dumper::LinuxPtraceDumper::new(ppid.as_raw())?; + let dumper = PtraceDumper::new(ppid.as_raw())?; dumper .find_mapping(addr1) .ok_or("No mapping for addr1 found")?; @@ -85,7 +88,7 @@ fn test_file_id() -> Result<()> { let ppid = getppid().as_raw(); let exe_link = format!("/proc/{}/exe", ppid); let exe_name = std::fs::read_link(&exe_link)?.into_os_string(); - let mut dumper = linux_ptrace_dumper::LinuxPtraceDumper::new(getppid().as_raw())?; + let mut dumper = PtraceDumper::new(getppid().as_raw())?; let mut found_exe = None; for (idx, mapping) in dumper.mappings.iter().enumerate() { if mapping.name.as_ref().map(|x| x.into()).as_ref() == Some(&exe_name) { @@ -102,7 +105,7 @@ fn test_file_id() -> Result<()> { fn test_merged_mappings(path: String, mapped_mem: usize, mem_size: usize) -> Result<()> { // Now check that LinuxPtraceDumper interpreted the mappings properly. - let dumper = linux_ptrace_dumper::LinuxPtraceDumper::new(getppid().as_raw())?; + let dumper = PtraceDumper::new(getppid().as_raw())?; let mut mapping_count = 0; for map in &dumper.mappings { if map.name == Some(path.clone()) { @@ -120,13 +123,13 @@ fn test_merged_mappings(path: String, mapped_mem: usize, mem_size: usize) -> Res fn test_linux_gate_mapping_id() -> Result<()> { let ppid = getppid().as_raw(); - let mut dumper = linux_ptrace_dumper::LinuxPtraceDumper::new(ppid)?; + let mut dumper = PtraceDumper::new(ppid)?; let mut found_linux_gate = false; for mut mapping in dumper.mappings.clone() { if mapping.name.as_deref() == Some(LINUX_GATE_LIBRARY_NAME) { found_linux_gate = true; dumper.suspend_threads()?; - let id = LinuxPtraceDumper::elf_identifier_for_mapping(&mut mapping, ppid)?; + let id = PtraceDumper::elf_identifier_for_mapping(&mut mapping, ppid)?; test!(!id.is_empty(), "id-vec is empty")?; test!(id.iter().any(|&x| x > 0), "all id elements are 0")?; dumper.resume_threads()?; @@ -139,7 +142,7 @@ fn test_linux_gate_mapping_id() -> Result<()> { fn test_mappings_include_linux_gate() -> Result<()> { let ppid = getppid().as_raw(); - let dumper = linux_ptrace_dumper::LinuxPtraceDumper::new(ppid)?; + let dumper = PtraceDumper::new(ppid)?; let linux_gate_loc = dumper.auxv[&AT_SYSINFO_EHDR]; test!(linux_gate_loc != 0, "linux_gate_loc == 0")?; let mut found_linux_gate = false; diff --git a/src/crash_context/crash_context_mips.rs b/src/crash_context/crash_context_mips.rs deleted file mode 100644 index c7971be1..00000000 --- a/src/crash_context/crash_context_mips.rs +++ /dev/null @@ -1,12 +0,0 @@ -use super::CrashContext; -use libc::MD_CONTEXT_MIPS_REG_SP; - -impl CrashContext { - pub fn get_instruction_pointer(&self) -> usize { - self.context.uc_mcontext.pc as usize - } - - pub fn get_stack_pointer(&self) -> usize { - self.context.uc_mcontext.gregs[MD_CONTEXT_MIPS_REG_SP as usize] as usize - } -} diff --git a/src/crash_context/mod.rs b/src/crash_context/mod.rs deleted file mode 100644 index 2be8fb15..00000000 --- a/src/crash_context/mod.rs +++ /dev/null @@ -1,65 +0,0 @@ -use libc; - -// Minidump defines register structures which are different from the raw -// structures which we get from the kernel. These are platform specific -// functions to juggle the ucontext_t and user structures into minidump format. - -#[cfg(target_arch = "x86_64")] -#[path = "crash_context_x86_64.rs"] -pub mod imp; -#[cfg(target_arch = "x86")] -#[path = "crash_context_x86.rs"] -pub mod imp; -// Deactivated for now, as ucontext_t is missing from libc -// #[cfg(target_arch = "arm")] -// #[path = "crash_context_arm.rs"] -// pub mod imp; -#[cfg(target_arch = "arm")] -use crate::minidump_cpu::RawContextCPU; -#[cfg(target_arch = "arm")] -impl CrashContext { - pub fn get_instruction_pointer(&self) -> usize { - 0 - } - - pub fn get_stack_pointer(&self) -> usize { - 0 - } - - pub fn fill_cpu_context(&self, _: &mut RawContextCPU) {} -} - -#[cfg(target_arch = "aarch64")] -#[path = "crash_context_aarch64.rs"] -pub mod imp; -#[cfg(target_arch = "mips")] -#[path = "crash_context_mips.rs"] -pub mod imp; - -#[cfg(target_arch = "aarch64")] -pub type fpstate_t = libc::fpsimd_context; // Currently not part of libc! This will produce an error. -#[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips", - target_arch = "arm-eabi" -)))] -#[cfg(target_arch = "x86")] -#[allow(non_camel_case_types)] -pub type fpstate_t = libc::_libc_fpstate; -#[cfg(target_arch = "x86_64")] -#[allow(non_camel_case_types)] -pub type fpstate_t = libc::user_fpregs_struct; - -#[repr(C)] -#[derive(Clone)] -pub struct CrashContext { - pub siginfo: libc::siginfo_t, - pub tid: libc::pid_t, // the crashing thread. - #[cfg(not(target_arch = "arm"))] - pub context: libc::ucontext_t, - // #ifdef this out because FP state is not part of user ABI for Linux ARM. - // In case of MIPS Linux FP state is already part of ucontext_t so - // 'float_state' is not required. - #[cfg(not(any(target_arch = "mips", target_arch = "arm")))] - pub float_state: fpstate_t, -} diff --git a/src/lib.rs b/src/lib.rs index 1a774cd8..8a5ea122 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,17 +1,10 @@ -#[cfg(target_os = "android")] -mod android; -pub mod app_memory; -mod auxv_reader; -pub mod crash_context; -mod dso_debug; -mod dumper_cpu_info; -pub mod errors; -pub mod linux_ptrace_dumper; -pub mod maps_reader; +cfg_if::cfg_if! { + if #[cfg(any(target_os = "linux", target_os = "android"))] { + mod linux; + + pub use linux::*; + } +} + pub mod minidump_cpu; pub mod minidump_format; -pub mod minidump_writer; -mod sections; -pub mod thread_info; - -pub use maps_reader::LINUX_GATE_LIBRARY_NAME; diff --git a/src/linux.rs b/src/linux.rs new file mode 100644 index 00000000..ced835e5 --- /dev/null +++ b/src/linux.rs @@ -0,0 +1,15 @@ +#[cfg(target_os = "android")] +mod android; +pub mod app_memory; +pub(crate) mod auxv_reader; +pub mod crash_context; +mod dso_debug; +mod dumper_cpu_info; +pub mod errors; +pub mod maps_reader; +pub mod minidump_writer; +pub mod ptrace_dumper; +pub(crate) mod sections; +pub mod thread_info; + +pub use maps_reader::LINUX_GATE_LIBRARY_NAME; diff --git a/src/android.rs b/src/linux/android.rs similarity index 100% rename from src/android.rs rename to src/linux/android.rs diff --git a/src/app_memory.rs b/src/linux/app_memory.rs similarity index 100% rename from src/app_memory.rs rename to src/linux/app_memory.rs diff --git a/src/auxv_reader.rs b/src/linux/auxv_reader.rs similarity index 100% rename from src/auxv_reader.rs rename to src/linux/auxv_reader.rs diff --git a/src/linux/crash_context.rs b/src/linux/crash_context.rs new file mode 100644 index 00000000..8c155834 --- /dev/null +++ b/src/linux/crash_context.rs @@ -0,0 +1,37 @@ +//! Minidump defines register structures which are different from the raw +//! structures which we get from the kernel. These are platform specific +//! functions to juggle the ucontext_t and user structures into minidump format. + +#![allow(non_camel_case_types)] + +cfg_if::cfg_if! { + if #[cfg(target_arch = "x86_64")] { + pub(crate) mod x86_64; + + pub type fpstate_t = libc::user_fpregs_struct; + } else if #[cfg(target_arch = "x86")] { + pub(crate) mod x86; + + pub type fpstate_t = libc::_libc_fpstate; + } else if #[cfg(target_arch = "arm")] { + pub(crate) mod arm; + } else if #[cfg(target_arch = "aarch64")] { + pub(crate) mod aarch64; + + pub type fpstate_t = libc::fpsimd_context; // Currently not part of libc! This will produce an error. + } +} + +#[repr(C)] +#[derive(Clone)] +pub struct CrashContext { + pub siginfo: libc::siginfo_t, + pub tid: libc::pid_t, // the crashing thread. + #[cfg(not(target_arch = "arm"))] + pub context: libc::ucontext_t, + // #ifdef this out because FP state is not part of user ABI for Linux ARM. + // In case of MIPS Linux FP state is already part of ucontext_t so + // 'float_state' is not required. + #[cfg(not(target_arch = "arm"))] + pub float_state: fpstate_t, +} diff --git a/src/crash_context/crash_context_aarch64.rs b/src/linux/crash_context/aarch64.rs similarity index 100% rename from src/crash_context/crash_context_aarch64.rs rename to src/linux/crash_context/aarch64.rs diff --git a/src/crash_context/crash_context_arm.rs b/src/linux/crash_context/arm.rs similarity index 100% rename from src/crash_context/crash_context_arm.rs rename to src/linux/crash_context/arm.rs diff --git a/src/crash_context/crash_context_x86.rs b/src/linux/crash_context/x86.rs similarity index 100% rename from src/crash_context/crash_context_x86.rs rename to src/linux/crash_context/x86.rs diff --git a/src/crash_context/crash_context_x86_64.rs b/src/linux/crash_context/x86_64.rs similarity index 100% rename from src/crash_context/crash_context_x86_64.rs rename to src/linux/crash_context/x86_64.rs diff --git a/src/dso_debug.rs b/src/linux/dso_debug.rs similarity index 85% rename from src/dso_debug.rs rename to src/linux/dso_debug.rs index 781c34ab..d2e0459d 100644 --- a/src/dso_debug.rs +++ b/src/linux/dso_debug.rs @@ -1,27 +1,35 @@ -use crate::auxv_reader::AuxvType; -use crate::errors::SectionDsoDebugError; -use crate::linux_ptrace_dumper::LinuxPtraceDumper; -use crate::minidump_format::*; -use crate::sections::{write_string_to_location, MemoryArrayWriter, MemoryWriter}; -use libc; +use crate::{ + linux::{ + auxv_reader::AuxvType, + errors::SectionDsoDebugError, + ptrace_dumper::PtraceDumper, + sections::{write_string_to_location, Buffer, MemoryArrayWriter, MemoryWriter}, + }, + minidump_format::*, +}; use std::collections::HashMap; -use std::io::Cursor; type Result = std::result::Result; -#[cfg(all(target_pointer_width = "32"))] -use goblin::elf::program_header::program_header32::SIZEOF_PHDR; -#[cfg(all(target_pointer_width = "64"))] -use goblin::elf::program_header::program_header64::SIZEOF_PHDR; +cfg_if::cfg_if! { + if #[cfg(target_pointer_width = "32")] { + use goblin::elf::program_header::program_header32::SIZEOF_PHDR; + } else if #[cfg(target_pointer_width = "64")] { + use goblin::elf::program_header::program_header64::SIZEOF_PHDR; + } +} -#[cfg(all(target_pointer_width = "64", target_arch = "arm"))] -type ElfAddr = u64; -#[cfg(all(target_pointer_width = "64", not(target_arch = "arm")))] -type ElfAddr = libc::Elf64_Addr; -#[cfg(all(target_pointer_width = "32", target_arch = "arm"))] -type ElfAddr = u32; -#[cfg(all(target_pointer_width = "32", not(target_arch = "arm")))] -type ElfAddr = libc::Elf32_Addr; +cfg_if::cfg_if! { + if #[cfg(all(target_pointer_width = "64", target_arch = "arm"))] { + type ElfAddr = u64; + } else if #[cfg(all(target_pointer_width = "64", not(target_arch = "arm")))] { + type ElfAddr = libc::Elf64_Addr; + } else if #[cfg(all(target_pointer_width = "32", target_arch = "arm"))] { + type ElfAddr = u32; + } else if #[cfg(all(target_pointer_width = "32", not(target_arch = "arm")))] { + type ElfAddr = libc::Elf32_Addr; + } +} // COPY from #[derive(Debug, Clone, Default)] @@ -71,7 +79,7 @@ pub struct RDebug { } pub fn write_dso_debug_stream( - buffer: &mut Cursor>, + buffer: &mut Buffer, blamed_thread: i32, auxv: &HashMap, ) -> Result { @@ -95,7 +103,7 @@ pub fn write_dso_debug_stream( .get(&at_phdr) .ok_or(SectionDsoDebugError::CouldNotFind("AT_PHDR in auxv"))? as usize; - let ph = LinuxPtraceDumper::copy_from_process( + let ph = PtraceDumper::copy_from_process( blamed_thread, phdr as *mut libc::c_void, SIZEOF_PHDR * phnum_max, @@ -145,7 +153,7 @@ pub fn write_dso_debug_stream( // DSOs loaded into the program. If this information is indeed available, // dump it to a MD_LINUX_DSO_DEBUG stream. loop { - let dyn_data = LinuxPtraceDumper::copy_from_process( + let dyn_data = PtraceDumper::copy_from_process( blamed_thread, (dyn_addr as usize + dynamic_length) as *mut libc::c_void, dyn_size, @@ -178,7 +186,7 @@ pub fn write_dso_debug_stream( // See for a more detailed discussion of the how the dynamic // loader communicates with debuggers. - let debug_entry_data = LinuxPtraceDumper::copy_from_process( + let debug_entry_data = PtraceDumper::copy_from_process( blamed_thread, r_debug as *mut libc::c_void, std::mem::size_of::(), @@ -193,7 +201,7 @@ pub fn write_dso_debug_stream( let mut dso_vec = Vec::new(); let mut curr_map = debug_entry.r_map; while curr_map != 0 { - let link_map_data = LinuxPtraceDumper::copy_from_process( + let link_map_data = PtraceDumper::copy_from_process( blamed_thread, curr_map as *mut libc::c_void, std::mem::size_of::(), @@ -219,7 +227,7 @@ pub fn write_dso_debug_stream( for (idx, map) in dso_vec.iter().enumerate() { let mut filename = String::new(); if map.l_name > 0 { - let filename_data = LinuxPtraceDumper::copy_from_process( + let filename_data = PtraceDumper::copy_from_process( blamed_thread, map.l_name as *mut libc::c_void, 256, @@ -258,7 +266,7 @@ pub fn write_dso_debug_stream( }; dirent.location.data_size += dynamic_length as u32; - let dso_debug_data = LinuxPtraceDumper::copy_from_process( + let dso_debug_data = PtraceDumper::copy_from_process( blamed_thread, dyn_addr as *mut libc::c_void, dynamic_length, diff --git a/src/dumper_cpu_info/mod.rs b/src/linux/dumper_cpu_info.rs similarity index 69% rename from src/dumper_cpu_info/mod.rs rename to src/linux/dumper_cpu_info.rs index 248ae4c2..6577bf07 100644 --- a/src/dumper_cpu_info/mod.rs +++ b/src/linux/dumper_cpu_info.rs @@ -1,14 +1,22 @@ -#[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "mips", - target_arch = "mips64" -))] -#[path = "cpu_info_x86_mips.rs"] -pub mod imp; -#[cfg(any(target_arch = "arm", target_arch = "aarch64"))] -#[path = "cpu_info_arm.rs"] -pub mod imp; +cfg_if::cfg_if! { + if #[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "mips", + target_arch = "mips64" + ))] + { + pub mod x86_mips; + pub use x86_mips as imp; + } else if #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + ))] + { + pub mod arm; + pub use arm as imp; + } +} pub use imp::write_cpu_information; diff --git a/src/dumper_cpu_info/cpu_info_arm.rs b/src/linux/dumper_cpu_info/arm.rs similarity index 100% rename from src/dumper_cpu_info/cpu_info_arm.rs rename to src/linux/dumper_cpu_info/arm.rs diff --git a/src/dumper_cpu_info/cpu_info_x86_mips.rs b/src/linux/dumper_cpu_info/x86_mips.rs similarity index 100% rename from src/dumper_cpu_info/cpu_info_x86_mips.rs rename to src/linux/dumper_cpu_info/x86_mips.rs diff --git a/src/errors.rs b/src/linux/errors.rs similarity index 100% rename from src/errors.rs rename to src/linux/errors.rs diff --git a/src/maps_reader.rs b/src/linux/maps_reader.rs similarity index 99% rename from src/maps_reader.rs rename to src/linux/maps_reader.rs index ec0b4543..c8435f96 100644 --- a/src/maps_reader.rs +++ b/src/linux/maps_reader.rs @@ -4,10 +4,7 @@ use crate::thread_info::Pid; use byteorder::{NativeEndian, ReadBytesExt}; use goblin::elf; use memmap2::{Mmap, MmapOptions}; -use std::convert::TryInto; -use std::fs::File; -use std::mem::size_of; -use std::path::PathBuf; +use std::{fs::File, mem::size_of, path::PathBuf}; pub const LINUX_GATE_LIBRARY_NAME: &str = "linux-gate.so"; pub const DELETED_SUFFIX: &str = " (deleted)"; diff --git a/src/minidump_writer.rs b/src/linux/minidump_writer.rs similarity index 96% rename from src/minidump_writer.rs rename to src/linux/minidump_writer.rs index 644843d9..622181fb 100644 --- a/src/minidump_writer.rs +++ b/src/linux/minidump_writer.rs @@ -1,12 +1,16 @@ -use crate::app_memory::AppMemoryList; -use crate::crash_context::CrashContext; -use crate::dso_debug; -use crate::errors::{FileWriterError, InitError, MemoryWriterError, WriterError}; -use crate::linux_ptrace_dumper::LinuxPtraceDumper; -use crate::maps_reader::{MappingInfo, MappingList}; -use crate::minidump_format::*; -use crate::sections::*; -use crate::thread_info::Pid; +use crate::{ + linux::{ + app_memory::AppMemoryList, + crash_context::CrashContext, + dso_debug, + errors::{FileWriterError, InitError, MemoryWriterError, WriterError}, + maps_reader::{MappingInfo, MappingList}, + ptrace_dumper::PtraceDumper, + sections::*, + thread_info::Pid, + }, + minidump_format::*, +}; use std::io::{Cursor, Read, Seek, SeekFrom, Write}; pub type DumpBuf = Cursor>; @@ -185,7 +189,7 @@ impl MinidumpWriter { /// Generates a minidump and writes to the destination provided. Returns the in-memory /// version of the minidump as well. pub fn dump(&mut self, destination: &mut (impl Write + Seek)) -> Result> { - let mut dumper = LinuxPtraceDumper::new(self.process_id)?; + let mut dumper = PtraceDumper::new(self.process_id)?; dumper.suspend_threads()?; dumper.late_init()?; @@ -209,7 +213,7 @@ impl MinidumpWriter { Ok(buffer.into_inner()) } - fn crash_thread_references_principal_mapping(&self, dumper: &LinuxPtraceDumper) -> bool { + fn crash_thread_references_principal_mapping(&self, dumper: &PtraceDumper) -> bool { if self.crash_context.is_none() || self.principal_mapping.is_none() { return false; } @@ -244,7 +248,7 @@ impl MinidumpWriter { return false; } }; - let stack_copy = match LinuxPtraceDumper::copy_from_process( + let stack_copy = match PtraceDumper::copy_from_process( self.blamed_thread, stack_ptr as *mut libc::c_void, stack_len, @@ -265,7 +269,7 @@ impl MinidumpWriter { fn generate_dump( &mut self, buffer: &mut DumpBuf, - dumper: &mut LinuxPtraceDumper, + dumper: &mut PtraceDumper, destination: &mut (impl Write + Seek), ) -> Result<()> { // A minidump file contains a number of tagged streams. This is the number diff --git a/src/linux_ptrace_dumper.rs b/src/linux/ptrace_dumper.rs similarity index 96% rename from src/linux_ptrace_dumper.rs rename to src/linux/ptrace_dumper.rs index d8409e77..50efd493 100644 --- a/src/linux_ptrace_dumper.rs +++ b/src/linux/ptrace_dumper.rs @@ -1,21 +1,27 @@ -// use libc::c_void; #[cfg(target_os = "android")] -use crate::android::late_process_mappings; -use crate::auxv_reader::{AuxvType, ProcfsAuxvIter}; -use crate::errors::{DumperError, InitError, ThreadInfoError}; -use crate::maps_reader::{MappingInfo, MappingInfoParsingResult, DELETED_SUFFIX}; -use crate::minidump_format::MDGUID; -use crate::thread_info::{Pid, ThreadInfo}; -use crate::LINUX_GATE_LIBRARY_NAME; +use crate::linux::android::late_process_mappings; +use crate::{ + linux::{ + auxv_reader::{AuxvType, ProcfsAuxvIter}, + errors::{DumperError, InitError, ThreadInfoError}, + maps_reader::{MappingInfo, MappingInfoParsingResult, DELETED_SUFFIX}, + thread_info::{Pid, ThreadInfo}, + LINUX_GATE_LIBRARY_NAME, + }, + minidump_format::MDGUID, +}; use goblin::elf; -use nix::errno::Errno; -use nix::sys::{ptrace, wait}; -use std::collections::HashMap; -use std::convert::TryInto; -use std::ffi::c_void; -use std::io::{BufRead, BufReader}; -use std::path; -use std::result::Result; +use nix::{ + errno::Errno, + sys::{ptrace, wait}, +}; +use std::{ + collections::HashMap, + ffi::c_void, + io::{BufRead, BufReader}, + path, + result::Result, +}; #[derive(Debug, Clone)] pub struct Thread { @@ -24,7 +30,7 @@ pub struct Thread { } #[derive(Debug)] -pub struct LinuxPtraceDumper { +pub struct PtraceDumper { pub pid: Pid, threads_suspended: bool, pub threads: Vec, @@ -37,18 +43,18 @@ pub const AT_SYSINFO_EHDR: u32 = 33; #[cfg(target_pointer_width = "64")] pub const AT_SYSINFO_EHDR: u64 = 33; -impl Drop for LinuxPtraceDumper { +impl Drop for PtraceDumper { fn drop(&mut self) { // Always try to resume all threads (e.g. in case of error) let _ = self.resume_threads(); } } -impl LinuxPtraceDumper { +impl PtraceDumper { /// Constructs a dumper for extracting information of a given process /// with a process ID of |pid|. pub fn new(pid: Pid) -> Result { - let mut dumper = LinuxPtraceDumper { + let mut dumper = PtraceDumper { pid, threads_suspended: false, threads: Vec::new(), diff --git a/src/sections/mod.rs b/src/linux/sections.rs similarity index 86% rename from src/sections/mod.rs rename to src/linux/sections.rs index 086e7e23..d4e0b26d 100644 --- a/src/sections/mod.rs +++ b/src/linux/sections.rs @@ -6,12 +6,19 @@ pub mod systeminfo_stream; pub mod thread_list_stream; pub mod thread_names_stream; -use crate::errors::MemoryWriterError; -use crate::minidump_format::*; +use crate::{ + errors::{self, MemoryWriterError}, + linux::{ + minidump_writer::{self, DumpBuf, MinidumpWriter}, + ptrace_dumper::PtraceDumper, + }, + minidump_format::*, +}; use std::convert::TryInto; -use std::io::{Cursor, Write}; +use std::io::Write; -type Result = std::result::Result; +pub type Buffer = std::io::Cursor>; +type WriteResult = std::result::Result; #[derive(Debug, PartialEq)] pub struct MemoryWriter { @@ -25,7 +32,7 @@ where T: Default + Sized, { /// Create a slot for a type T in the buffer, we can fill right now with real values. - pub fn alloc_with_val(buffer: &mut Cursor>, val: T) -> Result { + pub fn alloc_with_val(buffer: &mut Buffer, val: T) -> WriteResult { // Get position of this value (e.g. before we add ourselves there) let position = buffer.position(); let size = std::mem::size_of::(); @@ -42,14 +49,14 @@ where /// Create a slot for a type T in the buffer, we can fill later with real values. /// This function fills it with `Default::default()`, which is less performant than /// using uninitialized memory, but safe. - pub fn alloc(buffer: &mut Cursor>) -> Result { + pub fn alloc(buffer: &mut Buffer) -> WriteResult { // Filling out the buffer with default-values let val: T = Default::default(); Self::alloc_with_val(buffer, val) } /// Write actual values in the buffer-slot we got during `alloc()` - pub fn set_value(&mut self, buffer: &mut Cursor>, val: T) -> Result<()> { + pub fn set_value(&mut self, buffer: &mut Buffer, val: T) -> WriteResult<()> { // Save whereever the current cursor stands in the buffer let curr_pos = buffer.position(); @@ -89,7 +96,7 @@ where T: Default + Sized, { /// Create a slot for a type T in the buffer, we can fill in the values in one go. - pub fn alloc_from_array(buffer: &mut Cursor>, array: &[T]) -> Result { + pub fn alloc_from_array(buffer: &mut Buffer, array: &[T]) -> WriteResult { // Get position of this value (e.g. before we add ourselves there) let position = buffer.position(); for val in array { @@ -109,7 +116,7 @@ where /// Create a slot for a type T in the buffer, we can fill later with real values. /// This function fills it with `Default::default()`, which is less performant than /// using uninitialized memory, but safe. - pub fn alloc_array(buffer: &mut Cursor>, array_size: usize) -> Result { + pub fn alloc_array(buffer: &mut Buffer, array_size: usize) -> WriteResult { // Get position of this value (e.g. before we add ourselves there) let position = buffer.position(); for _ in 0..array_size { @@ -129,12 +136,7 @@ where } /// Write actual values in the buffer-slot we got during `alloc()` - pub fn set_value_at( - &mut self, - buffer: &mut Cursor>, - val: T, - index: usize, - ) -> Result<()> { + pub fn set_value_at(&mut self, buffer: &mut Buffer, val: T, index: usize) -> WriteResult<()> { // Save whereever the current cursor stands in the buffer let curr_pos = buffer.position(); @@ -170,9 +172,9 @@ where } pub fn write_string_to_location( - buffer: &mut Cursor>, + buffer: &mut Buffer, text: &str, -) -> Result { +) -> WriteResult { let letters: Vec = text.encode_utf16().collect(); // First write size of the string (x letters in u16, times the size of u16) diff --git a/src/sections/app_memory.rs b/src/linux/sections/app_memory.rs similarity index 54% rename from src/sections/app_memory.rs rename to src/linux/sections/app_memory.rs index cbc28ba2..d2ae5a3c 100644 --- a/src/sections/app_memory.rs +++ b/src/linux/sections/app_memory.rs @@ -1,15 +1,12 @@ -use crate::errors::SectionAppMemoryError; -use crate::linux_ptrace_dumper::LinuxPtraceDumper; -use crate::minidump_format::*; -use crate::minidump_writer::{DumpBuf, MinidumpWriter}; -use crate::sections::MemoryArrayWriter; - -type Result = std::result::Result; +use super::*; /// Write application-provided memory regions. -pub fn write(config: &mut MinidumpWriter, buffer: &mut DumpBuf) -> Result<()> { +pub fn write( + config: &mut MinidumpWriter, + buffer: &mut DumpBuf, +) -> Result<(), errors::SectionAppMemoryError> { for app_memory in &config.app_memory { - let data_copy = LinuxPtraceDumper::copy_from_process( + let data_copy = PtraceDumper::copy_from_process( config.blamed_thread, app_memory.ptr as *mut libc::c_void, app_memory.length, diff --git a/src/sections/exception_stream.rs b/src/linux/sections/exception_stream.rs similarity index 93% rename from src/sections/exception_stream.rs rename to src/linux/sections/exception_stream.rs index 65e14119..4de13888 100644 --- a/src/sections/exception_stream.rs +++ b/src/linux/sections/exception_stream.rs @@ -1,9 +1,5 @@ -use crate::errors::SectionExceptionStreamError; -use crate::minidump_format::*; -use crate::minidump_writer::{CrashingThreadContext, DumpBuf, MinidumpWriter}; -use crate::sections::MemoryWriter; - -type Result = std::result::Result; +use super::minidump_writer::CrashingThreadContext; +use super::*; #[allow(non_camel_case_types, unused)] #[repr(u32)] @@ -45,7 +41,10 @@ enum MDExceptionCodeLinux { dump requested. */ } -pub fn write(config: &mut MinidumpWriter, buffer: &mut DumpBuf) -> Result { +pub fn write( + config: &mut MinidumpWriter, + buffer: &mut DumpBuf, +) -> Result { let exception = if let Some(context) = &config.crash_context { let sig_addr; #[cfg(target_arch = "arm")] diff --git a/src/sections/mappings.rs b/src/linux/sections/mappings.rs similarity index 85% rename from src/sections/mappings.rs rename to src/linux/sections/mappings.rs index d95741d0..1cc9b886 100644 --- a/src/sections/mappings.rs +++ b/src/linux/sections/mappings.rs @@ -1,11 +1,5 @@ -use crate::errors::SectionMappingsError; -use crate::linux_ptrace_dumper::LinuxPtraceDumper; -use crate::maps_reader::MappingInfo; -use crate::minidump_format::*; -use crate::minidump_writer::{DumpBuf, MinidumpWriter}; -use crate::sections::{write_string_to_location, MemoryArrayWriter, MemoryWriter}; - -type Result = std::result::Result; +use super::*; +use crate::linux::maps_reader::MappingInfo; /// Write information about the mappings in effect. Because we are using the /// minidump format, the information about the mappings is pretty limited. @@ -14,8 +8,8 @@ type Result = std::result::Result; pub fn write( config: &mut MinidumpWriter, buffer: &mut DumpBuf, - dumper: &mut LinuxPtraceDumper, -) -> Result { + dumper: &mut PtraceDumper, +) -> Result { let mut modules = Vec::new(); // First write all the mappings from the dumper @@ -69,7 +63,7 @@ fn fill_raw_module( buffer: &mut DumpBuf, mapping: &MappingInfo, identifier: &[u8], -) -> Result { +) -> Result { let cv_record: MDLocationDescriptor; if identifier.is_empty() { // Just zeroes @@ -92,7 +86,7 @@ fn fill_raw_module( let (file_path, _) = mapping .get_mapping_effective_name_and_path() - .map_err(|e| SectionMappingsError::GetEffectivePathError(mapping.clone(), e))?; + .map_err(|e| errors::SectionMappingsError::GetEffectivePathError(mapping.clone(), e))?; let name_header = write_string_to_location(buffer, &file_path)?; Ok(MDRawModule { diff --git a/src/sections/memory_list_stream.rs b/src/linux/sections/memory_list_stream.rs similarity index 58% rename from src/sections/memory_list_stream.rs rename to src/linux/sections/memory_list_stream.rs index 4f090831..7f497792 100644 --- a/src/sections/memory_list_stream.rs +++ b/src/linux/sections/memory_list_stream.rs @@ -1,11 +1,9 @@ -use crate::errors::SectionMemListError; -use crate::minidump_format::*; -use crate::minidump_writer::{DumpBuf, MinidumpWriter}; -use crate::sections::{MemoryArrayWriter, MemoryWriter}; +use super::*; -type Result = std::result::Result; - -pub fn write(config: &mut MinidumpWriter, buffer: &mut DumpBuf) -> Result { +pub fn write( + config: &mut MinidumpWriter, + buffer: &mut DumpBuf, +) -> Result { let list_header = MemoryWriter::::alloc_with_val(buffer, config.memory_blocks.len() as u32)?; diff --git a/src/linux/sections/systeminfo_stream.rs b/src/linux/sections/systeminfo_stream.rs new file mode 100644 index 00000000..fd7aa576 --- /dev/null +++ b/src/linux/sections/systeminfo_stream.rs @@ -0,0 +1,16 @@ +use super::*; +use crate::linux::dumper_cpu_info as dci; + +pub fn write(buffer: &mut DumpBuf) -> Result { + let mut info_section = MemoryWriter::::alloc(buffer)?; + let dirent = MDRawDirectory { + stream_type: MDStreamType::SystemInfoStream as u32, + location: info_section.location(), + }; + let mut info: MDRawSystemInfo = Default::default(); + dci::write_cpu_information(&mut info)?; + dci::write_os_information(buffer, &mut info)?; + + info_section.set_value(buffer, info)?; + Ok(dirent) +} diff --git a/src/sections/thread_list_stream.rs b/src/linux/sections/thread_list_stream.rs similarity index 93% rename from src/sections/thread_list_stream.rs rename to src/linux/sections/thread_list_stream.rs index d3672d99..fc3bfc0a 100644 --- a/src/sections/thread_list_stream.rs +++ b/src/linux/sections/thread_list_stream.rs @@ -1,13 +1,5 @@ -use crate::errors::SectionThreadListError; -use crate::linux_ptrace_dumper::LinuxPtraceDumper; -use crate::minidump_cpu::RawContextCPU; -use crate::minidump_format::*; -use crate::minidump_writer::{CrashingThreadContext, DumpBuf, MinidumpWriter}; -use crate::sections::{MemoryArrayWriter, MemoryWriter}; -use std::convert::TryInto; -use std::io::Write; - -type Result = std::result::Result; +use super::*; +use crate::{minidump_cpu::RawContextCPU, minidump_writer::CrashingThreadContext}; // The following kLimit* constants are for when minidump_size_limit_ is set // and the minidump size might exceed it. @@ -34,8 +26,8 @@ enum MaxStackLen { pub fn write( config: &mut MinidumpWriter, buffer: &mut DumpBuf, - dumper: &LinuxPtraceDumper, -) -> Result { + dumper: &PtraceDumper, +) -> Result { let num_threads = dumper.threads.len(); // Memory looks like this: // ... @@ -116,7 +108,7 @@ pub fn write( ip_memory_d.memory.data_size = (end_of_range - ip_memory_d.start_of_memory_range) as u32; - let memory_copy = LinuxPtraceDumper::copy_from_process( + let memory_copy = PtraceDumper::copy_from_process( thread.thread_id as i32, ip_memory_d.start_of_memory_range as *mut libc::c_void, ip_memory_d.memory.data_size as usize, @@ -178,12 +170,12 @@ pub fn write( fn fill_thread_stack( config: &mut MinidumpWriter, buffer: &mut DumpBuf, - dumper: &LinuxPtraceDumper, + dumper: &PtraceDumper, thread: &mut MDRawThread, instruction_ptr: usize, stack_ptr: usize, max_stack_len: MaxStackLen, -) -> Result<()> { +) -> Result<(), errors::SectionThreadListError> { thread.stack.start_of_memory_range = stack_ptr.try_into()?; thread.stack.memory.data_size = 0; thread.stack.memory.rva = buffer.position() as u32; @@ -203,7 +195,7 @@ fn fill_thread_stack( } } - let mut stack_bytes = LinuxPtraceDumper::copy_from_process( + let mut stack_bytes = PtraceDumper::copy_from_process( thread.thread_id.try_into()?, stack as *mut libc::c_void, stack_len, diff --git a/src/sections/thread_names_stream.rs b/src/linux/sections/thread_names_stream.rs similarity index 69% rename from src/sections/thread_names_stream.rs rename to src/linux/sections/thread_names_stream.rs index decb1674..cf060d5f 100644 --- a/src/sections/thread_names_stream.rs +++ b/src/linux/sections/thread_names_stream.rs @@ -1,14 +1,9 @@ -use crate::errors::SectionThreadNamesError; -use crate::linux_ptrace_dumper::LinuxPtraceDumper; -use crate::minidump_format::*; -use crate::minidump_writer::DumpBuf; -use crate::sections::write_string_to_location; -use crate::sections::{MemoryArrayWriter, MemoryWriter}; -use std::convert::TryInto; +use super::*; -type Result = std::result::Result; - -pub fn write(buffer: &mut DumpBuf, dumper: &LinuxPtraceDumper) -> Result { +pub fn write( + buffer: &mut DumpBuf, + dumper: &PtraceDumper, +) -> Result { // Only count threads that have a name let num_threads = dumper.threads.iter().filter(|t| t.name.is_some()).count(); // Memory looks like this: diff --git a/src/thread_info/mod.rs b/src/linux/thread_info.rs similarity index 88% rename from src/thread_info/mod.rs rename to src/linux/thread_info.rs index 8ed6d181..e5e3ed23 100644 --- a/src/thread_info/mod.rs +++ b/src/linux/thread_info.rs @@ -10,27 +10,21 @@ type Result = std::result::Result; pub type Pid = i32; -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -#[path = "thread_info_x86.rs"] -mod imp; -#[cfg(target_arch = "arm")] -#[path = "thread_info_arm.rs"] -mod imp; -#[cfg(target_arch = "aarch64")] -#[path = "thread_info_aarch64.rs"] -mod imp; -#[cfg(target_arch = "mips")] -#[path = "thread_info_mips.rs"] -mod imp; - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -pub type ThreadInfo = imp::ThreadInfoX86; -#[cfg(target_arch = "arm")] -pub type ThreadInfo = imp::ThreadInfoArm; -#[cfg(target_arch = "aarch64")] -pub type ThreadInfo = imp::ThreadInfoAarch64; -#[cfg(target_arch = "mips")] -pub type ThreadInfo = imp::ThreadInfoMips; +cfg_if::cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + mod x86; + pub type ThreadInfo = x86::ThreadInfoX86; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub type ThreadInfo = arm::ThreadInfoArm; + } else if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub type ThreadInfo = aarch64::ThreadInfoAarch64; + } else if #[cfg(target_arch = "mips")] { + mod mips; + pub type ThreadInfo = mips::ThreadInfoMips; + } +} #[derive(Debug)] #[allow(non_camel_case_types)] diff --git a/src/thread_info/thread_info_aarch64.rs b/src/linux/thread_info/aarch64.rs similarity index 100% rename from src/thread_info/thread_info_aarch64.rs rename to src/linux/thread_info/aarch64.rs diff --git a/src/thread_info/thread_info_arm.rs b/src/linux/thread_info/arm.rs similarity index 100% rename from src/thread_info/thread_info_arm.rs rename to src/linux/thread_info/arm.rs diff --git a/src/thread_info/thread_info_mips.rs b/src/linux/thread_info/mips.rs similarity index 100% rename from src/thread_info/thread_info_mips.rs rename to src/linux/thread_info/mips.rs diff --git a/src/thread_info/thread_info_x86.rs b/src/linux/thread_info/x86.rs similarity index 99% rename from src/thread_info/thread_info_x86.rs rename to src/linux/thread_info/x86.rs index 6dbf6c2d..f5c8532f 100644 --- a/src/thread_info/thread_info_x86.rs +++ b/src/linux/thread_info/x86.rs @@ -5,9 +5,7 @@ use crate::minidump_cpu::RawContextCPU; #[cfg(target_arch = "x86_64")] use crate::thread_info::to_u128; use core::mem::size_of_val; -use libc; use libc::user; -use memoffset; use nix::sys::ptrace; use nix::unistd; #[cfg(target_arch = "x86")] diff --git a/src/minidump_cpu.rs b/src/minidump_cpu.rs new file mode 100644 index 00000000..8c314426 --- /dev/null +++ b/src/minidump_cpu.rs @@ -0,0 +1,25 @@ +cfg_if::cfg_if! { + if #[cfg(target_arch = "x86_64")] { + pub(crate) mod amd64; + pub(crate) use amd64 as imp; + + pub type RawContextCPU = imp::MDRawContextAMD64; + } else if #[cfg(target_arch = "x86")] { + pub(crate) mod x86; + pub(crate) pub use x86 as imp; + + pub type RawContextCPU = imp::MDRawContextX86; + } else if #[cfg(target_arch = "arm")] { + pub(crate) mod arm; + pub(crate) pub use arm as imp; + + pub type RawContextCPU = imp::MDRawContextARM; + } else if #[cfg(target_arch = "aarch64")] { + pub(crate) mod aarch64; + pub(crate) pub use aarch64 as imp; + + compile_error!("flesh me out"); + } else { + compile_error!("unsupported target architecture"); + } +} diff --git a/src/minidump_cpu/minidump_cpu_aarch64.rs b/src/minidump_cpu/aarch64.rs similarity index 100% rename from src/minidump_cpu/minidump_cpu_aarch64.rs rename to src/minidump_cpu/aarch64.rs diff --git a/src/minidump_cpu/minidump_cpu_amd64.rs b/src/minidump_cpu/amd64.rs similarity index 94% rename from src/minidump_cpu/minidump_cpu_amd64.rs rename to src/minidump_cpu/amd64.rs index 3924d792..cd445dae 100644 --- a/src/minidump_cpu/minidump_cpu_amd64.rs +++ b/src/minidump_cpu/amd64.rs @@ -161,9 +161,9 @@ pub const MD_CONTEXT_AMD64_SEGMENTS: u32 = MD_CONTEXT_AMD64 | 0x00000004; /* CONTEXT_SEGMENTS */ pub const MD_CONTEXT_AMD64_FLOATING_POINT: u32 = MD_CONTEXT_AMD64 | 0x00000008; /* CONTEXT_FLOATING_POINT */ -pub const MD_CONTEXT_AMD64_DEBUG_REGISTERS: u32 = MD_CONTEXT_AMD64 | 0x00000010; +//pub const MD_CONTEXT_AMD64_DEBUG_REGISTERS: u32 = MD_CONTEXT_AMD64 | 0x00000010; /* CONTEXT_DEBUG_REGISTERS */ -pub const MD_CONTEXT_AMD64_XSTATE: u32 = MD_CONTEXT_AMD64 | 0x00000040; +//pub const MD_CONTEXT_AMD64_XSTATE: u32 = MD_CONTEXT_AMD64 | 0x00000040; /* CONTEXT_XSTATE */ /* WinNT.h refers to CONTEXT_MMX_REGISTERS but doesn't appear to define it @@ -174,6 +174,6 @@ pub const MD_CONTEXT_AMD64_FULL: u32 = MD_CONTEXT_AMD64_CONTROL | MD_CONTEXT_AMD64_INTEGER | MD_CONTEXT_AMD64_FLOATING_POINT; /* CONTEXT_FULL */ -pub const MD_CONTEXT_AMD64_ALL: u32 = - MD_CONTEXT_AMD64_FULL | MD_CONTEXT_AMD64_SEGMENTS | MD_CONTEXT_AMD64_DEBUG_REGISTERS; +//pub const MD_CONTEXT_AMD64_ALL: u32 = +//MD_CONTEXT_AMD64_FULL | MD_CONTEXT_AMD64_SEGMENTS | MD_CONTEXT_AMD64_DEBUG_REGISTERS; /* CONTEXT_ALL */ diff --git a/src/minidump_cpu/minidump_cpu_arm.rs b/src/minidump_cpu/arm.rs similarity index 100% rename from src/minidump_cpu/minidump_cpu_arm.rs rename to src/minidump_cpu/arm.rs diff --git a/src/minidump_cpu/minidump_cpu_mips.rs b/src/minidump_cpu/minidump_cpu_mips.rs deleted file mode 100644 index 8b137891..00000000 --- a/src/minidump_cpu/minidump_cpu_mips.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/minidump_cpu/minidump_cpu_ppc.rs b/src/minidump_cpu/minidump_cpu_ppc.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/src/minidump_cpu/minidump_cpu_ppc64.rs b/src/minidump_cpu/minidump_cpu_ppc64.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/src/minidump_cpu/minidump_cpu_sparc.rs b/src/minidump_cpu/minidump_cpu_sparc.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/src/minidump_cpu/mod.rs b/src/minidump_cpu/mod.rs deleted file mode 100644 index ebce0ad5..00000000 --- a/src/minidump_cpu/mod.rs +++ /dev/null @@ -1,26 +0,0 @@ -#[cfg(target_arch = "x86_64")] -#[path = "minidump_cpu_amd64.rs"] -pub mod imp; -#[cfg(target_arch = "x86")] -#[path = "minidump_cpu_x86.rs"] -pub mod imp; -#[cfg(target_arch = "arm")] -#[path = "minidump_cpu_arm.rs"] -pub mod imp; -#[cfg(target_arch = "aarch64")] -#[path = "minidump_cpu_aarch64.rs"] -pub mod imp; -#[cfg(target_arch = "mips")] -#[path = "minidump_cpu_mips.rs"] -pub mod imp; - -#[cfg(target_arch = "x86_64")] -pub type RawContextCPU = imp::MDRawContextAMD64; -#[cfg(target_arch = "x86")] -pub type RawContextCPU = imp::MDRawContextX86; -#[cfg(target_arch = "arm")] -pub type RawContextCPU = imp::MDRawContextARM; -#[cfg(target_arch = "aarch64")] -pub type RawContextCPU = imp::MDRawContextX86; -#[cfg(target_arch = "mips")] -pub type RawContextCPU = i32; diff --git a/src/minidump_cpu/minidump_cpu_x86.rs b/src/minidump_cpu/x86.rs similarity index 100% rename from src/minidump_cpu/minidump_cpu_x86.rs rename to src/minidump_cpu/x86.rs diff --git a/src/sections/systeminfo_stream.rs b/src/sections/systeminfo_stream.rs deleted file mode 100644 index dabd7793..00000000 --- a/src/sections/systeminfo_stream.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::dumper_cpu_info::{write_cpu_information, write_os_information}; -use crate::errors::SectionSystemInfoError; -use crate::minidump_format::*; -use crate::minidump_writer::DumpBuf; -use crate::sections::MemoryWriter; - -type Result = std::result::Result; - -pub fn write(buffer: &mut DumpBuf) -> Result { - let mut info_section = MemoryWriter::::alloc(buffer)?; - let dirent = MDRawDirectory { - stream_type: MDStreamType::SystemInfoStream as u32, - location: info_section.location(), - }; - let mut info: MDRawSystemInfo = Default::default(); - write_cpu_information(&mut info)?; - write_os_information(buffer, &mut info)?; - - info_section.set_value(buffer, info)?; - Ok(dirent) -} diff --git a/tests/minidump_writer.rs b/tests/minidump_writer.rs index 95c26fb3..3055c1d8 100644 --- a/tests/minidump_writer.rs +++ b/tests/minidump_writer.rs @@ -1,18 +1,21 @@ +#![cfg(any(target_os = "linux", target_os = "android"))] + use minidump::*; use minidump_common::format::{GUID, MINIDUMP_STREAM_TYPE::*}; -use minidump_writer_linux::app_memory::AppMemory; -#[cfg(not(any(target_arch = "mips", target_arch = "arm")))] -use minidump_writer_linux::crash_context::fpstate_t; -use minidump_writer_linux::crash_context::CrashContext; -use minidump_writer_linux::errors::*; -use minidump_writer_linux::linux_ptrace_dumper::LinuxPtraceDumper; -use minidump_writer_linux::maps_reader::{MappingEntry, MappingInfo, SystemMappingInfo}; -use minidump_writer_linux::minidump_writer::MinidumpWriter; -use minidump_writer_linux::thread_info::Pid; -use nix::errno::Errno; -use nix::sys::signal::Signal; +#[cfg(not(target_arch = "arm"))] +use minidump_writer::crash_context::fpstate_t; +use minidump_writer::{ + app_memory::AppMemory, + crash_context::CrashContext, + errors::*, + maps_reader::{MappingEntry, MappingInfo, SystemMappingInfo}, + minidump_writer::MinidumpWriter, + ptrace_dumper::PtraceDumper, + thread_info::Pid, +}; +use nix::{errno::Errno, sys::signal::Signal}; use std::collections::HashSet; -use std::convert::TryInto; + use std::io::{BufRead, BufReader}; use std::os::unix::process::ExitStatusExt; use std::process::{Command, Stdio}; @@ -429,7 +432,7 @@ fn test_with_deleted_binary() { let pid = child.id() as i32; - let build_id = LinuxPtraceDumper::elf_file_identifier_from_mapped_file(&mem_slice) + let build_id = PtraceDumper::elf_file_identifier_from_mapped_file(&mem_slice) .expect("Failed to get build_id"); let guid = GUID { diff --git a/tests/ptrace_dumper.rs b/tests/ptrace_dumper.rs index c2e8fccf..442f7424 100644 --- a/tests/ptrace_dumper.rs +++ b/tests/ptrace_dumper.rs @@ -1,4 +1,4 @@ -use minidump_writer_linux::linux_ptrace_dumper; +use minidump_writer::ptrace_dumper::PtraceDumper; use nix::sys::mman::{mmap, MapFlags, ProtFlags}; use nix::sys::signal::Signal; use std::convert::TryInto; @@ -26,8 +26,7 @@ fn test_thread_list_from_parent() { let num_of_threads = 5; let mut child = start_child_and_wait_for_threads(num_of_threads); let pid = child.id() as i32; - let mut dumper = - linux_ptrace_dumper::LinuxPtraceDumper::new(pid).expect("Couldn't init dumper"); + let mut dumper = PtraceDumper::new(pid).expect("Couldn't init dumper"); assert_eq!(dumper.threads.len(), num_of_threads); dumper.suspend_threads().expect("Could not suspend threads"); @@ -196,8 +195,7 @@ fn test_sanitize_stack_copy() { let heap_addr = usize::from_str_radix(output.next().unwrap().trim_start_matches("0x"), 16) .expect("unable to parse mmap_addr"); - let mut dumper = - linux_ptrace_dumper::LinuxPtraceDumper::new(pid).expect("Couldn't init dumper"); + let mut dumper = PtraceDumper::new(pid).expect("Couldn't init dumper"); assert_eq!(dumper.threads.len(), num_of_threads); dumper.suspend_threads().expect("Could not suspend threads"); let thread_info = dumper