Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp
39587 views
1
//===-- WatchpointOptions.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/Breakpoint/WatchpointOptions.h"
10
11
#include "lldb/Breakpoint/StoppointCallbackContext.h"
12
#include "lldb/Core/Value.h"
13
#include "lldb/Target/Process.h"
14
#include "lldb/Target/Target.h"
15
#include "lldb/Target/ThreadSpec.h"
16
#include "lldb/Utility/Stream.h"
17
#include "lldb/Utility/StringList.h"
18
19
using namespace lldb;
20
using namespace lldb_private;
21
22
bool WatchpointOptions::NullCallback(void *baton,
23
StoppointCallbackContext *context,
24
lldb::user_id_t watch_id) {
25
return true;
26
}
27
28
// WatchpointOptions constructor
29
WatchpointOptions::WatchpointOptions()
30
: m_callback(WatchpointOptions::NullCallback) {}
31
32
// WatchpointOptions copy constructor
33
WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs)
34
: m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp),
35
m_callback_is_synchronous(rhs.m_callback_is_synchronous) {
36
if (rhs.m_thread_spec_up != nullptr)
37
m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);
38
}
39
40
// WatchpointOptions assignment operator
41
const WatchpointOptions &WatchpointOptions::
42
operator=(const WatchpointOptions &rhs) {
43
m_callback = rhs.m_callback;
44
m_callback_baton_sp = rhs.m_callback_baton_sp;
45
m_callback_is_synchronous = rhs.m_callback_is_synchronous;
46
if (rhs.m_thread_spec_up != nullptr)
47
m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);
48
return *this;
49
}
50
51
WatchpointOptions *
52
WatchpointOptions::CopyOptionsNoCallback(WatchpointOptions &orig) {
53
WatchpointHitCallback orig_callback = orig.m_callback;
54
lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
55
bool orig_is_sync = orig.m_callback_is_synchronous;
56
57
orig.ClearCallback();
58
WatchpointOptions *ret_val = new WatchpointOptions(orig);
59
60
orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);
61
62
return ret_val;
63
}
64
65
// Destructor
66
WatchpointOptions::~WatchpointOptions() = default;
67
68
// Callbacks
69
void WatchpointOptions::SetCallback(WatchpointHitCallback callback,
70
const BatonSP &callback_baton_sp,
71
bool callback_is_synchronous) {
72
m_callback_is_synchronous = callback_is_synchronous;
73
m_callback = callback;
74
m_callback_baton_sp = callback_baton_sp;
75
}
76
77
void WatchpointOptions::ClearCallback() {
78
m_callback = WatchpointOptions::NullCallback;
79
m_callback_is_synchronous = false;
80
m_callback_baton_sp.reset();
81
}
82
83
Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }
84
85
const Baton *WatchpointOptions::GetBaton() const {
86
return m_callback_baton_sp.get();
87
}
88
89
bool WatchpointOptions::InvokeCallback(StoppointCallbackContext *context,
90
lldb::user_id_t watch_id) {
91
if (m_callback && context->is_synchronous == IsCallbackSynchronous()) {
92
return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()
93
: nullptr,
94
context, watch_id);
95
} else
96
return true;
97
}
98
99
bool WatchpointOptions::HasCallback() {
100
return m_callback != WatchpointOptions::NullCallback;
101
}
102
103
const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {
104
return m_thread_spec_up.get();
105
}
106
107
ThreadSpec *WatchpointOptions::GetThreadSpec() {
108
if (m_thread_spec_up == nullptr)
109
m_thread_spec_up = std::make_unique<ThreadSpec>();
110
111
return m_thread_spec_up.get();
112
}
113
114
void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {
115
GetThreadSpec()->SetTID(thread_id);
116
}
117
118
void WatchpointOptions::GetCallbackDescription(
119
Stream *s, lldb::DescriptionLevel level) const {
120
if (m_callback_baton_sp.get()) {
121
s->EOL();
122
m_callback_baton_sp->GetDescription(s->AsRawOstream(), level,
123
s->GetIndentLevel());
124
}
125
}
126
127
void WatchpointOptions::GetDescription(Stream *s,
128
lldb::DescriptionLevel level) const {
129
// Figure out if there are any options not at their default value, and only
130
// print anything if there are:
131
132
if ((GetThreadSpecNoCreate() != nullptr &&
133
GetThreadSpecNoCreate()->HasSpecification())) {
134
if (level == lldb::eDescriptionLevelVerbose) {
135
s->EOL();
136
s->IndentMore();
137
s->Indent();
138
s->PutCString("Watchpoint Options:\n");
139
s->IndentMore();
140
s->Indent();
141
} else
142
s->PutCString(" Options: ");
143
144
if (m_thread_spec_up)
145
m_thread_spec_up->GetDescription(s, level);
146
else if (level == eDescriptionLevelBrief)
147
s->PutCString("thread spec: no ");
148
if (level == lldb::eDescriptionLevelFull) {
149
s->IndentLess();
150
s->IndentMore();
151
}
152
}
153
154
GetCallbackDescription(s, level);
155
}
156
157
void WatchpointOptions::CommandBaton::GetDescription(
158
llvm::raw_ostream &s, lldb::DescriptionLevel level,
159
unsigned indentation) const {
160
const CommandData *data = getItem();
161
162
if (level == eDescriptionLevelBrief) {
163
s << ", commands = %s"
164
<< ((data && data->user_source.GetSize() > 0) ? "yes" : "no");
165
return;
166
}
167
168
indentation += 2;
169
s.indent(indentation);
170
s << "watchpoint commands:\n";
171
172
indentation += 2;
173
if (data && data->user_source.GetSize() > 0) {
174
for (const std::string &line : data->user_source) {
175
s.indent(indentation);
176
s << line << "\n";
177
}
178
} else
179
s << "No commands.\n";
180
}
181
182