blob: 1898486221bba7eea8d06609fee2267039f9cb49 [file] [log] [blame]
Johnny Chene9a56272012-08-09 23:09:42 +00001//===-- WatchpointOptions.cpp -----------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Johnny Chene9a56272012-08-09 23:09:42 +00006//
7//===----------------------------------------------------------------------===//
8
Eugene Zelenko16fd7512015-10-30 18:50:12 +00009#include "lldb/Breakpoint/WatchpointOptions.h"
10
Kate Stoneb9c1b512016-09-06 20:57:50 +000011#include "lldb/Breakpoint/StoppointCallbackContext.h"
Johnny Chene9a56272012-08-09 23:09:42 +000012#include "lldb/Core/Value.h"
Johnny Chene9a56272012-08-09 23:09:42 +000013#include "lldb/Target/Process.h"
14#include "lldb/Target/Target.h"
15#include "lldb/Target/ThreadSpec.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000016#include "lldb/Utility/Stream.h"
Zachary Turner573ab902017-03-21 18:25:04 +000017#include "lldb/Utility/StringList.h"
Johnny Chene9a56272012-08-09 23:09:42 +000018
19using namespace lldb;
20using namespace lldb_private;
21
Kate Stoneb9c1b512016-09-06 20:57:50 +000022bool WatchpointOptions::NullCallback(void *baton,
23 StoppointCallbackContext *context,
24 lldb::user_id_t watch_id) {
25 return true;
Johnny Chene9a56272012-08-09 23:09:42 +000026}
27
28//----------------------------------------------------------------------
29// WatchpointOptions constructor
30//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000031WatchpointOptions::WatchpointOptions()
32 : m_callback(WatchpointOptions::NullCallback), m_callback_baton_sp(),
33 m_callback_is_synchronous(false), m_thread_spec_ap() {}
Johnny Chene9a56272012-08-09 23:09:42 +000034
35//----------------------------------------------------------------------
36// WatchpointOptions copy constructor
37//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000038WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs)
39 : m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp),
40 m_callback_is_synchronous(rhs.m_callback_is_synchronous),
41 m_thread_spec_ap() {
42 if (rhs.m_thread_spec_ap.get() != nullptr)
43 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
Johnny Chene9a56272012-08-09 23:09:42 +000044}
45
46//----------------------------------------------------------------------
47// WatchpointOptions assignment operator
48//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000049const WatchpointOptions &WatchpointOptions::
50operator=(const WatchpointOptions &rhs) {
51 m_callback = rhs.m_callback;
52 m_callback_baton_sp = rhs.m_callback_baton_sp;
53 m_callback_is_synchronous = rhs.m_callback_is_synchronous;
54 if (rhs.m_thread_spec_ap.get() != nullptr)
55 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
56 return *this;
Johnny Chene9a56272012-08-09 23:09:42 +000057}
58
59WatchpointOptions *
Kate Stoneb9c1b512016-09-06 20:57:50 +000060WatchpointOptions::CopyOptionsNoCallback(WatchpointOptions &orig) {
61 WatchpointHitCallback orig_callback = orig.m_callback;
62 lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
63 bool orig_is_sync = orig.m_callback_is_synchronous;
64
65 orig.ClearCallback();
66 WatchpointOptions *ret_val = new WatchpointOptions(orig);
67
68 orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);
69
70 return ret_val;
Johnny Chene9a56272012-08-09 23:09:42 +000071}
72
73//----------------------------------------------------------------------
74// Destructor
75//----------------------------------------------------------------------
Eugene Zelenko16fd7512015-10-30 18:50:12 +000076WatchpointOptions::~WatchpointOptions() = default;
Johnny Chene9a56272012-08-09 23:09:42 +000077
78//------------------------------------------------------------------
79// Callbacks
80//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000081void WatchpointOptions::SetCallback(WatchpointHitCallback callback,
82 const BatonSP &callback_baton_sp,
83 bool callback_is_synchronous) {
84 m_callback_is_synchronous = callback_is_synchronous;
85 m_callback = callback;
86 m_callback_baton_sp = callback_baton_sp;
Johnny Chene9a56272012-08-09 23:09:42 +000087}
88
Kate Stoneb9c1b512016-09-06 20:57:50 +000089void WatchpointOptions::ClearCallback() {
90 m_callback = WatchpointOptions::NullCallback;
91 m_callback_is_synchronous = false;
92 m_callback_baton_sp.reset();
Johnny Chene9a56272012-08-09 23:09:42 +000093}
94
Kate Stoneb9c1b512016-09-06 20:57:50 +000095Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }
96
97const Baton *WatchpointOptions::GetBaton() const {
98 return m_callback_baton_sp.get();
Johnny Chene9a56272012-08-09 23:09:42 +000099}
100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101bool WatchpointOptions::InvokeCallback(StoppointCallbackContext *context,
102 lldb::user_id_t watch_id) {
103 if (m_callback && context->is_synchronous == IsCallbackSynchronous()) {
Zachary Turner4e4fbe82016-09-13 17:53:38 +0000104 return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105 : nullptr,
106 context, watch_id);
107 } else
108 return true;
Johnny Chene9a56272012-08-09 23:09:42 +0000109}
110
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111bool WatchpointOptions::HasCallback() {
112 return m_callback != WatchpointOptions::NullCallback;
113}
114
115const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {
116 return m_thread_spec_ap.get();
117}
118
119ThreadSpec *WatchpointOptions::GetThreadSpec() {
120 if (m_thread_spec_ap.get() == nullptr)
121 m_thread_spec_ap.reset(new ThreadSpec());
122
123 return m_thread_spec_ap.get();
124}
125
126void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {
127 GetThreadSpec()->SetTID(thread_id);
128}
129
130void WatchpointOptions::GetCallbackDescription(
131 Stream *s, lldb::DescriptionLevel level) const {
132 if (m_callback_baton_sp.get()) {
133 s->EOL();
134 m_callback_baton_sp->GetDescription(s, level);
135 }
136}
137
138void WatchpointOptions::GetDescription(Stream *s,
139 lldb::DescriptionLevel level) const {
140 // Figure out if there are any options not at their default value, and only
Adrian Prantl05097242018-04-30 16:49:04 +0000141 // print anything if there are:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142
143 if ((GetThreadSpecNoCreate() != nullptr &&
144 GetThreadSpecNoCreate()->HasSpecification())) {
145 if (level == lldb::eDescriptionLevelVerbose) {
146 s->EOL();
147 s->IndentMore();
148 s->Indent();
149 s->PutCString("Watchpoint Options:\n");
150 s->IndentMore();
151 s->Indent();
152 } else
153 s->PutCString(" Options: ");
154
155 if (m_thread_spec_ap.get())
156 m_thread_spec_ap->GetDescription(s, level);
157 else if (level == eDescriptionLevelBrief)
158 s->PutCString("thread spec: no ");
159 if (level == lldb::eDescriptionLevelFull) {
160 s->IndentLess();
161 s->IndentMore();
Johnny Chene9a56272012-08-09 23:09:42 +0000162 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 }
164
165 GetCallbackDescription(s, level);
Johnny Chene9a56272012-08-09 23:09:42 +0000166}
167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168void WatchpointOptions::CommandBaton::GetDescription(
169 Stream *s, lldb::DescriptionLevel level) const {
Zachary Turner4e4fbe82016-09-13 17:53:38 +0000170 const CommandData *data = getItem();
Johnny Chene9a56272012-08-09 23:09:42 +0000171
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 if (level == eDescriptionLevelBrief) {
173 s->Printf(", commands = %s",
174 (data && data->user_source.GetSize() > 0) ? "yes" : "no");
175 return;
176 }
Johnny Chene9a56272012-08-09 23:09:42 +0000177
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178 s->IndentMore();
179 s->Indent("watchpoint commands:\n");
Johnny Chene9a56272012-08-09 23:09:42 +0000180
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181 s->IndentMore();
182 if (data && data->user_source.GetSize() > 0) {
183 const size_t num_strings = data->user_source.GetSize();
184 for (size_t i = 0; i < num_strings; ++i) {
185 s->Indent(data->user_source.GetStringAtIndex(i));
186 s->EOL();
Johnny Chene9a56272012-08-09 23:09:42 +0000187 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 } else {
189 s->PutCString("No commands.\n");
190 }
191 s->IndentLess();
192 s->IndentLess();
Johnny Chene9a56272012-08-09 23:09:42 +0000193}