diff --git a/src/agent/debugger/src/breakpoint.rs b/src/agent/debugger/src/breakpoint.rs index 7f1eae25df..239e2bb61a 100644 --- a/src/agent/debugger/src/breakpoint.rs +++ b/src/agent/debugger/src/breakpoint.rs @@ -103,6 +103,11 @@ impl ResolvedBreakpoint { self.kind } + pub fn update(&mut self, id: BreakpointId, kind: BreakpointType) { + self.id = id; + self.kind = kind; + } + #[allow(unused)] pub fn is_enabled(&self) -> bool { !self.is_disabled() @@ -119,10 +124,8 @@ impl ResolvedBreakpoint { pub(crate) fn disable(&mut self, process_handle: HANDLE) -> Result<()> { self.disabled = self.disabled.saturating_add(1); - if self.is_disabled() { - if let Some(original_byte) = self.original_byte.take() { - write_instruction_byte(process_handle, self.address, original_byte)?; - } + if let Some(original_byte) = self.original_byte.take() { + write_instruction_byte(process_handle, self.address, original_byte)?; } Ok(()) @@ -131,9 +134,10 @@ impl ResolvedBreakpoint { pub fn enable(&mut self, process_handle: HANDLE) -> Result<()> { self.disabled = self.disabled.saturating_sub(1); - let new_original_byte = process::read_memory(process_handle, self.address as _)?; - self.original_byte = Some(new_original_byte); - write_instruction_byte(process_handle, self.address, 0xcc)?; + if self.original_byte.is_none() { + self.original_byte = Some(process::read_memory(process_handle, self.address as _)?); + write_instruction_byte(process_handle, self.address, 0xcc)?; + } Ok(()) } diff --git a/src/agent/debugger/src/module.rs b/src/agent/debugger/src/module.rs index 1af7bebec8..df7d27a9c3 100644 --- a/src/agent/debugger/src/module.rs +++ b/src/agent/debugger/src/module.rs @@ -117,9 +117,21 @@ impl Module { address: u64, process_handle: HANDLE, ) -> Result<()> { - let mut breakpoint = ResolvedBreakpoint::new(id, kind, address); - breakpoint.enable(process_handle)?; - self.breakpoints.insert(address, breakpoint); + if let Some(breakpoint) = self.breakpoints.get_mut(address) { + // Update the existing breakpoint with a (probably new) id and (probably not new) kind. + breakpoint.update(id, kind); + if breakpoint.is_disabled() { + // Existing breakpoint was disabled, but the caller wants a new + // breakpoint that by luck or otherwise, was at the same address + // as an existing breakpoint, so we go ahead and enable. + breakpoint.enable(process_handle)?; + } + } else { + let mut breakpoint = ResolvedBreakpoint::new(id, kind, address); + breakpoint.enable(process_handle)?; + self.breakpoints.insert(address, breakpoint); + } + Ok(()) }