Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/API/SBWatchpoint.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- SBWatchpoint.cpp --------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "lldb/API/SBWatchpoint.h"
10
#include "lldb/API/SBAddress.h"
11
#include "lldb/API/SBDebugger.h"
12
#include "lldb/API/SBDefines.h"
13
#include "lldb/API/SBEvent.h"
14
#include "lldb/API/SBStream.h"
15
#include "lldb/Utility/Instrumentation.h"
16
17
#include "lldb/Breakpoint/Watchpoint.h"
18
#include "lldb/Breakpoint/WatchpointList.h"
19
#include "lldb/Symbol/CompilerType.h"
20
#include "lldb/Target/Process.h"
21
#include "lldb/Target/Target.h"
22
#include "lldb/Utility/Stream.h"
23
#include "lldb/lldb-defines.h"
24
#include "lldb/lldb-types.h"
25
26
using namespace lldb;
27
using namespace lldb_private;
28
29
158
SBWatchpoint::SBWatchpoint() { LLDB_INSTRUMENT_VA(this); }
30
31
SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp)
32
11
    : m_opaque_wp(wp_sp) {
33
11
  LLDB_INSTRUMENT_VA(this, wp_sp);
34
11
}
35
36
SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs)
37
78
    : m_opaque_wp(rhs.m_opaque_wp) {
38
78
  LLDB_INSTRUMENT_VA(this, rhs);
39
78
}
40
41
79
const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) {
42
79
  LLDB_INSTRUMENT_VA(this, rhs);
43
44
79
  m_opaque_wp = rhs.m_opaque_wp;
45
79
  return *this;
46
79
}
47
48
247
SBWatchpoint::~SBWatchpoint() = default;
49
50
3
watch_id_t SBWatchpoint::GetID() {
51
3
  LLDB_INSTRUMENT_VA(this);
52
53
3
  watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
54
3
  lldb::WatchpointSP watchpoint_sp(GetSP());
55
3
  if (watchpoint_sp)
56
2
    watch_id = watchpoint_sp->GetID();
57
58
3
  return watch_id;
59
3
}
60
61
6
bool SBWatchpoint::IsValid() const {
62
6
  LLDB_INSTRUMENT_VA(this);
63
6
  return this->operator bool();
64
6
}
65
18
SBWatchpoint::operator bool() const {
66
18
  LLDB_INSTRUMENT_VA(this);
67
68
18
  return bool(m_opaque_wp.lock());
69
18
}
70
71
0
bool SBWatchpoint::operator==(const SBWatchpoint &rhs) const {
72
0
  LLDB_INSTRUMENT_VA(this, rhs);
73
74
0
  return GetSP() == rhs.GetSP();
75
0
}
76
77
0
bool SBWatchpoint::operator!=(const SBWatchpoint &rhs) const {
78
0
  LLDB_INSTRUMENT_VA(this, rhs);
79
80
0
  return !(*this == rhs);
81
0
}
82
83
0
SBError SBWatchpoint::GetError() {
84
0
  LLDB_INSTRUMENT_VA(this);
85
86
0
  SBError sb_error;
87
0
  lldb::WatchpointSP watchpoint_sp(GetSP());
88
0
  if (watchpoint_sp) {
89
0
    sb_error.SetError(watchpoint_sp->GetError());
90
0
  }
91
0
  return sb_error;
92
0
}
93
94
3
int32_t SBWatchpoint::GetHardwareIndex() {
95
3
  LLDB_INSTRUMENT_VA(this);
96
97
3
  int32_t hw_index = -1;
98
99
3
  lldb::WatchpointSP watchpoint_sp(GetSP());
100
3
  if (watchpoint_sp) {
101
2
    std::lock_guard<std::recursive_mutex> guard(
102
2
        watchpoint_sp->GetTarget().GetAPIMutex());
103
2
    hw_index = watchpoint_sp->GetHardwareIndex();
104
2
  }
105
106
3
  return hw_index;
107
3
}
108
109
4
addr_t SBWatchpoint::GetWatchAddress() {
110
4
  LLDB_INSTRUMENT_VA(this);
111
112
4
  addr_t ret_addr = LLDB_INVALID_ADDRESS;
113
114
4
  lldb::WatchpointSP watchpoint_sp(GetSP());
115
4
  if (watchpoint_sp) {
116
3
    std::lock_guard<std::recursive_mutex> guard(
117
3
        watchpoint_sp->GetTarget().GetAPIMutex());
118
3
    ret_addr = watchpoint_sp->GetLoadAddress();
119
3
  }
120
121
4
  return ret_addr;
122
4
}
123
124
4
size_t SBWatchpoint::GetWatchSize() {
125
4
  LLDB_INSTRUMENT_VA(this);
126
127
4
  size_t watch_size = 0;
128
129
4
  lldb::WatchpointSP watchpoint_sp(GetSP());
130
4
  if (watchpoint_sp) {
131
3
    std::lock_guard<std::recursive_mutex> guard(
132
3
        watchpoint_sp->GetTarget().GetAPIMutex());
133
3
    watch_size = watchpoint_sp->GetByteSize();
134
3
  }
135
136
4
  return watch_size;
137
4
}
138
139
7
void SBWatchpoint::SetEnabled(bool enabled) {
140
7
  LLDB_INSTRUMENT_VA(this, enabled);
141
142
7
  lldb::WatchpointSP watchpoint_sp(GetSP());
143
7
  if (watchpoint_sp) {
144
6
    Target &target = watchpoint_sp->GetTarget();
145
6
    std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
146
6
    ProcessSP process_sp = target.GetProcessSP();
147
6
    const bool notify = true;
148
6
    if (process_sp) {
149
6
      if (enabled)
150
2
        process_sp->EnableWatchpoint(watchpoint_sp.get(), notify);
151
4
      else
152
4
        process_sp->DisableWatchpoint(watchpoint_sp.get(), notify);
153
6
    } else {
154
0
      watchpoint_sp->SetEnabled(enabled, notify);
155
0
    }
156
6
  }
157
7
}
158
159
7
bool SBWatchpoint::IsEnabled() {
160
7
  LLDB_INSTRUMENT_VA(this);
161
162
7
  lldb::WatchpointSP watchpoint_sp(GetSP());
163
7
  if (watchpoint_sp) {
164
6
    std::lock_guard<std::recursive_mutex> guard(
165
6
        watchpoint_sp->GetTarget().GetAPIMutex());
166
6
    return watchpoint_sp->IsEnabled();
167
6
  } else
168
1
    return false;
169
7
}
170
171
53
uint32_t SBWatchpoint::GetHitCount() {
172
53
  LLDB_INSTRUMENT_VA(this);
173
174
53
  uint32_t count = 0;
175
53
  lldb::WatchpointSP watchpoint_sp(GetSP());
176
53
  if (watchpoint_sp) {
177
52
    std::lock_guard<std::recursive_mutex> guard(
178
52
        watchpoint_sp->GetTarget().GetAPIMutex());
179
52
    count = watchpoint_sp->GetHitCount();
180
52
  }
181
182
53
  return count;
183
53
}
184
185
2
uint32_t SBWatchpoint::GetIgnoreCount() {
186
2
  LLDB_INSTRUMENT_VA(this);
187
188
2
  lldb::WatchpointSP watchpoint_sp(GetSP());
189
2
  if (watchpoint_sp) {
190
1
    std::lock_guard<std::recursive_mutex> guard(
191
1
        watchpoint_sp->GetTarget().GetAPIMutex());
192
1
    return watchpoint_sp->GetIgnoreCount();
193
1
  } else
194
1
    return 0;
195
2
}
196
197
3
void SBWatchpoint::SetIgnoreCount(uint32_t n) {
198
3
  LLDB_INSTRUMENT_VA(this, n);
199
200
3
  lldb::WatchpointSP watchpoint_sp(GetSP());
201
3
  if (watchpoint_sp) {
202
2
    std::lock_guard<std::recursive_mutex> guard(
203
2
        watchpoint_sp->GetTarget().GetAPIMutex());
204
2
    watchpoint_sp->SetIgnoreCount(n);
205
2
  }
206
3
}
207
208
3
const char *SBWatchpoint::GetCondition() {
209
3
  LLDB_INSTRUMENT_VA(this);
210
211
3
  lldb::WatchpointSP watchpoint_sp(GetSP());
212
3
  if (!watchpoint_sp)
213
1
    return nullptr;
214
215
2
  std::lock_guard<std::recursive_mutex> guard(
216
2
      watchpoint_sp->GetTarget().GetAPIMutex());
217
2
  return ConstString(watchpoint_sp->GetConditionText()).GetCString();
218
3
}
219
220
3
void SBWatchpoint::SetCondition(const char *condition) {
221
3
  LLDB_INSTRUMENT_VA(this, condition);
222
223
3
  lldb::WatchpointSP watchpoint_sp(GetSP());
224
3
  if (watchpoint_sp) {
225
2
    std::lock_guard<std::recursive_mutex> guard(
226
2
        watchpoint_sp->GetTarget().GetAPIMutex());
227
2
    watchpoint_sp->SetCondition(condition);
228
2
  }
229
3
}
230
231
bool SBWatchpoint::GetDescription(SBStream &description,
232
65
                                  DescriptionLevel level) {
233
65
  LLDB_INSTRUMENT_VA(this, description, level);
234
235
65
  Stream &strm = description.ref();
236
237
65
  lldb::WatchpointSP watchpoint_sp(GetSP());
238
65
  if (watchpoint_sp) {
239
63
    std::lock_guard<std::recursive_mutex> guard(
240
63
        watchpoint_sp->GetTarget().GetAPIMutex());
241
63
    watchpoint_sp->GetDescription(&strm, level);
242
63
    strm.EOL();
243
63
  } else
244
2
    strm.PutCString("No value");
245
246
65
  return true;
247
65
}
248
249
0
void SBWatchpoint::Clear() {
250
0
  LLDB_INSTRUMENT_VA(this);
251
252
0
  m_opaque_wp.reset();
253
0
}
254
255
177
lldb::WatchpointSP SBWatchpoint::GetSP() const {
256
177
  LLDB_INSTRUMENT_VA(this);
257
258
177
  return m_opaque_wp.lock();
259
177
}
260
261
73
void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) {
262
73
  LLDB_INSTRUMENT_VA(this, sp);
263
264
73
  m_opaque_wp = sp;
265
73
}
266
267
5
bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) {
268
5
  LLDB_INSTRUMENT_VA(event);
269
270
5
  return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) !=
