diff --git a/src/bin/test.rs b/src/bin/test.rs index 36721d3d..e2ad1b54 100644 --- a/src/bin/test.rs +++ b/src/bin/test.rs @@ -6,15 +6,13 @@ pub type Result = std::result::Result; #[cfg(any(target_os = "linux", target_os = "android"))] mod linux { - use { - super::*, - error_graph::ErrorList, - minidump_writer::{ - LINUX_GATE_LIBRARY_NAME, ProcessReaderKind, - minidump_writer::{MinidumpWriter, MinidumpWriterConfig}, - }, - std::ptr, - }; + use super::*; + use error_graph::ErrorList; + use minidump_writer::Pid; + use minidump_writer::minidump_writer::{MinidumpWriter, MinidumpWriterConfig}; + use minidump_writer::remote_process_inspection as remote; + use minidump_writer::{LINUX_GATE_LIBRARY_NAME, ProcessReaderKind}; + use std::{ptr, thread}; macro_rules! test { ($x:expr, $errmsg:expr) => { @@ -41,7 +39,7 @@ mod linux { let ppid = getppid(); fail_on_soft_error!( soft_errors, - MinidumpWriterConfig::new(ppid, ppid).build_for_testing(&mut soft_errors)? + remote_mw_config(ppid, ppid).build_for_testing(&mut soft_errors)? ); Ok(()) } @@ -50,7 +48,7 @@ mod linux { let ppid = getppid(); let dumper = fail_on_soft_error!( soft_errors, - MinidumpWriterConfig::new(ppid, ppid).build_for_testing(&mut soft_errors)? + remote_mw_config(ppid, ppid).build_for_testing(&mut soft_errors)? ); test!(!dumper.threads.is_empty(), "No threads"); test!( @@ -75,7 +73,7 @@ mod linux { let ppid = getppid(); let mut dumper = fail_on_soft_error!( soft_errors, - MinidumpWriterConfig::new(ppid, ppid).build_for_testing(&mut soft_errors)? + remote_mw_config(ppid, ppid).build_for_testing(&mut soft_errors)? ); // We support 3 different methods of reading memory from another @@ -158,7 +156,7 @@ mod linux { let dumper = fail_on_soft_error!( soft_errors, - MinidumpWriterConfig::new(ppid, ppid).build_for_testing(&mut soft_errors)? + remote_mw_config(ppid, ppid).build_for_testing(&mut soft_errors)? ); dumper .find_mapping(addr1) @@ -179,7 +177,7 @@ mod linux { let dumper = fail_on_soft_error!( soft_errors, - MinidumpWriterConfig::new(ppid, ppid).build_for_testing(&mut soft_errors)? + remote_mw_config(ppid, ppid).build_for_testing(&mut soft_errors)? ); let exe_mapping = dumper @@ -200,7 +198,7 @@ mod linux { // Now check that PtraceDumper interpreted the mappings properly. let dumper = fail_on_soft_error!( soft_errors, - MinidumpWriterConfig::new(getppid(), getppid()).build_for_testing(&mut soft_errors)? + remote_mw_config(getppid(), getppid()).build_for_testing(&mut soft_errors)? ); let mut mapping_count = 0; for map in &dumper.mappings { @@ -225,7 +223,7 @@ mod linux { let ppid = getppid(); let dumper = fail_on_soft_error!( soft_errors, - MinidumpWriterConfig::new(ppid, ppid).build_for_testing(&mut soft_errors)? + remote_mw_config(ppid, ppid).build_for_testing(&mut soft_errors)? ); let linux_gate = dumper .mappings @@ -243,7 +241,7 @@ mod linux { let ppid = getppid(); let dumper = fail_on_soft_error!( soft_errors, - MinidumpWriterConfig::new(ppid, ppid).build_for_testing(&mut soft_errors)? + remote_mw_config(ppid, ppid).build_for_testing(&mut soft_errors)? ); let linux_gate_loc = dumper.auxv.get_linux_gate_address().unwrap(); test!(linux_gate_loc != 0, "linux_gate_loc == 0"); @@ -443,6 +441,65 @@ mod linux { _ => Err("Unknown test option".into()), } } + + fn remote_mw_config(process_id: Pid, blamed_thread: Pid) -> MinidumpWriterConfig { + let mut config = MinidumpWriterConfig::new(process_id, blamed_thread); + config.set_remote_transport(TransportForTestExecutor::new(process_id)); + config + } + + #[derive(Debug)] + struct TransportForTestExecutor { + transport: Option>>, + thread_handle: Option>, + } + + impl TransportForTestExecutor { + pub fn new(pid: Pid) -> Self { + let (backend_io, executor_io) = + remote::io::UnixStream::pair().expect("failed to create unix stream"); + + let thread_handle = thread::spawn(move || { + let args_buf = vec![0u8; remote::ARGS_BUFFER_LEN]; + let transport = remote::transport::postcard::Executor::new(executor_io, args_buf); + let mut executor_resources = remote::ExecutorResources::const_new(); + remote::executor::run(pid, transport, executor_resources.as_mut()) + .expect("an error occurred running the executor"); + }); + + let output_buf = vec![0u8; remote::OUTPUT_BUFFER_LEN]; + let transport = remote::transport::postcard::Backend::new(backend_io, output_buf); + + TransportForTestExecutor { + transport: Some(transport), + thread_handle: Some(thread_handle), + } + } + } + + impl Drop for TransportForTestExecutor { + fn drop(&mut self) { + drop(self.transport.take().unwrap()); + if let Err(payload) = self.thread_handle.take().unwrap().join() + && !thread::panicking() + { + std::panic::resume_unwind(payload); + } + } + } + + impl remote::transport::Backend for TransportForTestExecutor { + fn max_response_output_len(&self) -> usize { + self.transport.as_ref().unwrap().max_response_output_len() + } + + fn send_request<'output, Req: serde::Serialize, Resp: serde::Deserialize<'output>>( + &'output mut self, + req: Req, + ) -> std::result::Result { + self.transport.as_mut().unwrap().send_request(req) + } + } } #[cfg(target_os = "windows")] diff --git a/src/linux/minidump_writer/mod.rs b/src/linux/minidump_writer/mod.rs index 1330fb1f..c7198751 100644 --- a/src/linux/minidump_writer/mod.rs +++ b/src/linux/minidump_writer/mod.rs @@ -11,6 +11,7 @@ use { maps_reader::{MappingInfo, MappingList}, module_list, process_inspection::{self, ProcessInspector, process_reader::CopyFromProcessError}, + remote_process_inspection, serializers::*, thread_info::{ThreadInfo, ThreadInfoError}, }, @@ -202,6 +203,19 @@ impl MinidumpWriterConfig { self } + /// Set the transport used to communicate with the remote executor + /// + /// The [`MinidumpWriter`] is created in local mode by default. Specifying a remote Transport + /// changes it to remote mode, where it will forward all process inspection syscalls to a + /// remote process for execution. + pub fn set_remote_transport( + &mut self, + transport: T, + ) -> &mut Self { + self.process_inspector = process_inspection::remote(transport); + self + } + /// Generates a minidump and writes to the destination provided. Returns the in-memory /// version of the minidump as well. pub fn write(self, destination: &mut (impl Write + Seek)) -> Result, WriterError> { @@ -955,10 +969,8 @@ impl MinidumpWriter { src: usize, length: usize, ) -> Result, CopyFromProcessError> { - let length = - std::num::NonZeroUsize::new(length).ok_or(CopyFromProcessError::InvalidArgument)?; let mem = process_inspector.process_reader(); - mem.read_to_vec(src, length) + mem.read_all_to_vec(src, length) } } diff --git a/src/linux/mod.rs b/src/linux/mod.rs index ad9470f7..835a09e1 100644 --- a/src/linux/mod.rs +++ b/src/linux/mod.rs @@ -3,7 +3,9 @@ pub use { maps_reader::LINUX_GATE_LIBRARY_NAME, - process_inspection::{Error as BackendError, ProcessReaderKind, process_reader}, + process_inspection::{ + Error as BackendError, ProcessReaderKind, process_reader, remote_process_inspection, + }, }; pub mod app_memory; diff --git a/src/linux/process_inspection/mod.rs b/src/linux/process_inspection/mod.rs index 2fce2c79..6505a04e 100644 --- a/src/linux/process_inspection/mod.rs +++ b/src/linux/process_inspection/mod.rs @@ -1,7 +1,7 @@ use super as linux; use crate::module_reader::{ModuleMemoryReadError, ReadError, ReadModuleMemory}; use linux::maps_reader; -use process_backend::{ProcessReader as _, Stat, local, regs::*}; +use process_backend::{ProcessReader as _, Stat, local, regs::*, remote}; use process_reader::{CopyFromProcessError, ProcessReader, ProcessReaderBackend}; use std::{ borrow::Cow, @@ -20,10 +20,71 @@ pub use process_backend::ProcessReaderKind; pub mod process_reader; +pub mod remote_process_inspection { + use process_backend::remote::executor::resources::*; + + pub mod executor { + pub use process_backend::remote::executor::{Error, Resources, run}; + } + + pub use process_backend::remote::{io, transport}; + + pub const ARGS_BUFFER_LEN: usize = super::MAX_INPUT_PATH_LEN; + pub const OUTPUT_BUFFER_LEN: usize = SCRATCH_BUFFER_LEN; + + // All of these are arbitrary and may need to be adjusted + const MAX_SIMULTANEOUS_OPEN_FILES: usize = 5; + const MAX_SIMULTANEOUS_OPEN_DIRS: usize = 5; + const MAX_SIMULTANEOUS_OPEN_MODULE_MEMORY_READERS: usize = 5; + const SCRATCH_BUFFER_LEN: usize = + if super::MAX_SYMLINK_TARGET_LEN > super::MAX_DIRECTORY_NAME_LENGTH { + super::MAX_SYMLINK_TARGET_LEN + } else { + super::MAX_DIRECTORY_NAME_LENGTH + }; + + pub struct ExecutorResources { + file_readers: [FileReader; MAX_SIMULTANEOUS_OPEN_FILES], + dir_readers: [DirReader; MAX_SIMULTANEOUS_OPEN_DIRS], + mapped_module_memory_readers: + [MappedModuleMemoryReader; MAX_SIMULTANEOUS_OPEN_MODULE_MEMORY_READERS], + scratch_buf: [u8; SCRATCH_BUFFER_LEN], + } + + impl ExecutorResources { + pub const fn const_new() -> ExecutorResources { + ExecutorResources { + file_readers: FileReader::new_array(), + dir_readers: DirReader::new_array(), + mapped_module_memory_readers: MappedModuleMemoryReader::new_array(), + scratch_buf: [0; SCRATCH_BUFFER_LEN], + } + } + + pub const fn as_mut(&mut self) -> Resources<'_> { + Resources { + file_readers: &mut self.file_readers, + dir_readers: &mut self.dir_readers, + mapped_module_memory_readers: &mut self.mapped_module_memory_readers, + scratch_buf: &mut self.scratch_buf, + } + } + } +} + pub(crate) type Result = core::result::Result; -// These are both arbitrary choices and may need to be tweaked -const MAX_PATH_LEN: usize = 65536; +// These are arbitrary choices and are probably way bigger than they need to be. +// They probably could be optimized further... + +// The longest path that may be passed as an argument to any of the APIs that +// take a PathBuf arg. Realistically, even this is a fairly conservative number. +const MAX_INPUT_PATH_LEN: usize = 1024; + +// The longest symlink we'd ever expect to get from a call to read_link() +const MAX_SYMLINK_TARGET_LEN: usize = 1024; + +/// The longest directory name we'd expect to see from a read_dir() iterator const MAX_DIRECTORY_NAME_LENGTH: usize = 256; pub(crate) fn local(pid: libc::pid_t) -> Box { @@ -31,6 +92,13 @@ pub(crate) fn local(pid: libc::pid_t) -> Box { Box::new(local::Backend::new(pid)) } +pub(crate) fn remote<'t, T: remote_process_inspection::transport::Backend + 't>( + transport: T, +) -> Box { + set_process_backend_drop_fail_handler(); + Box::new(remote::backend::Backend::new(transport)) +} + pub trait ProcessInspector: core::fmt::Debug { fn process_reader<'a>(&'a self) -> ProcessReader<'a>; fn pid(&self) -> Result; @@ -61,6 +129,15 @@ pub trait ProcessInspector: core::fmt::Debug { fn fail_one_syscall_with(&self, errno: core::ffi::c_int); } +fn path_to_cstring(path: PathBuf) -> Result { + let c_path = CString::new(path.into_os_string().into_vec()).unwrap(); + if c_path.as_bytes_with_nul().len() <= MAX_INPUT_PATH_LEN { + Ok(c_path) + } else { + Err(Error::InputPathTooLong) + } +} + impl ProcessInspector for B { fn process_reader<'a>(&'a self) -> ProcessReader<'a> { ProcessReader::new(self) @@ -97,25 +174,25 @@ impl ProcessInspector for B { } fn stat_file(&self, path: PathBuf) -> Result { - let c_path = CString::new(path.into_os_string().into_vec()).unwrap(); + let c_path = path_to_cstring(path)?; B::stat_file(self, &c_path).map_err(Error::Backend) } fn read_file<'a>(&'a self, path: PathBuf) -> Result> { - let c_path = CString::new(path.into_os_string().into_vec()).unwrap(); + let c_path = path_to_cstring(path)?; let reader = B::read_file(self, &c_path).map_err(Error::Backend)?; Ok(FileReader(Box::new(reader))) } fn read_dir<'a>(&'a self, path: PathBuf) -> Result> { - let c_path = CString::new(path.into_os_string().into_vec()).unwrap(); + let c_path = path_to_cstring(path)?; let reader = B::read_dir(self, &c_path).map_err(Error::Backend)?; Ok(DirReader(Box::new(reader))) } fn read_link(&self, path: PathBuf) -> Result { - let c_path = CString::new(path.into_os_string().into_vec()).unwrap(); - let mut buf = vec![0u8; MAX_PATH_LEN]; + let c_path = path_to_cstring(path)?; + let mut buf = vec![0u8; MAX_SYMLINK_TARGET_LEN]; let len = B::read_link(self, &c_path, &mut buf).map_err(Error::Backend)?; buf.truncate(len); Ok(PathBuf::from(OsString::from_vec(buf))) @@ -205,9 +282,14 @@ impl<'a> MappedModuleMemoryReader<'a> { loop { let bytes_read = self.0.read_at(offset, buf).map_err(Error::Backend)?; + if bytes_read == 0 { + return Err(Error::UnexpectedEndOfBuffer); + } + if bytes_read == buf.len() { return Ok(()); } + offset = offset .checked_add(bytes_read) .ok_or(Error::AddressOverflowed)?; @@ -270,6 +352,8 @@ pub enum Error { UnexpectedEndOfBuffer, #[error("got an unexpected end of file")] UnexpectedEndOfFile, + #[error("a path argument was too long")] + InputPathTooLong, } fn set_process_backend_drop_fail_handler() { diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 74fc0f42..9fb5e30d 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,11 +1,7 @@ -use std::{ - error, - io::{BufRead, BufReader}, - process::{Child, Command, Stdio}, - result, -}; - use serde::Serialize; +use std::io::{BufRead, BufReader}; +use std::process::{Child, Command, Stdio}; +use std::{error, result}; #[allow(unused)] type Error = Box; @@ -258,13 +254,15 @@ pub use linux::*; #[cfg(any(target_os = "linux", target_os = "android"))] #[allow(unused)] mod linux { - use { - minidump_writer::{ - CrashContextExt, Pid, - module_reader::{self, ModuleMemoryReadError, ReadModuleMemory}, - }, - std::borrow::Cow, - }; + use minidump_writer::minidump_writer::MinidumpWriterConfig; + use minidump_writer::module_reader::{self, ModuleMemoryReadError, ReadModuleMemory}; + use minidump_writer::remote_process_inspection; + use minidump_writer::{CrashContextExt, Pid}; + use procfs_core::process; + use remote_process_inspection as remote; + use std::borrow::Cow; + use std::thread; + pub struct SliceModuleMemoryReader<'a>(pub &'a [u8]); impl<'a> ReadModuleMemory for SliceModuleMemoryReader<'a> { @@ -319,6 +317,65 @@ mod linux { }, } } + + pub fn remote_mw_config(process_id: Pid, blamed_thread: Pid) -> MinidumpWriterConfig { + let mut config = MinidumpWriterConfig::new(process_id, blamed_thread); + config.set_remote_transport(TransportForTestExecutor::new(process_id)); + config + } + + #[derive(Debug)] + pub struct TransportForTestExecutor { + transport: Option>>, + thread_handle: Option>, + } + + impl TransportForTestExecutor { + pub fn new(pid: Pid) -> Self { + let (backend_io, executor_io) = + remote::io::UnixStream::pair().expect("failed to create unix stream"); + + let thread_handle = thread::spawn(move || { + let args_buf = vec![0u8; remote::ARGS_BUFFER_LEN]; + let transport = remote::transport::postcard::Executor::new(executor_io, args_buf); + let mut executor_resources = remote::ExecutorResources::const_new(); + remote::executor::run(pid, transport, executor_resources.as_mut()) + .expect("an error occurred running the executor"); + }); + + let output_buf = vec![0u8; remote::OUTPUT_BUFFER_LEN]; + let transport = remote::transport::postcard::Backend::new(backend_io, output_buf); + + TransportForTestExecutor { + transport: Some(transport), + thread_handle: Some(thread_handle), + } + } + } + + impl Drop for TransportForTestExecutor { + fn drop(&mut self) { + drop(self.transport.take().unwrap()); + if let Err(payload) = self.thread_handle.take().unwrap().join() + && !thread::panicking() + { + std::panic::resume_unwind(payload); + } + } + } + + impl remote::transport::Backend for TransportForTestExecutor { + fn max_response_output_len(&self) -> usize { + self.transport.as_ref().unwrap().max_response_output_len() + } + + fn send_request<'output, Req: serde::Serialize, Resp: serde::Deserialize<'output>>( + &'output mut self, + req: Req, + ) -> Result { + self.transport.as_mut().unwrap().send_request(req) + } + } } fn print_stdio(bytes: &[u8]) { diff --git a/tests/linux_minidump_writer.rs b/tests/linux_minidump_writer.rs index 71fbec90..e9f7af98 100644 --- a/tests/linux_minidump_writer.rs +++ b/tests/linux_minidump_writer.rs @@ -1,26 +1,20 @@ #![cfg(any(target_os = "linux", target_os = "android"))] #![allow(unused_imports, unused_variables)] -use { - common::*, - minidump::*, - minidump_common::format::{GUID, MINIDUMP_STREAM_TYPE::*}, - minidump_writer::{ - CrashContextExt, Pid, - app_memory::AppMemory, - maps_reader::{MappingEntry, MappingInfo}, - minidump_writer::{MinidumpWriter, MinidumpWriterConfig, errors::WriterError}, - module_reader::{self}, - }, - procfs_core::process::MMPermissions, - serde_json::json, - std::{ - collections::HashSet, - io::{BufRead, BufReader}, - os::unix::process::ExitStatusExt, - process::{Command, Stdio}, - }, -}; +use common::*; +use minidump::*; +use minidump_common::format::{GUID, MINIDUMP_STREAM_TYPE::*}; +use minidump_writer::app_memory::AppMemory; +use minidump_writer::maps_reader::{MappingEntry, MappingInfo}; +use minidump_writer::minidump_writer::{MinidumpWriter, MinidumpWriterConfig, errors::WriterError}; +use minidump_writer::module_reader; +use minidump_writer::{CrashContextExt, Pid}; +use procfs_core::process::MMPermissions; +use serde_json::json; +use std::collections::HashSet; +use std::io::{BufRead, BufReader}; +use std::os::unix::process::ExitStatusExt; +use std::process::{Command, Stdio}; mod common; @@ -32,7 +26,7 @@ enum Context { impl Context { pub fn minidump_writer(&self, pid: Pid) -> MinidumpWriterConfig { - let mut mw = MinidumpWriterConfig::new(pid, pid); + let mut mw = remote_mw_config(pid, pid); if self == &Context::With { let crash_context = get_dummy_crash_context(pid); mw.set_crash_context(crash_context); @@ -213,7 +207,7 @@ fn module_list_properties() { .tempfile() .unwrap(); - MinidumpWriterConfig::new(pid, pid) + remote_mw_config(pid, pid) .write(&mut tmpfile) .expect("could not write minidump"); @@ -580,7 +574,7 @@ fn minidump_size_limit() { .tempfile() .unwrap(); - MinidumpWriterConfig::new(pid, pid) + remote_mw_config(pid, pid) .write(&mut tmpfile) .expect("Could not write minidump"); @@ -612,7 +606,7 @@ fn minidump_size_limit() { .tempfile() .unwrap(); - let mut tmp = MinidumpWriterConfig::new(pid, pid); + let mut tmp = remote_mw_config(pid, pid); tmp.set_minidump_size_limit(minidump_size_limit); tmp.write(&mut tmpfile).expect("Could not write minidump"); @@ -658,7 +652,7 @@ fn minidump_size_limit() { .tempfile() .unwrap(); - let mut tmp = MinidumpWriterConfig::new(pid, pid); + let mut tmp = remote_mw_config(pid, pid); tmp.set_minidump_size_limit(minidump_size_limit); tmp.write(&mut tmpfile).expect("Could not write minidump"); @@ -745,7 +739,7 @@ fn with_deleted_binary() { .tempfile() .unwrap(); - MinidumpWriterConfig::new(pid, pid) + remote_mw_config(pid, pid) .write(&mut tmpfile) .expect("Could not write minidump"); @@ -806,7 +800,7 @@ fn memory_info_list_stream() { .unwrap(); // Write a minidump - MinidumpWriterConfig::new(pid, pid) + remote_mw_config(pid, pid) .write(&mut tmpfile) .expect("cound not write minidump"); child.kill().expect("Failed to kill process"); diff --git a/tests/linux_minidump_writer_soft_error.rs b/tests/linux_minidump_writer_soft_error.rs index d4a999d7..e9ac5b11 100644 --- a/tests/linux_minidump_writer_soft_error.rs +++ b/tests/linux_minidump_writer_soft_error.rs @@ -2,7 +2,7 @@ use common::*; use minidump::Minidump; -use minidump_writer::{FailSpotName, minidump_writer::MinidumpWriterConfig}; +use minidump_writer::FailSpotName; mod common; @@ -20,7 +20,7 @@ fn soft_error_stream() { fail_client.set_enabled(FailSpotName::StopProcess, true); // Write a minidump - MinidumpWriterConfig::new(pid, pid) + remote_mw_config(pid, pid) .write(&mut tmpfile) .expect("cound not write minidump"); child.kill().expect("Failed to kill process"); @@ -53,7 +53,7 @@ fn soft_error_stream_content() { } // Write a minidump - MinidumpWriterConfig::new(pid, pid) + remote_mw_config(pid, pid) .write(&mut tmpfile) .expect("cound not write minidump"); child.kill().expect("Failed to kill process"); @@ -88,7 +88,7 @@ fn thread_stack_pointer_unmapped_soft_error() { let mut fail_client = FailSpotName::testing_client(); fail_client.set_enabled(FailSpotName::StackPointerMapping, true); - MinidumpWriterConfig::new(pid, pid) + remote_mw_config(pid, pid) .write(&mut tmpfile) .expect("could not write minidump"); child.kill().expect("Failed to kill process"); @@ -111,7 +111,7 @@ fn thread_stack_unreadable_soft_error() { let mut fail_client = FailSpotName::testing_client(); fail_client.set_enabled(FailSpotName::ThreadStackCopy, true); - MinidumpWriterConfig::new(pid, pid) + remote_mw_config(pid, pid) .write(&mut tmpfile) .expect("could not write minidump"); child.kill().expect("Failed to kill process"); @@ -134,7 +134,7 @@ fn crashing_thread_ip_memory_unreadable_soft_error() { let mut fail_client = FailSpotName::testing_client(); fail_client.set_enabled(FailSpotName::CrashingThreadIpCopy, true); - let mut config = MinidumpWriterConfig::new(pid, pid); + let mut config = remote_mw_config(pid, pid); config.set_crash_context(get_dummy_crash_context(pid)); config .write(&mut tmpfile) diff --git a/tests/ptrace_dumper.rs b/tests/ptrace_dumper.rs index 299837fe..9a269551 100644 --- a/tests/ptrace_dumper.rs +++ b/tests/ptrace_dumper.rs @@ -1,19 +1,14 @@ //! All of these tests are specific to ptrace #![cfg(any(target_os = "linux", target_os = "android"))] -use { - common::*, - error_graph::ErrorList, - minidump_writer::minidump_writer::MinidumpWriterConfig, - std::{ - convert::TryInto, - ffi::c_void, - io::{BufRead, BufReader}, - mem::size_of, - os::unix::process::ExitStatusExt, - ptr, - }, -}; +use common::*; +use error_graph::ErrorList; +use std::convert::TryInto; +use std::ffi::c_void; +use std::io::{BufRead, BufReader}; +use std::mem::size_of; +use std::os::unix::process::ExitStatusExt; +use std::ptr; mod common; @@ -106,7 +101,7 @@ fn thread_list_from_parent() { let dumper = assert_no_soft_errors!( soft_errors, - MinidumpWriterConfig::new(pid, pid).build_for_testing(&mut soft_errors) + remote_mw_config(pid, pid).build_for_testing(&mut soft_errors) ) .expect("Couldn't init dumper"); @@ -287,7 +282,7 @@ fn sanitizes_stack_copies() { let dumper = assert_no_soft_errors!( soft_errors, - MinidumpWriterConfig::new(pid, pid).build_for_testing(&mut soft_errors) + remote_mw_config(pid, pid).build_for_testing(&mut soft_errors) ) .expect("Couldn't init dumper"); assert_eq!(dumper.threads.len(), num_of_threads);