use super::*;
impl MinidumpWriter {
pub(crate) fn write_memory_list(
&mut self,
buffer: &mut DumpBuf,
dumper: &TaskDumper,
) -> Result<MDRawDirectory, WriterError> {
if let Some(cc) = &self.crash_context
&& cc.exception.is_some()
{
const IP_MEM_SIZE: u64 = 256;
let get_ip_block = |tid| -> Option<std::ops::Range<u64>> {
let thread_state = dumper.read_thread_state(tid).ok()?;
let ip = thread_state.pc();
let region = dumper.get_vm_region(ip).ok()?;
if ip < region.range.start || ip > region.range.end {
return None;
}
let start = std::cmp::max(region.range.start, ip - IP_MEM_SIZE / 2);
let end = std::cmp::min(ip + IP_MEM_SIZE / 2, region.range.end);
Some(start..end)
};
if let Some(ip_range) = get_ip_block(cc.thread) {
let size = ip_range.end - ip_range.start;
let stack_buffer = dumper.read_task_memory(ip_range.start as _, size as usize)?;
let ip_location = MDLocationDescriptor {
data_size: size as u32,
rva: buffer.position() as u32,
};
buffer.write_all(&stack_buffer);
self.memory_blocks.push(MDMemoryDescriptor {
start_of_memory_range: ip_range.start,
memory: ip_location,
});
}
}
let list_header =
MemoryWriter::<u32>::alloc_with_val(buffer, self.memory_blocks.len() as u32)?;
let mut dirent = MDRawDirectory {
stream_type: MDStreamType::MemoryListStream as u32,
location: list_header.location(),
};
let block_list =
MemoryArrayWriter::<MDMemoryDescriptor>::alloc_from_array(buffer, &self.memory_blocks)?;
dirent.location.data_size += block_list.location().data_size;
Ok(dirent)
}
}