271
5
         nullptr;
272
5
}
273
274
WatchpointEventType
275
5
SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) {
276
5
  LLDB_INSTRUMENT_VA(event);
277
278
5
  if (event.IsValid())
279
5
    return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent(
280
5
        event.GetSP());
281
0
  return eWatchpointEventTypeInvalidType;
282
5
}
283
284
0
SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) {
285
0
  LLDB_INSTRUMENT_VA(event);
286
287
0
  SBWatchpoint sb_watchpoint;
288
0
  if (event.IsValid())
289
0
    sb_watchpoint =
290
0
        Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP());
291
0
  return sb_watchpoint;
292
0
}
293
294
6
lldb::SBType SBWatchpoint::GetType() {
295
6
  LLDB_INSTRUMENT_VA(this);
296
297
6
  lldb::WatchpointSP watchpoint_sp(GetSP());
298
6
  if (watchpoint_sp) {
299
6
    std::lock_guard<std::recursive_mutex> guard(
300
6
        watchpoint_sp->GetTarget().GetAPIMutex());
301
6
    const CompilerType &type = watchpoint_sp->GetCompilerType();
302
6
    return lldb::SBType(type);
303
6
  }
304
0
  return lldb::SBType();
305
6
}
306
307
3
WatchpointValueKind SBWatchpoint::GetWatchValueKind() {
308
3
  LLDB_INSTRUMENT_VA(this);
309
310
3
  lldb::WatchpointSP watchpoint_sp(GetSP());
311
3
  if (watchpoint_sp) {
312
3
    std::lock_guard<std::recursive_mutex> guard(
313
3
        watchpoint_sp->GetTarget().GetAPIMutex());
314
3
    if (watchpoint_sp->IsWatchVariable())
315
1
      return WatchpointValueKind::eWatchPointValueKindVariable;
316
2
    return WatchpointValueKind::eWatchPointValueKindExpression;
317
3
  }
318
0
  return WatchpointValueKind::eWatchPointValueKindInvalid;
319
3
}
320
321
5
const char *SBWatchpoint::GetWatchSpec() {
322
5
  LLDB_INSTRUMENT_VA(this);
323
324
5
  lldb::WatchpointSP watchpoint_sp(GetSP());
325
5
  if (!watchpoint_sp)
326
0
    return nullptr;
327
328
5
  std::lock_guard<std::recursive_mutex> guard(
329
5
      watchpoint_sp->GetTarget().GetAPIMutex());
330
  // Store the result of `GetWatchSpec()` as a ConstString
331
  // so that the C string we return has a sufficiently long
332
  // lifetime. Note this a memory leak but should be fairly
333
  // low impact.
334
5
  return ConstString(watchpoint_sp->GetWatchSpec()).AsCString();
335
5
}
336
337
3
bool SBWatchpoint::IsWatchingReads() {
338
3
  LLDB_INSTRUMENT_VA(this);
339
3
  lldb::WatchpointSP watchpoint_sp(GetSP());
340
3
  if (watchpoint_sp) {
341
3
    std::lock_guard<std::recursive_mutex> guard(
342
3
        watchpoint_sp->GetTarget().GetAPIMutex());
343
344
3
    return watchpoint_sp->WatchpointRead();
345
3
  }
346
347
0
  return false;
348
3
}
349
350
3
bool SBWatchpoint::IsWatchingWrites() {
351
3
  LLDB_INSTRUMENT_VA(this);
352
3
  lldb::WatchpointSP watchpoint_sp(GetSP());
353
3
  if (watchpoint_sp) {
354
3
    std::lock_guard<std::recursive_mutex> guard(
355
3
        watchpoint_sp->GetTarget().GetAPIMutex());
356
357
3
    return watchpoint_sp->WatchpointWrite() ||
358
3
           
watchpoint_sp->WatchpointModify()1
;
359
3
  }
360
361
0
  return false;
362
3
}