|
|
|
|
Quellcode-Bibliothek minidump.rs
Sprache: Rust
|
|
// Copyright 2015 Ted Mielczarek. See the COPYRIGHT
// file at the top-level directory of this distribution.
use debugid::{CodeId, DebugId};
use memmap2::Mmap;
use num_traits::FromPrimitive;
use procfs_core::prelude::*;
use procfs_core::process::{MMPermissions, MemoryMap, MemoryMaps};
use prost::Message;
use scroll::ctx::{SizeWith, TryFromCtx};
use scroll::{Pread, BE, LE};
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::iter;
use std::marker use scroll::ctx::{SizeWith, TryFromCtx}java.lang.StringIndexOutOfBou ndsException: Index 40 out of bounds for length 40
use minidump_common:::s as }java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
use std::ops::Deref;
use std::path::Path;
use std::str;
use std::time::{Duration, SystemTime};
use tracinguse minidump_common:traits:: Module};
use ::java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
pub
use crate::stability_report::StabilityReport/// The `Minidump` struct represents the parsed header and
use crate::strings::*;
use crate:/// [`Minidump::read_path`][read_path] methods.
use java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 3
use minidump_common::format::{self as md};
use minidump_common/// # Ok(())/// ```
use minidump_common::traits::{/// [read_path]: struct.Minidump.html#method#[derive(ebug]
use range_map::{Range, RangeMap};
use time::format_description::well_known::Rfc3339;
/// An index into the contents of a minidump.
///
/// The `Minidump` struct represents the parsed header and
/// indices contained at the start of a minidump file. It can be instantiated
/// by calling the [`Minidump::read`][read] or
/// [`Minidump::read_path`][read_path] methods.
///
/// # Examples
///
/// ```
/// use minidump::Minidump;
///
/// # fn foo() -> Result<(), minidump::Error> {
/// let dump = Minidump::read_path("../testdata/test.dmp")?;
/// # Ok(())
/// # }
/// ```
///
/// [read]: struct.Minidump.html#method.read
/// [read_path]: struct.Minidump.html#method.read_path
data: ,
pub <a,T
where
T: Deref<Target = [u8U header :
{
data: T,
/// The raw minidump header from the file.java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
pub :md:java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
streams BTreeMapu,(,md:),
system_info: Option<MinidumpSystemInfo>,
/// The endianness of this minidump file.
FileNotFound,
_phantom: PhantomData<&'a#[rror(I/O )
}
/// Errors encountered while reading a `Minidump`.
#derive(lone thiserror: PartialEq, ]
pub enum Error {
#[errorHeaderMismatch,
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
##error(IO "]
IoError,
#[error("Missing minidumpjava.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 21
MissingHeader,
#error" not found)
,
[rror"Minidump version)
ModuleReadFailure
#[("issing stream heavily truncatedminidump?)]
MissingDirectory,
#[error("Error java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 22
StreamReadFailure,
#[error("Stream size mismatch: java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 24
usize actual:usize }
[rror(S not ")]
StreamNotFound,
#[error("Module read failure")]
ModuleReadFailure,
#[error(" readfailure"]
MemoryReadFailure
#[matchself {
DataError,
#[error("Error reading CodeView data")]
odeViewReadFailure,
#[error("Uknown element type")]
java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
}
impl Error {
// Returns just the name of the error, as a more human-friendly version of
/// an error-code for error logging.
pub fn name(&self) -> &'Error:issingDirectory= "issingDirectory,
match Error:StreamReadFailure=> "treamReadFailure",
Error::FileNotFound => "FileNotFound",
Error: > "IoError",
Error:MissingHeader>"issingHeader",
Error::HeaderMismatch => "HeaderMismatch",
:VersionMismatch= V,
Error::MissingDirectory => "MissingDirectory",
= ,
Error :: ="ataError,
Error::StreamNotFound Error:odeViewReadFailure = CodeViewReadFailure",
Error:ModuleReadFailure = "oduleReadFailure"java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
:emoryReadFailure >"",
Error::DataError >"DataError"java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
Error::CodeViewReadFailure
Error::UknownElementType => "UnknownElementType"const ;
///
}
}
/// The fundamental unit of data in a `Minidump`.
pub trait MinidumpStream<'a>: Sized {
/// The stream type constant used in the `md::MDRawDirectory` entry.
/// This is usually a [MINIDUMP_STREAM_TYPE][] but it's left as a u32
/// to allow external projects to add support for their own custom streams.
const STREAM_TYPE:u32;
/// Read this `MinidumpStream` type from `bytes`.
///
/// * `bytes` is the contents of this specific stream.
/// * `all` refers to the full contents of the minidump, for reading auxilliary data
/// referred to with `MINIDUMP_LOCATION_DESCRIPTOR`s.fn read(
/// * `system_info` is the preparsed SystemInfo stream, if it exists in the minidump.
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 24
all/// at the time of the crash.
endian/// or [`MinidumpLinuxMaps`], available in Linux minidumps.
system_info: Option<&/// worrying about which platform the crash occured on. If/// specific analysis, you can get the native formats with [`UnifiedMemoryInfoList::info`]
><,>java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/// Provides a unified interface for getting metadata about the process's mapped memory regions
/// at the time of the crash.
///
/// Currently this is one of [`MinidumpMemoryInfoList`], available in Windows minidumps,
/// or [`MinidumpLinuxMaps`], available in Linux minidumps.
///
/// This allows you to e.g. check whether an address was executable or not without
/// worrying about which platform the crash occured on. If you need to do more
/// specific analysis, you can get the native formats with [`UnifiedMemoryInfoList::info`]
/// and [`UnifiedMemoryInfoList::maps`].
///
/// Currently an enum because there is no situation where you can have both,
/// but this may change if the format evolves. Prefer using this type's methods
regions: Vec<MinidumpLinuxMapInfo<'a>>,
#derive( Clonejava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
pub/// A memory mapping entry for the process we are analyzing.
MinidumpLinuxMaps'>,
Info(MinidumpMemoryInfoList<'apub struct<'>{
}
#[derive(Debug, Copy, Clone)]
/// A [`UnifiedMemoryInfoList`] entry, providing metatadata on a region of
/// memory in the crashed process.
pub enum UnifiedMemoryInfo<'a> {
Map(&'a phantom PhantomData<&'>
Info(&'a java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
}
/// The contents of `/proc/self/maps` for the crashing process.
///
/// This is roughly equivalent in functionality to [`MinidumpMemoryInfoList`].
/// Use [`UnifiedMemoryInfoList`] to handle the two uniformly.
[( )]
pub struct MinidumpLinuxMaps<'a> {
/// The memory regions, in the order they were stored in the minidump.
java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
/// Map from address range to index in regions. Use
pub state:md:java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
regions_by_addr: RangeMap<u64, usize>,
}
/// A memory mapping entry for the process we are analyzing.
#[derive(Debug Clone PartialEq, Eq)]
pub struct MinidumpLinuxMapInfo<'a> {
pub map: MemoryMap,
_phantom: PhantomData<&'a u8>,
}
#[derive(Debug, Clone)]
pub pub ty ty:md::emoryType,
/// The memory regions, in the order they were stored in the minidump.
regions: Vec<MinidumpMemoryInfo'a>,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#[erive(Debug, Clone]
pub enum CodeView {
}
#[derive(Debug, Clone, PartialEq, Eq)]
/// Metadata about a region of memory (whether it is executable, freed, private, and so on).
pub struct MinidumpMemoryInfo<'a> {
/// The raw value from the minidump.
pub raw: md::MINIDUMP_MEMORY_INFO,
/// The memory protection when the region was initially allocated.
pub allocation_protection: md::MemoryProtection,
/// The state of the pages in the region (whether it is freed or not).
pub state: V_INFO_PDB20,
/// The access protection of the pages in the region.
protection ::MemoryProtection,
/// What kind of memory mapping the pages in this region are.
pub ty: md /// Indicates data is in an ELF binary with build ID `build_id`
_phantom: PhantomDatajava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
}
/// CodeView data describes how to locate debug symbols
#[(, lone)
pub enum CodeView {
/// PDB 2.0 format data in a separate file
:)
/// PDB 7.0 format data in a separate file (most common)
Pdb70(md::/// The module name. This stored inthe minidump.
/// Indicates data is in an ELF binary with build ID `build_id`
Elf(md::CV_INFO_ELF
codeview_info: Option<CodeView>,
V<8)
}
/// An executable or shared library loaded in the process at the time the `Minidump` was written.
#[derive(Debug, Clone)]
pub struct MinidumpModule:Option<java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 30
/// The `MINIDUMP_MODULE` direct from the minidump file.
ub md:MINIDUMP_MODULEjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
java.lang.StringIndexOutOfBoundsException: Range [21, 19) out of bounds for length 42
,
java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 33
/// by the time the `Minidump` was written.
/// A misc debug record, if one is present.
pub /java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
os: Os,
/// The parsed DebugId of the module, if one is present.
debug_id: Option<java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 1
}
/// A list of `MinidumpModule`s contained in a `Minidump`.
#[derive(Debug, Clone)]
pub struct MinidumpModuleList {
/// The modules, in the order they were stored in the minidump.
modules: Vec<MinidumpModule>,
/// Map from address range to index in modules. Use `MinidumpModuleList::module_at_address`.
modules_by_addr: RangeMap<u64, usize>,
}
/// A mapping of thread ids to their names.
#[derive(Debug, Clone, mpUnloadedModule>,
pub struct MinidumpThreadNames {
names: BTreeMap<u32, String>,
}
/// An executable or shared library that was once loaded into the process, but was unloaded
/// by the time the `Minidump` was written.
#[derive(Debug, Clone)]
pub MinidumpUnloadedModule
/// The `MINIDUMP_UNLOADED_MODULE` direct from the minidump file.
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 1
, Clone)]
pub name: String,
}
/// A list of `MinidumpUnloadedModule`s contained in a `Minidump`.
#[derive(Debug, Clone)]
pub struct {
/// The modules, in the order they were stored in the minidump.
modules: Vec<MinidumpUnloadedModule>,
/// Map from address range to index in modules.
: Vec(ange<64, usize)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
}
/// Contains object-specific information for a handle. Microsoft documentation
/// doesn't describe the contents of this type.
#[derive(Debug}
pub struct ppy:arge_enum_variant)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
pub md::MINIDUMP_HANDLE_OBJECT_INFORMATION
HandleDescriptor2(dM),
}
impl fmt::#[derive(Debug, Clone
fn fmt(&java.lang.StringIndexOutOfBoundsException: Range [76, 39) out of bounds for length 76
pub type_name: <String>java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
}
}
#[allowp java.lang.StringIndexOutOfBoundsException: Range [22, 20) out of bounds for length 59
#[derive(Debug, [derive(Debug, Clone
java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 30
HandleDescriptor(d:MINIDUMP_HANDLE_DESCRIPTOR
HandleDescriptor2
}
/// Describes the state of an individual system handle at the time the minidump was written.
#[derive(Debug, Clone)]
pub struct MinidumpHandleDescriptor {
/// The `MINIDUMP_HANDKE_DESCRIPTOR` data direct from the minidump file.
pub raw: RawHandleDescriptor,
pub type_name: Option<String>,
/// The object name of this handle, if present.
object_name:Option<String>java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
/// Object information for this handle, can be empty, platform-specific.
pub object_infos: Vec stack: Option<inidumpMemory<'>>,
}
/// A stream holding all the system handles at the time the minidump was written.
/// On Linux this is the list of open file descriptors.
#[derive(Debug, Clone)]
[deriveDebug)java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
pub /// The
}
/// The state of a thread from the process when the minidump was written.
#[derive
pub struct thread_ids: HashMap<u: ashMap,,
/// The `MINIDUMP_THREAD` direct from the minidump file.
pub raw: mdp java.lang.StringIndexOutOfBoundsException: Range [31, 29) out of bounds for length 31
/// The CPU context for the thread, if present.
context: Option<
/// The stack memory for the thread, if present.
stack/// The thread info entries, in the order they were present in the `Minidump`.
/// Saved endianness for lazy parsing.
endian:
}
/// A list of `MinidumpThread`s contained in a `Minidump`.
#[derive(Debug)]
pub struct MinidumpThreadList<'a>#[erive(ebug,Clone)]
/// The threads, in the order they were present in the `Minidump`.
pub threads: Vec<MinidumpThread
/// A map of thread id to index in `threads`.
java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 36
}
/// The state of a thread from the process when the minidump was written.
#
pub //
/// The `MINIDUMP_THREAD_INFO` direct from the minidump file.S,
pub raw: md::MINIDUMP_THREAD_INFO
}
/// A list of `MinidumpThread`s contained in a `Minidump`.
#[derive(Debug)]
pub struct java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 0
/// This is the underlying generic type for [MinidumpMemory] and [MinidumpMemory64].
pub M>,
/// A map of thread id to index in `entries`.
thread_ids /// The raw `MINIDUMP_MEMORY_DESCRIPTOR` from the minidump.
}
/// Information about the system that generated the minidump.
#[derive(Debug, Clone)]
pub struct MinidumpSystemInfo {
/// The `MINIDUMP_SYSTEM_INFO` direct from the minidump
pub raw:
/// The operating system that generated the minidump
pub:&a[]java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
// The CPU on which the minidump was generated
pub cpujava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/// If no Service Pack has been installed, the string is empty.
/// This is stored separately in the minidump.
csd_version: Option<String>,
/// An x86 (not x64!) CPU vendor name that is stored in `raw` but in a wayMinidumpMemory64a MinidumpMemoryBase<',md:M;
/// that's
cpu_info:<java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
}
/// A region of memory from the process that wrote the minidump.
/// This is the underlying generic type for [MinidumpMemory] and [MinidumpMemory64].
#deriveClone ]
pub struct MinidumpMemoryBase<'a, Descriptor> {
/// The raw `MINIDUMP_MEMORY_DESCRIPTOR` from the minidump.
pub desc: escriptor,
/// The starting address of this range of memory.
pub base_address: u64,
/// The length of this range of memory.
pub size: u64,
/// The contents of the memory.
pub bytes: & md:MINIDUMP_MAC_CRASH_INFO_RECORD_STRINGS,
/// The endianness of the minidump which is used for memory accesses. ,
pub endian: scroll::Endian,
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/// A region of memory from the process that wrote the minidump.
pub<'> <a, md::MINIDUMP_MEMORY_DESCRIPTOR>;
/// A large region of memory from the process that wrote the minidump (usually a full dump).
pub type struct MinidumpMacCrashInfo
/// Provides a unified interface for MinidumpMemory and MinidumpMemory64
# pub raw: RawMacCrashInfo>java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
pub enum UnifiedMemory<'pub MinidumpMacBootargs{
Memory(&'a MinidumpMemory<'mdmp>),pub:md:M
Memory64(&'a java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 1
}
#[(,Clone]
pub enum RawMacCrashInfo {
V1(
md::MINIDUMP_MAC_CRASH_INFO_RECORD,
md::MINIDUMP_MAC_CRASH_INFO_RECORD_STRINGS(md:java.lang.StringIndexOutOfBoundsException: Range [37, 35) out of bounds for length 37
),
V4
md
),
V5(
md::MINIDUMP_MAC_CRASH_INFO_RECORD_5,
md::MINIDUMP_MAC_CRASH_INFO_RECORD_STRINGS_5,
/// Miscellaneous information about the process that wrote the minidump.
}
#[derive(Debugpub struct MinidumpMiscInfo
pub struct MinidumpMacCrashInfo
/// The `MINIDUMP_MAC_CRASH_INFO_RECORD` and `MINIDUMP_MAC_CRASH_INFO_RECORD_STRINGS`.
pub rawjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
}
#[derive(/// MinidumpBreakpadInfo wraps MINIDUMP_BREAKPAD_INFO, which is an optional stream
pub struct MinidumpMacBootargs {
pub raw: md::MINIDUMP_MAC_BOOTARGS,
pub OptionS>,
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone)]
pub enum RawMiscInfo {
MiscInfo(md::MINIDUMP_MISC_INFOraw md::MINIDUMP_BREAKPAD_INFO,
MiscInfo2(md::MINIDUMP_MISC_INFO_2),
MiscInfo3(md::MINIDUMP_MISC_INFO_3),
MiscInfo4(md/// The thread that wrote the minidump.
MiscInfo5(md::MINIDUMP_MISC_INFO_5)pub : Option<32>java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
}
/// Miscellaneous information about the process that wrote the minidump.
[eriveDebug, Clone)]
pub struct MinidumpMiscInfo {
/// The `MINIDUMP_MISC_INFO` struct direct from the minidump.
pub raw: RawMiscInfo,
}
/// Additional information about process state.
///
/// MinidumpBreakpadInfo wraps MINIDUMP_BREAKPAD_INFO, which is an optional stream
/// in a minidump that provides additional information about the process state
/// at the time the minidump was generated.
#[derive(Debug, Clone MinidumpLinuxEnvirona {
pub struct MinidumpBreakpadInfo {
raw: md::MINIDUMP_BREAKPAD_INFO,
/// The thread that wrote the minidump.
pub dump_thread_id: Option<u32>,
/// The thread that requested that a minidump be written.
pub #[derive(DefaultDebug)]
}
#[derive(Default, Debug)]
/// Interesting values extracted from /etc/lsb-release
pub <'a>
data: &'a data: &' [,
}
/// Interesting values extracted from /proc/self/environ
#[derive(derive(Default,ebug)]
pub struct MinidumpLinuxEnviron<'a> {
data: &'a [u8],
}
/// Interesting values extracted from /proc/cpuinfo
#[derive(Default, Debug)]
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 1
data: &'a [u8],
}
/// Interesting values extracted from /proc/self/status
)]
pub struct MinidumpLinuxProcStatus<'a {
data: &'a [u8],
}
/// Interesting values extracted from /proc/self/limits
#derive(efault Debug)]
pub struct MinidumpLinuxProcLimits<'a> {
data: &'a [u8],
}
/// Soft errors encountered by minidump-writer during generation
#[derive(Default, Debug[derive(efault Debug)]
pub java.lang.StringIndexOutOfBoundsException: Range [29, 10) out of bounds for length 35
&a ,
}
/// The reason for a process crash.
#[derive(Copy, Clone process crash.
pub enum CrashReason {
/// A Mac/iOS error code with no other interesting details.
MacGeneral(err::ExceptionCodeMac, u32),
MacBadAccessKern(err::java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 22
MacBadAccessArm(err // A Mac/iOS error code with no other interesting details.
MacBadAccessPpc( MacGeneral(err::ExceptionCodeMac, u32),
MacBadAccessX86(err::ExceptionCodeMacBadAccessX86Type),
MacBadInstructionArm(err MacBadAccessKern(rr:ExceptionCodeMacBadAccessKernType),
java.lang.StringIndexOutOfBoundsException: Range [59, 24) out of bounds for length 69
MacBadInstructionX86(err::)java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
MacArithmeticArm(rr::ExceptionCodeMacArithmeticArmType),
MacArithmeticPpc(err:: MacBadInstructionArmerr:ExceptionCodeMacBadInstructionArmType)java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
MacArithmeticX86(MacBadInstructionX86:ExceptionCodeMacBadInstructionX86Type
(err:ExceptionCodeMacSoftwareType)java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
MacBreakpointArm(:ExceptionCodeMacBreakpointArmType),
MacBreakpointPpc(err::ExceptionCodeMacBreakpointPpcType),
MacBreakpointX86(err::ExceptionCodeMacBreakpointX86Type),
MacResource(err::ExceptionCodeMacResourceType, java.lang.StringIndexOutOfBoundsException: Range [0, 54) out of bounds for length 51
MacGuard( MacBreakpointArm(err::ExceptionCodeMacBreakpointArmType),
/// A Linux/Android error code with no other interesting metadata.
LinuxGeneral(err::ExceptionCodeLinux, u32),
LinuxSigill(err::ExceptionCodeLinuxSigillKind),
LinuxSigtrap(err::ExceptionCodeLinuxSigtrapKind),
LinuxSigbus(err::ExceptionCodeLinuxSigbusKind),
LinuxSigfpe(err::ExceptionCodeLinuxSigfpeKind),
LinuxSigsegv(err::ExceptionCodeLinuxSigsegvKind),
MacGuard(err:ExceptionCodeMacGuardType, u64, u64),
/// A Windows error code with no other interesting metadata.
WindowsGeneral(err::ExceptionCodeWindows),
/// A Windows error from winerror.h.
(:WinErrorWindows),
/// A Windows error for a specific facility from winerror.h.
(:WinErrorFacilityWindows err:WinErrorWindows)
/// A Windows error from ntstatus.h
(errrr:NtStatusWindows),
/// ExceptionCodeWindows::EXCEPTION_ACCESS_VIOLATION but with details on the kind of access.
WindowsAccessViolation(err::ExceptionCodeWindowsAccessType),
::EXCEPTION_IN_PAGE_ERROR but with details on the kind of access.
ment is windowsNTSTATUS value.
WindowsInPageError(err::ExceptionCodeWindowsInPageErrorType, u64),
/// ExceptionCodeWindows::EXCEPTION_STACK_BUFFER_OVERRUN with an accompanying
/// windows FAST_FAIL value.
WindowsStackBufferOverrun(u64),
/// A Windows error with no known mapping.
ownu32),
Unknown(u32, u32),
}
/// Information about the exception that caused the minidump to be generated.
///
/// `MinidumpException` wraps `MINIDUMP_EXCEPTION_STREAM`, which contains information
/// about the exception that caused the minidump to be generated, if the
/// minidump was generated in an exception handler called as a result of an
/// exception. It also provides access to a `MinidumpContext` object, which
/// contains the CPU context for the exception thread at the time the exception
/// occurred.
#[derive(Debug)]
pub struct /// ExceptionCodeWindows
/// The raw exception information from the minidump stream.err:ExceptionCodeWindowsAccessType
pub raw: md::MINIDUMP_EXCEPTION_STREAM,
/// The thread that encountered this exception.
pub thread_id: u32,
/// If present, the CPU context from the time the thread encountered the exception.
/// This should be used in place of the context contained within the thread with id
/// `thread_id`, since it points to the code location where the exception happened,
/// without any exception handling routines that are likely to be on the stack after
/// that point.
context: Option<&'a that caused the minidump to be generated, if /// minidump was generated in an exception handler called as a result of an
/// Saved endianess for lazy parsing.
endian:scroll:Ejava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
}
/// A list of memory regions included in a minidump.
/// This is the underlying generic type for [MinidumpMemoryList] and [MinidumpMemory64List].
#[derive(java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 7
pub struct MinidumpMemoryListBase
/// The memory regions, in the order they were stored in the minidump.
/
::java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
regions_by_addr: RangeMap<[eriveDebug)java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
}
/// A list of memory regions included in a minidump.
pub<' =MinidumpMemoryListBase<a md:>
/// A list of large memory regions included in a minidump (usually a full dump).
pub type /// Map from address range .Use `java.lang.StringIndexOutOfBoundsException: Range [76, 75) out of bounds for length 96
/// Provides a unified interface for MinidumpMemoryList and MinidumpMemory64List
)
pub enum
Memory(MinidumpMemoryList<p <a> a ::java.lang.StringIndexOutOfBoundsException: Range [96, 95) out of bounds for length 97
Memory64 java.lang.StringIndexOutOfBoundsException: Range [28, 26) out of bounds for length 32
}
Default '>{
fn default() default) - Self{
Self::Memory(Default:: ::emory(efault:d)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
}
}
/// Information about an assertion that caused a crash.
#)java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
pub struct /// A typed annotation object.
pub raw: vejava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
}
/// A typed annotation object.
#[derive(Clone, String(,
#[non_exhaustive]
pub enum MinidumpAnnotation {
/// An invalid annotation. Reserved for internal use.
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
/// A `NUL`-terminated C-string. for {
String(tring,
/// Clients may declare their own custom types.
UserDefined(md::MINIDUMP_ANNOTATION),
/// An unsupported annotation from a future crashpad version.
Unsupported(md::MINIDUMP_ANNOTATION,
}
impl PartialEq for MinidumpAnnotation {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Invalid, Self::Invalid) =(Self::Stringa,Self:(b)> java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(Self::String(a), Self::String(/// The raw crashpad module extension information
_ => false,
}
}
/// Additional Crashpad-specific information about a module carried within a minidump file.
#[derive(ebug]
pub struct MinidumpModuleCrashpadInfo {
extension
pub raw: md:: annotation_objects<, ,
/// Index of the corresponding module in the `MinidumpModuleList`.
pubderivejava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
pub list_annotations: Vec<String>,
pub simple_annotations: BTreeMapsimple_annotations:BTreeMapString,>,
pub annotation_objects: pub Vec<>,
}
/// Additional Crashpad-specific information carried within a minidump file.
#[timejava.lang.StringIndexOutOfBoundsException: Range [26, 24) out of bounds for length 55
java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
pub raw: md::MINIDUMP_CRASHPAD_INFO,
simple_annotations BTreeMap< ,
pub module_list: Vec<MinidumpModuleCrashpadInfo>,
}
//======================================================
// Implementations
fn format_time_t(t: u32let ::ry_from(month as u8?
f(t as java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
()
time. as u8,
.unwrap_or_default()
}
fn format_system_time(time: time. u8,
// Note this drops the day_of_week field on the ground -- is that fine?
format_date= |{
use std::convert::TryFrom;
let month = .okok(?
let date = .ssume_utc(java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
datetime date
.with_hms_milli(
/// Produce a slice of `bytes` corresponding to the offset and size in `loc`, or an
time.minute as:&::INIDUMP_LOCATION_DESCRIPTOR
time.econdasu8
time.milliseconds,
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
.ok(?
.assume_utc();
format(&Rfc3339).k(java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
;
format_date().unwrap_or_else(|| "<invalid date>".to_owned())
}
/// Produce a slice of `bytes` corresponding to the offset and size in `loc`, or an
/// `Error` if the data is not fully contained within `bytes`.
fn location_slice<' u bytes.o,.k)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
'[8,
loc: &md::MINIDUMP_LOCATION_DESCRIPTOR,
)- <&a[],Error{
let start = loc.rva as usize;
start
.checked_add(loc. ::ittle= java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 56
.and_then(|end| bytes.get(start
.ok_or(Error:java.lang.StringIndexOutOfBoundsException: Range [60, 40) out of bounds for length 95
}
/// Read a u32 length-prefixed UTF-16 string from `bytes` at `offset`.
offsetm , [u8],:scroll: - S java.lang.StringIndexOutOfBoundsException: Index 98 out of bounds for length 98
yteso,java.lang.StringIndexOutOfBoundsException: Range [50, 48) out of bounds for length 56
let ) -> Optionstr
if !size.is_multiple_of( :=gread_withjava.lang.StringIndexOutOfBoundsException: Range [54, 53) out of bounds for length 61
return None;
}
let encoding = match endian {
scroll::Endian::Little =>java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
E:Big >:,
};
let s = encoding
.) -> Option<&'a str&a str> java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
*ffset = ;
Some(s.into()O(0u8)>s)java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
}
#[inlinel = *java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 33
fn read_string_utf8_unterminated<'a>(
offset: &mut usize,
bytesjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 5
endian: .map(String(:rom)
) java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
let string_from_bytes_nul:&] ><ow<_ > {
let bytesoffset asusize.);
std::str::from_utf8(slice).ok()
}
fn read_string_utf8/// Format `bytes` as a String of hex digits
offset: &mut hex_bytes S>= bytes.iter(|java.lang.StringIndexOutOfBoundsException: Range [61, 60) out of bounds for length 84
/// Attempt to read a CodeView java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
endian :scroll:java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
) -> Option<&'a str> {
let string = read_string_utf8_unterminated
match : .(, ndian(?java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
Ok(0u8) => Some(string),
_ >None
}
}
fn read_cstring_utf8(offset: &mut /java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
let initial_offset = *offset
{
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 6
= {
break;
}
}
std::str::from_utf8&bytes[initial_offset..*offset - 1])
.map(String::from)
.ok()
}
/// Convert `bytes` with trailing NUL characters to a string
fn string_from_bytes_nul
|&|b= )next()mapS:java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
}java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
/// Format `bytes` as a String of hex digits
n java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 41
let hex_bytes: r raw = Some(DebugId::rom_pdb20(raw.signature, raw.age)),
hex_bytes.join("")
}
/// Attempt to read a CodeView record from `data` at `location`
fn read_codeview(
location: &md::MINIDUMP_LOCATION_DESCRIPTOR,
data: &[u8],
endian: scroll:,
)-> Option<odeView>{
let bytes = location_slice(data, location).ok()?;
// The CodeView data can be one of a few different formats. Try to read the None;
// signature first to figure out what format the data is.
let signature: u32
(matchCvSignature::rom_u32(ignature){
// PDB data has two known versions: the current 7.0 and the older 2.0 version.
Some(CvSignature::Pdb70) = // as if the first 16 bytes were a GUID.
Some(CvSignature::db20)=>CodeView:Pdb20(.(, endian()),
// Breakpad's ELF build ID format.
CvSignature:Elf = CodeView::(ytespread_with(0 endian).ok()java.lang.StringIndexOutOfBoundsException: Index 83 out of bounds for length 83
// Other formats aren't handled, but save the raw bytes.
knownbytes))
})
}
fn read_debug_id(codeview_info java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 36
{
CodeView::Pdb70(ref raw)} java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
// For macOS, this should be its code ID with the age (0)
/ appended the of it. makes it identical to debug
// here.
let uuid = Uuid (DebugId:from_uuid)
raw.signature.data1,
raw.signature.data2,
raw.signature.data3,
&raw.signature.data4
);
(!uuid.is_nil()).then(|| DebugId::from_parts(uuid, raw.age))
}
CodeView::Pdb20(ref raw) => Some(DebugId::from_pdb20(raw.signature, raw.age)),
CodeView::Elf(ref raw) => {
// For empty or trivial `build_id`s, we don't want to return a `DebugId`. usizejava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
if raw. let =
return None;
}
// For backwards-compat (Linux minidumps have historically
// as if the first 16 bytes were a GUID.
let guid_size = < actual buf.en
let guid = ifOk( java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 42
// Pad with zeros.
let /// Useful for testing.
.uild_id
)
.cloned()
raw:md: {
java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 36
.collect( .md::::efault()
v. ,
else java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
raw.uild_id.pread_with::md:>0,endian.(java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
};
guid}
.map // Read additional data to construct a `MinidumpModule` from `bytes` using the information
}
_= ,
}
}
/// Checks that the buffer is large enough for the given number of items.
///
/// Essentially ensures that `buf.len() >= offset + (number_of_entries * size_of_entry)`.
/// Returns `(number_of_entries, expected_size)` on success.
fn ensure_count_in_bound(
buf: &[u8],
ntries:usize
size_of_entry: usize,
offset: usize,
Result(size , {
let expected_size = let codeview_info = if raw = java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
sjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
.and_then(|v| let os = system_info(|nfo|info.os).Os:Unknown())
.ok_or(Errorlet =codeview_info
as_ref)
ErrError:java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
(MinidumpModule
actual: buf.len(),
});
}
Ok((number_of_entries, expected_size))
}
impl MinidumpModule {
/// Create a `MinidumpModule` with some basic info.
///
/// Useful for testing.
pub fn new(base: u64, T:>self,f:&utT)- io:esult(>{
MinidumpModule !
raw:
base_of_image: base,
size_of_image: size,
..md::MINIDUMP_MODULE::default()
},
name: signature= :x}
codeview_info: None,
,
os: Os::Unknown(0),
debug_id: None,
}
}
/// Read additional data to construct a `MinidumpModule` from `bytes` using the information.java.lang.StringIndexOutOfBoundsException: Range [36, 25) out of bounds for length 41
/// from the module list in `raw`.
(
raw: md:= :x
bytesmisc_record.={java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
endian:scroll:Endian
system_info: Option< () {\
) -> Result<self.raw.base_of_image,
let.awjava.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 37
let name =
read_string_utf16(&mut offset, bytes, .aw.version_info.java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
let self.raw.version_info.file_version_hi,
Noneselfversion_info,
} else {
Somejava.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 50
};
os=system_info||info.os.:(0);
=
.as_ref()
.and_then(|cv .java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 47
.awmisc_recordjava.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 43
raw,
name,
codeview_info,
misc_info: None,
os,
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
}java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
}
/// Write a human-readable description of this `MinidumpModule` to `f`.
/// This is very verbose, it is the format used by `minidump_dump`.
pubprint<:>(self, f&ut)- io:esult(> {
write! rawjava.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
f,
"MINIDUMP_MODULE
base_of_image ={:#x}
size_of_image = {:#x}
raw.java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 43
time_date_stamp = {:#x} {rawdata4
module_name_rva = {:#x}
raw.signature.data43,
version_info.struct_version = {:#x}
version_info.file_version = {:#signature.ata4[]java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
rawage
version_infojava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
version_info
version_info.={#}
version_info.file_type = {:#x}
version_infolet java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 35
. ={#}{#x}
.data_size {
cv_record.rva = {:#x}
misc_record.data_size = {}
misc_record.rva = {:#x}
code_file) \{\java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
(.ge = {
",
selfjava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
self.raw.aw.cv_of,
raw.,
format_time_t(self.raw.time_date_stamp),
self.raw.java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 28
self.raw.version_info.signature,
raw.java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 49
self.raw.version_info.file_version_hi,
self.raw ,
self.raw.java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
,
raw.java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
self.raw.java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 19
self.aw..,
self.raw.version_info.file_type,
self.raw.version_info.file_subtype,
self.raw.version_info.file_date_hi,
self.raw.version_info.file_date_lo,
self.raw.cv_record.data_size,
self.raw.cv_record.rva,
self.raw.misc_record.data_size,
self.}
self.code_file(),
self.code_identifier() letSome(ef m = java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 49
)?;
// Print CodeView data. {
matchwritelnf (ull)")java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
Some(CodeView::Pdb70,
let pdb_file_name =
string_from_bytes_nul(&raw.pdb_file_name
!f, c).java.lang.StringIndexOutOfBoundsException: Range [61, 53) out of bounds for length 68
(cv_record).self.debug_file.java.lang.StringIndexOutOfBoundsException: Range [40, 39) out of bounds for length 59
(cv_record).age = {}
(cv_record).pdb_file_name?;
",
raw.cv_signaturejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
rawjava.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 43
java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 24
(Rangenew
raw.signature.data4[self.(.(self.) -1
raw.signature.data4[1],
raw.signature.data4[2 {
raw.signature.java.lang.StringIndexOutOfBoundsException: Range [0, 42) out of bounds for length 30
raw.signature.data4[4],
raw.java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 5
signature.6]java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
raw.signaturefn java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 49
raw.age,SomeC:java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 89
/MacOs PDB70java.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 72
)?;
}
Some(CodeView::Pdb20:ew(java.lang.StringIndexOutOfBoundsException: Range [41, 39) out of bounds for length 65
java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 35
java.lang.StringIndexOutOfBoundsException: Range [43, 41) out of bounds for length 100
write!(
f,
" (Some(CodeView:Elf( raw) >
(cv_record).cv_header.offsetjava.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
(cv_record).signature = {:#x} {}
(cv_record).age =
(cv_record).pdb_file_name CodeId:&))
",
raw.cv_signature,
raw.cv_offset,
raw.signature,
format_time_t(raw.signature),/java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
raw.age,
pdb_file_name,
)?;
}
Some(CodeView::Elf // the Microsoft symbol server.
write!(
f,
" (cv_record).cv_signature // that no ,in case the code- extremely
(cv_record).build_id = {}
",
raw.cv_signature,
(r.uild_id)
)?;
}
Some(CodeView::":X{x"java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
writeln!(
f,
/ make it intothat
java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 40
)?;
}
None => {
writeln!(f }
}
}
// Print misc record data.
if let Some(ref _ Some(CodeView::Pd)=sjava.lang.StringIndexOutOfBoundsException: Range [69, 67) out of bounds for length 88
//TODO, not terribly important.
writeln! mjava.lang.StringIndexOutOfBoundsException: Range [59, 39) out of bounds for length 80
} else {
writeln!(f, " (misc_record) = (null)")?_ =None,
}
write!(
f,
r#"
( fn version( &elf) > <' str> java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
(version) = "{}"
"#
self.debug_file().unwrap_or {
self.debug_identifier().unwrap_or_default(),
if matchess.s, s:|Os:Ios Os::Windows) {
)?;
let java.lang.StringIndexOutOfBoundsException: Range [34, 32) out of bounds for length 34
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
fn memory_range(&self) -> Option<Range<u64>> {
if size) =0{
return None;
}
java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 24
self. Some(Cow(
self.base_address().checked_add(selflet format(
"}{.}.},
}
}
impl Module for MinidumpModule {
fn base_address(&self) -> u64 {
self.raw.base_of_image
}
fn java.lang.StringIndexOutOfBoundsException: Range [16, 9) out of bounds for length 18
self.raw.size_of_image as u64
}
None
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 9
}
fn &elf)- CodeId {
match self.codeview_info {
Some(CodeView ///
// MacOs uses PDB70 instead of its own dedicated format.
// See the following issue for a potential MacOs-specific format:
// https://github.com/rust-minidump/rust-minidump/issues/455{
SomeCodeId::(formatformat!":#}",raw))
}
SomeCodeView:Pdb20() |SomeCodeView:Pdb70() = C:(java.lang.StringIndexOutOfBoundsException: Range [91, 90) out of bounds for length 92
"{0:08X}{1:x}",
self.raw.time_date_stamp, selfname::f(name,
))),
Some}
// Return None instead of sentinel CodeIds for empty
// `build_id`s. Non-executable mapped files like fonts or .jar
// files will usually fall under this case.
if raw.java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 16
None
} else {
Some(CodeId::)- <inidumpUnloadedModule >{
}
}
None if self.os == Os::Windows => {
// Fall back to the timestamp + size-based debug-id for Windows.
// Some Module records from Windows have no codeview record, but
// the CodeId generated here is valid and can be looked up on
// the Microsoft symbol server.
// One example might be `wow64cpu.dll` with code-id `378BC3CDa000`.
// This can however lead to "false positive" code-ids for modules
// that have no timestamp, in which case the code-id looks extremely
// low-entropy. The same can happen though if they *do* have a
// codeview record.
Some(CodeId::new(format! :xjava.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
"{0:08X}{1:x}",
self.raw.time_date_stamp, self.raw.size_of_image
)))
}
// Occasionally things will make it into the module stream that
// shouldn't be there, and so no meaningful CodeId can be found from
// those. One of those things are SysV shared memory segments which
no CodeViewrecord
_ => self.raw.java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 30
}
}
fn debug_file(&self) -> Option<Cow<'_, str>> {..module_name_rva,
matchself. {
Some(CodeView: .)unwrap_or_default,
Some(CodeView::Pdb20(ref raw))java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
Some(CodeView::Elf(fn(self)- R<64>
//: record?not really java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
_ => None,
}
(Range:ew
fn java.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 32
self.
}
fn version(&self)}
if self.raw.version_info.signature
.struct_version =md:
{
Os:M|Os: :Wjava.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 69
=java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
.}.}},
self.raw.version_info.file_version_hi >> 16,
self.raw.version_info.file_version_hi & 0xffff.rawsize_of_imageas
..file_version_lo >16,
self.raw.version_info.java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 33
);
code_identifier(&self) -> Option<CodeId> {
} else{
// Assume Elf
let ver = format!(
"{}.{}.{}.{}",
self.raw.version_info.file_version_hi,
self.raw.version_info.file_version_lo"008}1x"java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
self.raw.version_info.product_version_hi,
self.rawversion_info.product_version_lo
);
Some(Cow::java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 5
}
} else {
None
}
}
}
impl MinidumpUnloadedModule {
/// Create a `MinidumpUnloadedModule` with some basic info.
///
/// Useful for testing.
pub fn new(base linux_list_iter
MinidumpUnloadedModule {
raw: md::MINIDUMP_UNLOADED_MODULE {
se_of_imagebasejava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
size_of_image: size,
..md:M::default(
},
name: String::from(name),
input =input.trim_ascii_whitespace)
}
/// Read additional data to construct a `MinidumpUnloadedModule` from `bytes` using the information
/// from the module list in `raw`.
pub fn read(let =
raw :MINIDUMP_UNLOADED_MODULE
bytes: &[u8],
endian: scroll::Endian,
) -> Result<MinidumpUnloadedModule, Error> {
let mut offset = raw.module_name_rva
let name = read_string_utf16(
Ok(MinidumpUnloadedModule { input.).m | java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
}
/// Write a human-readable description of this `MinidumpModule` to `f`.
///
/// This is very verbose, it is the format used by `minidump_dump`.
pub fn print<T: Write>(&selfoffset: musizejava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
write!:scroll::java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 27
f,
"MINIDUMP_UNLOADED_MODULE
base_of_image {x}
size_of_image = {:#x}
checksum :SizeWith<croll:Endianjava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
time_date_stamplet bytes
gread_with( endianjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
= \"{\java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
(code_identifier) = \"{}\"
"let count )=ensure_count_in_bound(
self.raw.base_of_image,
self.raw.size_of_image,
self.raw.checksum,
self.raw.time_date_stamp,
s.time_date_stamp)java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
self.raw.module_name_rva,
self.code_file(),
self.match bytes.len() -java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 38
?java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
Ok(())
}
fn memory_range(&self) -> Option<Range<u64>> {_=
if self.size() == 0 {
return None;
}
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 9
self.()
self.base_address().checked_add(self.size())? - 1,
java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 10
}
}
Modulefor {
fn base_address(&self) -> u64 {
self.raw.base_of_image
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}
self.raw.size_of_image java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 19
}
fn code_file(&self) -> fnread_ex_stream_list',T(
Cow::Borrowed(&self.name)
}
fn code_identifier(&self) -> Option:&a[8,
// TODO: This should be returning None if the unloaded module is coming
// from a non-Windows minidump. We'll need info about the operating
// system, ideally sourced from the SystemInfo to be able to do this.
Some(CodeId::new(format!(
"0X{1:"java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
..ime_date_stamp,selfraw.ize_of_image
)))
}
fn debug_file(&self) -> Option<Cow<'_, str>> {
None
}
fn debug_identifier(&self) -> Option<DebugId> {
None
}
fn version(&self) -> Option<Cow<'_, str>> {
None
}
}
/// Parses X:Y or X=Y lists, skipping any blank/unparseable lines
fn (
bytes: &[u8],
separator: u8,
- impl <=(LinuxOsStr, L){
fn strip_quotes(input: &LinuxOsStr) -> gread_with(ffset, )
/ Remove any extra surrounding whitespace since formats are inconsistent on this.
let input = input.trim_ascii_whitespace();
o MyValue` or return the trimmed
let output = input
strip_prefixb"")
.and_then(|input| input.strip_suffix(b"\""))
.(;
LinuxOsStr::from_bytes(output)
}
let input = LinuxOsStr: .( endian
input.lines().filter_map(move |line| {
line.split_once(separator)
.maplet =<>:ize_with(e)
})
}
fn read_stream_list<'a, T>(
offset: m java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 23
bytes // always extended with new trailing fields, and this information
endian: scroll::Endian,
) -> Result<Vec :Sjava.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 45
wherelet(umber_of_entries ensure_count_in_bound
T: TryFromCtx<'a, scroll::java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
T: SizeWith<scroll::Endian>,
{
let u: u32 = bytes
.gread_with(offset, endian)
.or(Err(Error::StreamReadFailure)
let (};
,
u as usize,
<T>::size_with(&endian),
mem::size_of::<u32>(),
)?;
raw: T = bytes
0 => {}
4 => {
// 4 bytes of padding.
*= 4;
}
_ => {
return Err(Errorjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
expected: counted_size,
:bytes.()
});
}
};
// read count T raw stream entries
let mut raw_entries = java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 24
for _ in 0..count {
let raw: T = bytes
.gread_with(offset, endian)
.rE(Error);
raw_entries.push(raw);
}
Ok(raw_entries m: =
}
fn read_ex_stream_list<'// read out the actual names
&utusize,
bytes: &'a [u8],
endian: scroll::Endian,
-ResultVec<,java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
where
Some=& java.lang.StringIndexOutOfBoundsException: Range [67, 61) out of bounds for length 77
T: SizeWithelse{
{
// Some newer list streams have an extended header: java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 65
//
// size_of_header: u32,
// size_of_entry: u32,
// number_of_entries: u32,
..
.get(&thread_id)
ew java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 46
let size_of_header: u32 = bytes
o, )
.or(Err(Error::java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 15
let size_of_entry: u32 = bytes thread_count = {java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
.selfnames.(java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
.or(Err(Error::for (i, (thread_id, name) self..ter)enumerate java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
let number_of_entries: u32}]
.gread_with(offset, endian)
.or(Err(Error::StreamReadFailure))?;
let expected_size_of_entry = <T>:java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
if size_of_entry as usizejava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
// For now, conservatively bail out if entries don't have
// the expected size. In theory we can assume entries are
// always extended with new trailing fields, and this information[]
// would let us walk over trailing fields we don't know about?
// But without an example let's be safe.
return Err(Error/
}
let ( modules_by_addr
bytes,
number_of_entries as usize,
size_of_entry as usize,
size_of_header as usizejava.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 28
)? }
let header_padding = match (size_of_header as usize /// Returns the module corresponding to the main executable.
Some(s) => s,
None => // The main comodule is java.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 77
;
*offset += header_padding;
// read count T raw stream entries
let mut raw_entries = Vec:
for _ in 0.}
let raw:
.gread_with(offset, endian)
.or(Err(Error::StreamReadFailure))?;
raw_entries.push(raw);
}
Ok .ajava.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 25
}
impl<'a> MinidumpStream<'a> for MinidumpThreadNames {
const STREAM_TYPE: u32 = MINIDUMP_STREAM_TYPE::ThreadNamesStream as u32;
fn read(
bytes: &'a [u8],
all: &'a [u8],
endian: scroll::Endian,
_system_info: Option<&MinidumpSystemInfo>,
) -> Result<Self, Error> {
let mut offset = 0;
let raw_names: ranges_valuesjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
read_stream_list(&mut offset, bytes, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// read out the actual names
let mut names = BTreeMap::new();
for raw_name in raw_names {
let mut offset = raw_name.java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 14
// Better to just drop unreadable names individually than the whole stream.
if self.m..(
names) in .(.){
} else {
warn!(
"Couldn't read thread java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 14
);
}
}
Ok(MinidumpThreadNames { names })
}
}
impl MinidumpThreadNames {
pubfn &,:u32 >Option<ow',str> {
self.names
get&)
.map(|name| Cow::Borrowed(&**name)java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
/// Write a human-readable description of this `MinidumpThreadNames` to `f`.
pub fnT:Write( f:&ut T) :esult<){
write!(
"MinidumpThreadNames
thread_count = {}
",
self.names.len( // read auxiliary data for each module
)?;
) self.iter()) java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
writeln!(
f,
" tracing(
module_index
= {thread_id:#x}
name = \"{name}\"
"
)?;
}
Ok(())
}
}
impl MinidumpModuleListjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
/// Return an empty `MinidumpModuleList`.
fn new() -> MinidumpModuleList {
MinidumpModuleList {
modules_by_addr: RangeMap:MinidumpUnloadedModuleList
}
}
/// Create a `MinidumpModuleList` from a list of `MinidumpModule`s.
java.lang.StringIndexOutOfBoundsException: Range [12, 6) out of bounds for length 28
let modules_by_addr = modules
.iter()
.(java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
.map(|(i, module)| (module.memory_range(), i))
.collect::<Vec<_(;
MinidumpModuleList {
modules,
MinidumpUnloadedMod
}
}
/// Returns the module corresponding to the main executable.
pub fn main_module(&self) -> Option<&java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 30
// The main code module is the first one present in a minidump file's
// We have all of our modules sorted by memory range (base address being the
if !self.modules.is_empty() {
Some(&self.modules[0])
} else {
None
}
}
/// Return a `MinidumpModule` whose address range covers `address`./java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
pub fn filter (|range.java.lang.StringIndexOutOfBoundsException: Range [56, 55) out of bounds for length 65
self.modules_by_addr
.get(address
.map(|&index| &self.modules[indexpub iter& > Item=&>{
}
/// Iterate over the modules in arbitrary order.
pub fn iter(&self) - }
}
pub fn by_addr(&self) -> impl DoubleEndedIterator<java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 28
self.modules_by_addr
.ranges_values()
.map(move |&(_, index)| &self.}
}
/// Write a human-readable description of this `MinidumpModuleList` to `f`.
///
/// This is very verbose, it is the format used by `minidump_dump`.
pub fn print<T: Write>(&self, f:/
write!(
f,
"MinidumpModuleList
module_count = {}
",
self.modules.len()
)?;
for (, )in ..).( java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
writeln!(f, "module[{i}]")?;
module.print(f)?;
}
Ok()java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
}
}
impl Default for MinidumpModuleList {
fn default() -Ok())
Self::new()
}
}
pStream<a MinidumpModuleList {
const STREAM_TYPE: u32 = MINIDUMP_STREAM_TYPE default(- {
fn read(
bytes: &'a [u8],
all: &'a [u8],
endian: scroll::Endian,
system_info const STREAM_TYPE:u32 :U asu32;
) -> Result<MinidumpModuleList, Error> {
let mut
fn java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
// read auxiliary data for each module
let mut modules = Vec::with_capacity(raw_modules.lenendian: scroll::Endian,
for (module_index, raw) in raw_modules._ystem_info: Option&>
if.size_of_image= 0| . u64 > u64::MAX -rawbase_of_image){
// Bad image size.
tracing::!
module_index,
base = raw.base_of_image,letraw_modules: Vec<md::MINIDUMP_UNLOADED_MODULE> =
size = raw.size_of_image,
b module size
);
continue;
}
modules.push(MinidumpModule::read(raw, all, endian, system_info)?);
}
Ok(MinidumpModuleList::from_modules(modules))
}
}
impl MinidumpUnloadedModuleList {
/// Return an empty `MinidumpModuleList`.
return Err(:);
MinidumpUnloadedModuleList {
modules: vec![],
modules_by_addr: vec![],
}
}
/// Create a `MinidumpModuleList` from a list of `MinidumpModule`s.
pub fn from_modules(modules: Vec<MinidumpUnloadedModule }
let mut modules_by_addr = (0..modules
.filter_map(|i| modules[i].memory_range().map(
.collect::<Vec<_>>();
modules_by_addr.sort_by_key(|(range, _idx)| *range);
MinidumpUnloadedModuleList {
modules,
modules_by_addr,
}
}
aniterator of M whoseaddress range ``
pub fn modules_at_address(
&java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
address: 64,
) -> impl Iterator<Item = &java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 24
// We have all of our modules sorted by memory range (base address being the
/high-order value need getthe valuesthat
// with our target address. I'm a bit too tired to work out the exact
// combination of binary searches to do this, so let's just use `filter`
// for now (unloaded_modules should be a bounded list anyway).
ddr
.iter()
filter( |range,_dx|range.(ddress)
.map(move |(_range, idx)| &self.modules[*idx])
}
/// Iterate over the modules in arbitrary order.
() - <tem=&inidumpUnloadedModule java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
modules.(
}
/// Iterate over the modules in order by memory address.
pub fn by_addr(& }java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
self.modules_by_addr
.iter()
.map(move !
}
/// Write a human-readable description of this `MinidumpModuleList` to `f`.
///
/// This is very verbose, it is the format used by `minidump_dump`.
nprint<: >(self, f: m T >io:Result<) {
write!(
f,
"MinidumpUnloadedModuleList
module_count = {}
",
self.modules.len()
)?;
( module)in .odules.(.( java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
writeln!(f, "module[{i}]")?;
module.java.lang.StringIndexOutOfBoundsException: Range [0, 24) out of bounds for length 0
}
Ok(())
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}
Default MinidumpUnloadedModuleList {
fn default() -> Self {
Self::new()
}
}
impl<'a> MinidumpStream<'a> for MinidumpUnloadedModuleList {
!,$ormat,$ield);
fn read(
bytes: &' }
],
endian: scroll::Endian,
_system_info: Option<&MinidumpSystemInfo>,
st, Error>{
let mut offset = 0;
let raw_modules: Vec<md::MINIDUMP_UNLOADED_MODULE> =
read_ex_stream_list(&mut offset, bytes, endian)?
// read auxiliary data for each module
mutmodules =:wr.);
for raw in raw_modules.into_iter() {
if raw.size_of_image == 0 || raw.size_of_image as u64 > (write_simple_field!f type_name_rva, "{:";
// Bad image size.
// TODO: just drop this module, keep the rest?
return Err(:ModuleReadFailure;
}
modules.push(MinidumpUnloadedModule::read(raw, all, endian)?);
}
Ok(MinidumpUnloadedModuleList::from_moduleswrite_simple_field( ;
}
}
// Generates an accessor for a HANDLE_DESCRIPTOR field with the following syntax:
//
// * VERSION_NUMBER: FIELD_NAME -> FIELD_TYPE
//
// With the following definitions:
//
// * VERSION_NUMBER: The HANDLE_DESCRIPTOR version this field was introduced in
// * FIELD_NAME: The name of the field to read
// * FIELD_TYPE: The type of the field
macro_rules! handle_descriptor_accessors {
() => {};
(@def $name:ident $t:ty [$($variant:ident ;
#[llowunreachable_patterns)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
pub fn $name(&self) -> Option<&$t> {
match self {
(
RawHandleDescriptor!,"n"?java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
)+
_ => None,
}
}
};
(1: $name:ident -> $t:ty, $($rest:ttforobject_infoin s.java.lang.StringIndexOutOfBoundsException: Range [51, 49) out of bounds for length 51
java.lang.StringIndexOutOfBoundsException: Range [51, 35) out of bounds for length 89
handle_descriptor_accessors!($($rest)*);
};
(2: $name:ident -> $java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 5
handle_descriptor_accessors!@def $$ [];
handle_descriptor_accessors!($($rest)*);
};
}
impl RawHandleDescriptor {
handle_descriptor_accessors!java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
1: }else {
1: type_name_rva -> md::RVA,
1: object_name_rva -> md::RVA,
1: attributes -> u32,
1: granted_access -> u32,
1: handle_count -> u32,
1tctx:HandleDescriptorContext
:object_info_rva -> md::RVA,
);
}
impl MinidumpHandleDescriptor {
/// Write a human-readable description.
pub fn print<T: Write>(&
macro_rules! write_simple_field {
, $format:iteral) = java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
write!(f, " {:18}= ", java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 29
selfraw.field( {
Some($field) => {
writeln!(f, $format, $ : raw.(
}
None => writeln!(f, "(invalid)")?,
}
};
($stream:ident, $ }java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
write_simple_field!($stream, $field, "{}");
};
}
writeln!(f, "MINIDUMP_HANDLE_DESCRIPTOR")?;
HandleDescriptorContext'>{
write_simple_field!(f, type_name_rva, "{:#x}");
write_simple_field!(f, object_name_rva, "{:#x}");
write_simple_field!(f, attributes, "{:#x}");
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
write_simple_field!(f, handle_count);
write_simple_field!(f, pointer_count);
write_simple_field!(f, object_info_rva, "{:#x}");
write!(f, " ( endianess: scroll::Endi::ndian,
if let Some(type_name) = &self.type_name {
writeln!(f, "{type_name:}")?;
} else {
writeln!(f, "(null)")?;
};
write!(f, " (object_name) = ")?;
if
writeln!(f, "{object_name:}")?;
} else {
writeln!(f,
}java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
if self.object_infos.is_empty() {
writeln!(f, " (object_info) = (null)")?;
} else {
for object_info in &self.object_infos {
writeln!(f, )- Result<,usize) Self:Error java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
}
}
()
}
fn read_string(offset: usize, const MINIDUMP_HANDLE_DESCRIPTOR_2_SIZEu32 java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
letmut = ;
if offset != 0 {
read_string_utf16(&mut offset, ctx.bytes,
} else {
None
}
}
fn read_object_info(
offset: usize raw=src.:<d:>(,ctx.endianess);
ctx: HandleDescriptorContext type_name :read_string(aw. as ,ctx;
) -> Option<MinidumpHandleObjectInformation> {
if offset == 0 {
return None;
}
bytes
.pread_with::<md::MINIDUMP_HANDLE_OBJECT_INFORMATION>( raw: RawHandleDescriptor::HandleDescriptor(raw::andleDescriptorraw)
ok(java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
.and_then(|raw| {
Some(MinidumpHandleObjectInformation {
raw: raw.clone(),
: md::INIDUMP_HANDLE_OBJECT_INFORMATION_TYPE:f(
raw.info_type,
)?,
})
})
}
}
#[derive(Copy, Clone)]
struct HandleDescriptorContext<'a> {
bytes:' u8,
fieldsize: u32,
java.lang.StringIndexOutOfBoundsException: Range [22, 13) out of bounds for length 30
}
impl<'a> HandleDescriptorContext<'a> {
fn new(
bytes: &'a [u8],
fieldsize: u32,
endianess:scroll:Endian,
) -> HandleDescriptorContext<'a> {
HandleDescriptorContext {
bytes,
fieldsize,
endianess,
}
}
}
impl<'a> TryFromCtx<'a, HandleDescriptorContext<'a>> for MinidumpHandleDescriptorobject_infospush();
type Error = scroll::Error;
fn try_from_ctx(
src: &'a [u8],
ctx: HandleDescriptorContext,
) -> Result<(Self, usize), Self::Error> {
const MINIDUMP_HANDLE_DESCRIPTOR_SIZEraw :HandleDescriptor2raw)java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
mem::size_of::<md::MINIDUMP_HANDLE_DESCRIPTOR>() as u32;
const object_name
mem::size_of::<md::MINIDUMP_HANDLE_DESCRIPTOR_2>() as u32;
match ctx.fieldsize {
},
let raw = src.pread_with::<md::MINIDUMP_HANDLE_DESCRIPTOR>(0, ctx.endianess)?;
let type_name = Self::read_string(raw.type_name_rva as java.lang.StringIndexOutOfBoundsException: Range [0, 76) out of bounds for length 18
let object_name = Self::read_string(raw.object_name_rva as usize :ctx.as usize,
Ok((
MinidumpHandleDescriptor {
raw: RawHandleDescriptor::HandleDescriptor(raw),
java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 9
object_name,
object_infos: Vec(
},
. ,
))
}
MINIDUMP_HANDLE_DESCRIPTOR_2_SIZE => {
let raw = src.pread_with::<md::MINIDUMP_HANDLE_DESCRIPTOR_2>(0, ctx.endianess)?;
let type_name = Self::read_string(raw.type_name_rva as usize, ctx);
java.lang.StringIndexOutOfBoundsException: Range [0, 19) out of bounds for length 5
let mut object_infos = Vec::<MinidumpHandleObjectInformation>::new();
let mut object_info_rva = raw.object_info_rva;
while object_info_rva != 0 {
if let
object_info_rva = java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 15
object_infos.push(object_info);
} else {
break;
}
}
Ok((
{
raw: RawHandleDescriptor::HandleDescriptor2(raw),
type_name,
object_name,
object_infos,
},
ctx.fieldsize as usize,
))
}
_= (scroll:rror:BadInput {
size: ctx.fieldsize as usize Self:n)
msg: "Unknown MINIDUMP_HANDLE_DESCRIPTOR type",
}),
}
}
}
impl MinidumpHandleDataStream {
// Return an empty `MinidumpHandleDataStream`.
pub fn new() -> MinidumpHandleDataStream {
MinidumpHandleDataStream { handles: vec![] }
}
/// Create a `MinidumpHandleDataStream` from a list of `MinidumpHandleDescriptor`s.
(:Vec<)->MinidumpHandleDataStream java.lang.StringIndexOutOfBoundsException: Index 93 out of bounds for length 93
MinidumpHandleDataStream { handles }
}
/
pub fn iter(&self) -> impl Iterator<Item = &MinidumpHandleDescriptor.:<u32>(&mut , endian)
self.handles.iter()
}
/// Write a human-readable description.
pub fn print<T: Write> .(ErrError::))
write!java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
f,
or(rror:);
handle_count = {}
",
self..)
)?;
for (i, handle) in self.handlesbytes,
writeln!(f, "handle[{i}]")?;
handle.print(f)?;
}
Ok(())
}
}
impl Default for MinidumpHandleDataStream {
fn default() ->
:new(java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
}
}
impl<'a> MinidumpStream<'a> for MinidumpHandleDataStream {
const STREAM_TYPE: u32 = MINIDUMP_STREAM_TYPE::HandleDataStream as u32;
fnread(
bytes: &'a [u8],
all: &'a [u8],
endian: scroll::Endian,
java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
) -> Result<MinidumpHandleDataStream, Error
let mut offset = 0;
let size_of_header = bytes
.gread_with::<u32>(&mut offset, endian)
.or(Err(Error::StreamReadFailure))?;
let size_of_descriptor = bytes
gread_with:<32(&utoffset, )
.or(Err(Error if desc.rva =0 |descmemory. =0{
let number_of_descriptors = bytes
.gread_with::<u32>(&mut offset,
.or(Err(Error::StreamReadFailure))?;
let =HandleDescriptorContext:( size_of_descriptor,endian;
let (number_of_entries, _) = ensure_count_in_bound(
}
number_of_descriptors as usize,
size_of_descriptor as usize,
size_of_header as usize,
)?;
// Skip the header
offset = size_of_header as usize;
let mut descriptors = Vec::<MinidumpHandleDescriptor>::with_capacity,
for _ in 0..number_of_entries {
let descriptor: MinidumpHandleDescriptor = bytes
.gread_with(&mut offset, ctx)
.or(Err(Error::StreamReadFailure/
descriptors.pushdescriptor)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
}
Ok(start_of_memory_range:x
}
}
impl<'a> MinidumpMemory<'a> {
pub fn read(
desc: &md::MINIDUMP_MEMORY_DESCRIPTOR,
data: &'a [u8],
endian: scroll::Endian,
) -> Result<MinidumpMemory<'a>, Error> {
if desc.memory.rva == 0 || desc.memory.data_size == print_contentsf)?;
// Windows will sometimes emit null stack RVAs, indicating that
// we need to lookup the address in a memory region. It's ok to
// emit an error for that here, the thread processing code will
// catch it.
return Err(Error::MemoryReadFailure);
}
let bytes = location_slice(data, /
Ok( fnprint<T >(s,f:& T,brief:bool)- io:<> {
desc: *esc,
base_address: desc.start_of_memory_range,
size: desc.java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
bytes,
endian,
})
}
/// Write a human-readable description of this `MinidumpMemory` to `f`.
///
// This is very verbose, it is the format used by `minidump_dump`.
pub fn print<T: Write>(&self, f: &mut T, brief: bool) java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
write!(
f,
"MINIDUMP_MEMORY_DESCRIPTOR
start_of_memory_range =:x}
memory.data_size = {:#x}
memory.rva = {:#x}
",
self.desc.start_of_memory_range, self.desc.memory.data_size, self
);
if !brief {
writeln!(f, "Memory")?;
self.f)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
}
writeln!(f)
}
}
impl MinidumpMemory64<'_> {
/// Write a human-readable description of this `MinidumpMemory64` to `f`.
///
/// This is very verbose, it is the format used by `minidump_dump`.
pub fn pub < >s,f m TT)-io:Result<( {
write!(
f,
"MINIDUMP_MEMORY_DESCRIPTOR64
start_of_memory_range ={:}
memory.data_size = for paragraph self.chunks(ARAGRAPH_SIZE java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
,
self.desc.start_of_memory_range, self.desc.data_size,
)?;
if !brief {
writeln!f,"emory"?;
self.print_contents(f)write!f "byte02} "?
}
writeln!(f)
}
}
impl<'a, Descriptor> MinidumpMemoryBase<'a, Descriptor> {
/// Get `mem::size_of::<T>()` bytes of memory at `addr` from this region.
///
/// Return `None` if the requested address range falls out of the bounds
/// of this memory region.
pub fn get_memory_at_address<T>(&self, addr: u64) -> Option<T>
where
T: TryFromCtx<'a, scroll::Endian, [u8], Error = scroll::Error>,
{
let start = addr.checked_sub(self.base_address)? as usize;
self.bytes !();
}
/// Write the contents of this `MinidumpMemory` to `f` as a hex string.
pub fn print_contents<T: Write>(&self, f: &mut T) -> io::Result<()> {
const PARAGRAPH_SIZE: usize = Ok())
let mut offset = 0;
for paragraph in self.bytes.chunks(PARAGRAPH_SIZE) {
write!f," offset:x:")
let mut byte_iter = paragraph.iter().fuse();
for _ in return ;
if let Some(java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 9
!f {:x );
} else {
(,""?java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
}
}
for &byte in paragraph.iter() {
let ascii_char = if !byte.is_ascii()
'.'
} else {
char::from(byte)
ritef "{})?;
}
writeln!(f)?;
offset + java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 37
}
Ok(())
}
pubfn&elf ->R<u64>{
matchjava.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 20
return None;
}
Some(Rangejava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 5
self.base_address,
self.base_address.checked_add(self.size)? - 1 Memory= bytes
))
}
}
java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 42
pub fn
where
T: TryFromCtx<'mdmp, scroll::Endian, [u8]match{
{
match self {
UnifiedMemory: java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
UnifiedMemory::Memory64(this) = print_contentsT & f mut)-io:esult(> java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
}
}
pub fn memory_range(&self) -> Option}
match self {
:M(this =tmemory_range(),
UnifiedMemory::Memory64(this) => java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 20
}
}
pub fn bytes(&self) -> &'a [u8] {
match self {
UnifiedMemory::Memory(this) => this.bytes,
UnifiedMemory::Memory64(this) java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 0
}
}
pub )>java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 63
self {
UnifiedMemory::Memory(this) => this.base_address,
}
}
}
pub fn size(&self) -> u64 {
match self {
UnifiedMemory::Memory(this) => this.size,
UnifiedMemory::Memory64(this) => this.size,
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
}
pub fn print_contentsrjava.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 20
match self {
UnifiedMemory::Memory(this) => this.print_contents/java.lang.StringIndexOutOfBoundsException: Index 84 out of bounds for length 84
UnifiedMemory::Memory64(java.lang.StringIndexOutOfBoundsException: Range [0, 40) out of bounds for length 14
}
}
pub fn print<T: Write>(&self|i|selfjava.lang.StringIndexOutOfBoundsException: Range [55, 53) out of bounds for length 55
java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 20
UnifiedMemory/
UnifiedMemory::/// That is the lifetime of theof the iterator
}
}
}
impl<'mdmp, Descriptor> MinidumpMemoryListBase<'mdmp, Descriptor&s java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
/// Return an empty `MinidumpMemoryListBase`.
pub fn new(}
MinidumpMemoryListBase // Iterate over the memory regions in order by memory address.
regions: vec![java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 19
regions_by_addr: RangeMap::new(),
.)
}
/// Create a `MinidumpMemoryListBase` from a list of `MinidumpMemoryBase`s.
pub fn from_regions(
Vec<<, java.lang.StringIndexOutOfBoundsException: Range [59, 57) out of bounds for length 60
) -> MinidumpMemoryListBase<'mdmp, Descriptor> {
.iter()
.enumerate()
.map(|(i, region)| (region.memory_range(), i))
.into_rangemap_safe();
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
regions,
regions_by_addr,
}
}
// Return a `MinidumpMemoryBase` containing memory at `address`, if one exists.
pub fn memory_at_address(
java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 36
address: u64,
) -> Option<&MinidumpMemoryBase<java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
self.regions_by_addr
.get(address)
.and_then(|&index| self.regions.get(index))
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
/// Iterate over the memory regions in the order contained in the minidump.
///
/// The iterator returns items of [MinidumpMemoryBase] as `&'slf MinidumpMemoryBase<'mdmp, Descriptor>`.
/// That is the lifetime of the item is bound to the lifetime of the iterator itself
/// (`'slf`), while the slice inside [MinidumpMemoryBase] pointing at the memory itself has
/// the lifetime of the [Minidump] struct ('mdmp).
pub fn iter<'slf>(
&'slf self,
) -> impl Iterator<Item = :Mthis={
self.regions.iter()
}
/// Iterate over the memory regions in order by memory address.
pub fn by_addr}
&'slf self,
pubiter<slf>'lf )-impl <Item java.lang.StringIndexOutOfBoundsException: Range [73, 71) out of bounds for length 87
self.regions_by_addr
.ranges_values()
.map(move |&(_, index)| &self.regions[index])
}
}
impl java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 16
/// Write a human-readable description of this `MinidumpMemoryList` to `f`.
///
/// This is very verbose, it is the format used by `minidump_dump`.
pub fn print<T: Write>(&self, f: java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
f,
"MinidumpMemoryList
}
",
self.regions.len()
)?;
for (i, region) in self.regionsflatten(java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
writeln!(f, "region
region.(f brief?java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
}
Ok(())
}
}
impl}
/// Write a human-readable description of this `MinidumpMemory64List` to `f`.
///
/// This is very verbose, it is the format used by `minidump_dump`.
pub
write!(
<a <a>fora{
"MinidumpMemory64List
region_count
",
self.regions.len()
)?;
for (i, region) in self.regions)- Result<java.lang.StringIndexOutOfBoundsException: Range [38, 34) out of bounds for length 48
writeln!(f, "region[{i}]")?;
region.print(f, brief)?;
}
java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 37
}
impl<'mdmp> UnifiedMemoryList
pub Ok(fjava.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 53 | | |