diff --git a/src/debugger/mod.rs b/src/debugger/mod.rs index 88f130a1..d530eaf9 100644 --- a/src/debugger/mod.rs +++ b/src/debugger/mod.rs @@ -467,7 +467,11 @@ impl Debugger { ))?; match event { StopReason::DebugeeExit(code) => { - self.watchpoints.clear_local_and_forget_all(); + // ignore all possible errors on watchpoints disabling + _ = self.watchpoints.clear_local_disable_global( + self.debugee.tracee_ctl(), + &mut self.breakpoints, + ); // ignore all possible errors on breakpoints disabling _ = self.breakpoints.disable_all_breakpoints(&self.debugee); self.hooks.on_exit(code); @@ -593,16 +597,17 @@ impl Debugger { pub fn restart_debugee(&mut self) -> Result { match self.debugee.execution_status() { ExecutionStatus::Unload => { - // all breakpoints already disabled by default + // all breakpoints and watchpoints already disabled by default } ExecutionStatus::InProgress => { print_warns!(self .watchpoints - .clear_local_forget_global(self.debugee.tracee_ctl(), &mut self.breakpoints)); + .clear_local_disable_global(self.debugee.tracee_ctl(), &mut self.breakpoints)); print_warns!(self.breakpoints.disable_all_breakpoints(&self.debugee)?); } ExecutionStatus::Exited => { - // all breakpoints already disabled by [`StopReason::DebugeeExit`] handler + // all breakpoints and watchpoints + // already disabled by [`StopReason::DebugeeExit`] handler } } @@ -1090,9 +1095,7 @@ impl Drop for Debugger { WaitStatus::Signaled(_, Signal::SIGKILL, _) )); } - ExecutionStatus::Exited => { - self.watchpoints.clear_and_forget_all(); - } + ExecutionStatus::Exited => {} } } } diff --git a/src/debugger/watchpoint.rs b/src/debugger/watchpoint.rs index 27fccba5..195194a8 100644 --- a/src/debugger/watchpoint.rs +++ b/src/debugger/watchpoint.rs @@ -209,8 +209,6 @@ pub struct Watchpoint { hw: HardwareBreakpoint, /// Subject for observation. subject: Subject, - /// Whether true if underlying hardware breakpoint is already disabled. - disabled: bool, } fn call_with_context(debugger: &mut Debugger, ctx: ExplorationContext, f: F) -> T @@ -395,7 +393,6 @@ impl Watchpoint { number: GLOBAL_WP_COUNTER.fetch_add(1, Ordering::Relaxed), hw: hw_brkpt, subject: Subject::Expression(target), - disabled: false, }; Ok((state, this)) } @@ -430,7 +427,6 @@ impl Watchpoint { number: GLOBAL_WP_COUNTER.fetch_add(1, Ordering::Relaxed), hw: hw_brkpt, subject: Subject::Address(target), - disabled: false, }; Ok((state, this)) @@ -474,7 +470,6 @@ impl Watchpoint { tracee_ctl: &TraceeCtl, breakpoints: &mut BreakpointRegistry, ) -> Result { - debug_assert!(!self.disabled); // disable hardware breakpoint let state = self.hw.disable(tracee_ctl)?; @@ -484,31 +479,19 @@ impl Watchpoint { breakpoints.remove_by_num(brkpt)?; } } - - // don't forget `disabled` flag - this will be checked when watchpoint dropped - self.disabled = true; Ok(state) } /// Enable watchpoint from disabled state. fn refresh(&mut self, tracee_ctl: &TraceeCtl) -> Result { - debug_assert!(self.disabled); if let Subject::Expression(ref mut expr_t) = self.subject { expr_t.last_value = None; } let state = self.hw.enable(tracee_ctl)?; - self.disabled = false; Ok(state) } } -impl Drop for Watchpoint { - fn drop(&mut self) { - // all dropped watchpoints should be disabled first - debug_assert!(self.disabled); - } -} - /// Watchpoint information struct. pub struct WatchpointView<'a> { pub number: u32, @@ -654,18 +637,9 @@ impl WatchpointRegistry { self.last_seen_state = None; } - /// Remove all watchpoints from registry without disabling. - pub fn clear_and_forget_all(&mut self) { - // this is hack for disable a watchpoint without real disabling - self.watchpoints - .drain(..) - .for_each(|mut wp| wp.disabled = true); - self.last_seen_state = None; - } - /// Remove all scoped watchpoints (typically it is watchpoints at local variables) /// and disable non-scoped. - pub fn clear_local_forget_global( + pub fn clear_local_disable_global( &mut self, tracee_ctl: &TraceeCtl, breakpoints: &mut BreakpointRegistry, @@ -690,16 +664,6 @@ impl WatchpointRegistry { result } - /// Remove all scoped watchpoints without disabling. - pub fn clear_local_and_forget_all(&mut self) { - // this is hack for disable a watchpoint without real disabling - self.watchpoints.retain_mut(|wp| { - wp.disabled = true; - !wp.scoped() - }); - self.last_seen_state = None; - } - /// Distribute all existed watchpoints to a new tracee (thread). pub fn distribute_to_tracee(&self, tracee: &Tracee) -> Result<(), Error> { if let Some(ref state) = self.last_seen_state {