Skip to content

Commit

Permalink
refactor: remove watchpoint disabled property
Browse files Browse the repository at this point in the history
  • Loading branch information
godzie44 committed May 19, 2024
1 parent a0d7a3b commit 99bcc3a
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 44 deletions.
17 changes: 10 additions & 7 deletions src/debugger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -593,16 +597,17 @@ impl Debugger {
pub fn restart_debugee(&mut self) -> Result<Pid, Error> {
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
}
}

Expand Down Expand Up @@ -1090,9 +1095,7 @@ impl Drop for Debugger {
WaitStatus::Signaled(_, Signal::SIGKILL, _)
));
}
ExecutionStatus::Exited => {
self.watchpoints.clear_and_forget_all();
}
ExecutionStatus::Exited => {}
}
}
}
Expand Down
38 changes: 1 addition & 37 deletions src/debugger/watchpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<F, T>(debugger: &mut Debugger, ctx: ExplorationContext, f: F) -> T
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -474,7 +470,6 @@ impl Watchpoint {
tracee_ctl: &TraceeCtl,
breakpoints: &mut BreakpointRegistry,
) -> Result<HardwareDebugState, Error> {
debug_assert!(!self.disabled);
// disable hardware breakpoint
let state = self.hw.disable(tracee_ctl)?;

Expand All @@ -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<HardwareDebugState, Error> {
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,
Expand Down Expand Up @@ -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,
Expand All @@ -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 {
Expand Down

0 comments on commit 99bcc3a

Please sign in to comment.