lldb/
watchpoint.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7use crate::{lldb_addr_t, sys, DescriptionLevel, SBError, SBStream};
8use std::fmt;
9
10/// An instance of a watch point for a specific target program.
11///
12/// A watchpoint is determined by the address the byte size that
13/// resulted in this particular instantiation. Each watchpoint has
14/// its own settable options.
15///
16/// # To Hit or Not
17///
18/// A watchpoint has multiple ways of controlling whether
19/// or not it should be considered active.
20///
21/// * Enabled. This is controlled via [`SBWatchpoint::is_enabled()`]
22///   and [`SBWatchpoint::set_enabled()`].
23/// * Ignore count. If set, this watchpoint will be ignored
24///   the first *ignore count* times that it is hit. This is
25///   controlled via [`SBWatchpoint::ignore_count()`] and
26///   [`SBWatchpoint::set_ignore_count()`].
27///
28/// A count of how many times a watchpoint has been it is
29/// available via [`SBWatchpoint::hit_count()`].
30pub struct SBWatchpoint {
31    /// The underlying raw `SBWatchpointRef`.
32    pub raw: sys::SBWatchpointRef,
33}
34
35impl SBWatchpoint {
36    /// Construct a new `SBWatchpoint`.
37    pub(crate) fn wrap(raw: sys::SBWatchpointRef) -> SBWatchpoint {
38        SBWatchpoint { raw }
39    }
40
41    /// Construct a new `Some(SBWatchpoint)` or `None`.
42    pub(crate) fn maybe_wrap(raw: sys::SBWatchpointRef) -> Option<SBWatchpoint> {
43        if unsafe { sys::SBWatchpointIsValid(raw) } {
44            Some(SBWatchpoint { raw })
45        } else {
46            None
47        }
48    }
49
50    /// Check whether or not this is a valid `SBWatchpoint` value.
51    pub fn is_valid(&self) -> bool {
52        unsafe { sys::SBWatchpointIsValid(self.raw) }
53    }
54
55    #[allow(missing_docs)]
56    pub fn error(&self) -> Option<SBError> {
57        SBError::maybe_wrap(unsafe { sys::SBWatchpointGetError(self.raw) })
58    }
59
60    #[allow(missing_docs)]
61    pub fn id(&self) -> i32 {
62        unsafe { sys::SBWatchpointGetID(self.raw) }
63    }
64
65    #[allow(missing_docs)]
66    pub fn hardware_index(&self) -> Option<i32> {
67        let idx = unsafe { sys::SBWatchpointGetHardwareIndex(self.raw) };
68        if idx == -1 {
69            None
70        } else {
71            Some(idx)
72        }
73    }
74
75    #[allow(missing_docs)]
76    pub fn watch_address(&self) -> lldb_addr_t {
77        unsafe { sys::SBWatchpointGetWatchAddress(self.raw) }
78    }
79
80    #[allow(missing_docs)]
81    pub fn watch_size(&self) -> usize {
82        unsafe { sys::SBWatchpointGetWatchSize(self.raw) }
83    }
84
85    #[allow(missing_docs)]
86    pub fn is_enabled(&self) -> bool {
87        unsafe { sys::SBWatchpointIsEnabled(self.raw) }
88    }
89
90    #[allow(missing_docs)]
91    pub fn set_enabled(&self, enabled: bool) {
92        unsafe { sys::SBWatchpointSetEnabled(self.raw, enabled) }
93    }
94
95    #[allow(missing_docs)]
96    pub fn hit_count(&self) -> u32 {
97        unsafe { sys::SBWatchpointGetHitCount(self.raw) }
98    }
99
100    #[allow(missing_docs)]
101    pub fn ignore_count(&self) -> u32 {
102        unsafe { sys::SBWatchpointGetIgnoreCount(self.raw) }
103    }
104
105    #[allow(missing_docs)]
106    pub fn set_ignore_count(&self, count: u32) {
107        unsafe { sys::SBWatchpointSetIgnoreCount(self.raw, count) }
108    }
109}
110
111impl Clone for SBWatchpoint {
112    fn clone(&self) -> SBWatchpoint {
113        SBWatchpoint {
114            raw: unsafe { sys::CloneSBWatchpoint(self.raw) },
115        }
116    }
117}
118
119impl fmt::Debug for SBWatchpoint {
120    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
121        let stream = SBStream::new();
122        unsafe { sys::SBWatchpointGetDescription(self.raw, stream.raw, DescriptionLevel::Brief) };
123        write!(fmt, "SBWatchpoint {{ {} }}", stream.data())
124    }
125}
126
127impl Drop for SBWatchpoint {
128    fn drop(&mut self) {
129        unsafe { sys::DisposeSBWatchpoint(self.raw) };
130    }
131}
132
133unsafe impl Send for SBWatchpoint {}
134unsafe impl Sync for SBWatchpoint {}
135
136#[cfg(feature = "graphql")]
137#[juniper::graphql_object]
138impl SBWatchpoint {
139    fn id() -> i32 {
140        self.id()
141    }
142
143    fn hardware_index() -> Option<i32> {
144        self.hardware_index()
145    }
146
147    // TODO(bm) This should be u64
148    fn watch_address() -> i32 {
149        self.watch_address() as i32
150    }
151
152    // TODO(bm) This should be u32
153    fn watch_size() -> i32 {
154        self.watch_size() as i32
155    }
156
157    fn is_enabled() -> bool {
158        self.is_enabled()
159    }
160
161    // TODO(bm) This should be u32
162    fn hit_count() -> i32 {
163        self.hit_count() as i32
164    }
165
166    // TODO(bm) This should be u32
167    fn ignore_count() -> i32 {
168        self.ignore_count() as i32
169    }
170}