blob: 479c46869d49d679e4600cca88aeeed2d85f5fd4 [file] [log] [blame]
Johnny Chene9a56272012-08-09 23:09:42 +00001//===-- WatchpointOptions.cpp -----------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Johnny Chene9a56272012-08-09 23:09:42 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
Eugene Zelenko16fd7512015-10-30 18:50:12 +000014#include "lldb/Breakpoint/WatchpointOptions.h"
15
Kate Stoneb9c1b512016-09-06 20:57:50 +000016#include "lldb/Breakpoint/StoppointCallbackContext.h"
Johnny Chene9a56272012-08-09 23:09:42 +000017#include "lldb/Core/StringList.h"
18#include "lldb/Core/Value.h"
Johnny Chene9a56272012-08-09 23:09:42 +000019#include "lldb/Target/Process.h"
20#include "lldb/Target/Target.h"
21#include "lldb/Target/ThreadSpec.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000022#include "lldb/Utility/Stream.h"
Johnny Chene9a56272012-08-09 23:09:42 +000023
24using namespace lldb;
25using namespace lldb_private;
26
Kate Stoneb9c1b512016-09-06 20:57:50 +000027bool WatchpointOptions::NullCallback(void *baton,
28 StoppointCallbackContext *context,
29 lldb::user_id_t watch_id) {
30 return true;
Johnny Chene9a56272012-08-09 23:09:42 +000031}
32
33//----------------------------------------------------------------------
34// WatchpointOptions constructor
35//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000036WatchpointOptions::WatchpointOptions()
37 : m_callback(WatchpointOptions::NullCallback), m_callback_baton_sp(),
38 m_callback_is_synchronous(false), m_thread_spec_ap() {}
Johnny Chene9a56272012-08-09 23:09:42 +000039
40//----------------------------------------------------------------------
41// WatchpointOptions copy constructor
42//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000043WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs)
44 : m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp),
45 m_callback_is_synchronous(rhs.m_callback_is_synchronous),
46 m_thread_spec_ap() {
47 if (rhs.m_thread_spec_ap.get() != nullptr)
48 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
Johnny Chene9a56272012-08-09 23:09:42 +000049}
50
51//----------------------------------------------------------------------
52// WatchpointOptions assignment operator
53//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000054const WatchpointOptions &WatchpointOptions::
55operator=(const WatchpointOptions &rhs) {
56 m_callback = rhs.m_callback;
57 m_callback_baton_sp = rhs.m_callback_baton_sp;
58 m_callback_is_synchronous = rhs.m_callback_is_synchronous;
59 if (rhs.m_thread_spec_ap.get() != nullptr)
60 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
61 return *this;
Johnny Chene9a56272012-08-09 23:09:42 +000062}
63
64WatchpointOptions *
Kate Stoneb9c1b512016-09-06 20:57:50 +000065WatchpointOptions::CopyOptionsNoCallback(WatchpointOptions &orig) {
66 WatchpointHitCallback orig_callback = orig.m_callback;
67 lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
68 bool orig_is_sync = orig.m_callback_is_synchronous;
69
70 orig.ClearCallback();
71 WatchpointOptions *ret_val = new WatchpointOptions(orig);
72
73 orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);
74
75 return ret_val;
Johnny Chene9a56272012-08-09 23:09:42 +000076}
77
78//----------------------------------------------------------------------
79// Destructor
80//----------------------------------------------------------------------
Eugene Zelenko16fd7512015-10-30 18:50:12 +000081WatchpointOptions::~WatchpointOptions() = default;
Johnny Chene9a56272012-08-09 23:09:42 +000082
83//------------------------------------------------------------------
84// Callbacks
85//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000086void WatchpointOptions::SetCallback(WatchpointHitCallback callback,
87 const BatonSP &callback_baton_sp,
88 bool callback_is_synchronous) {
89 m_callback_is_synchronous = callback_is_synchronous;
90 m_callback = callback;
91 m_callback_baton_sp = callback_baton_sp;
Johnny Chene9a56272012-08-09 23:09:42 +000092}
93
Kate Stoneb9c1b512016-09-06 20:57:50 +000094void WatchpointOptions::ClearCallback() {
95 m_callback = WatchpointOptions::NullCallback;
96 m_callback_is_synchronous = false;
97 m_callback_baton_sp.reset();
Johnny Chene9a56272012-08-09 23:09:42 +000098}
99
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }
101
102const Baton *WatchpointOptions::GetBaton() const {
103 return m_callback_baton_sp.get();
Johnny Chene9a56272012-08-09 23:09:42 +0000104}
105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106bool WatchpointOptions::InvokeCallback(StoppointCallbackContext *context,
107 lldb::user_id_t watch_id) {
108 if (m_callback && context->is_synchronous == IsCallbackSynchronous()) {
Zachary Turner4e4fbe82016-09-13 17:53:38 +0000109 return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 : nullptr,
111 context, watch_id);
112 } else
113 return true;
Johnny Chene9a56272012-08-09 23:09:42 +0000114}
115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116bool WatchpointOptions::HasCallback() {
117 return m_callback != WatchpointOptions::NullCallback;
118}
119
120const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {
121 return m_thread_spec_ap.get();
122}
123
124ThreadSpec *WatchpointOptions::GetThreadSpec() {
125 if (m_thread_spec_ap.get() == nullptr)
126 m_thread_spec_ap.reset(new ThreadSpec());
127
128 return m_thread_spec_ap.get();
129}
130
131void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {
132 GetThreadSpec()->SetTID(thread_id);
133}
134
135void WatchpointOptions::GetCallbackDescription(
136 Stream *s, lldb::DescriptionLevel level) const {
137 if (m_callback_baton_sp.get()) {
138 s->EOL();
139 m_callback_baton_sp->GetDescription(s, level);
140 }
141}
142
143void WatchpointOptions::GetDescription(Stream *s,
144 lldb::DescriptionLevel level) const {
145 // Figure out if there are any options not at their default value, and only
146 // print
147 // anything if there are:
148
149 if ((GetThreadSpecNoCreate() != nullptr &&
150 GetThreadSpecNoCreate()->HasSpecification())) {
151 if (level == lldb::eDescriptionLevelVerbose) {
152 s->EOL();
153 s->IndentMore();
154 s->Indent();
155 s->PutCString("Watchpoint Options:\n");
156 s->IndentMore();
157 s->Indent();
158 } else
159 s->PutCString(" Options: ");
160
161 if (m_thread_spec_ap.get())
162 m_thread_spec_ap->GetDescription(s, level);
163 else if (level == eDescriptionLevelBrief)
164 s->PutCString("thread spec: no ");
165 if (level == lldb::eDescriptionLevelFull) {
166 s->IndentLess();
167 s->IndentMore();
Johnny Chene9a56272012-08-09 23:09:42 +0000168 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169 }
170
171 GetCallbackDescription(s, level);
Johnny Chene9a56272012-08-09 23:09:42 +0000172}
173
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174void WatchpointOptions::CommandBaton::GetDescription(
175 Stream *s, lldb::DescriptionLevel level) const {
Zachary Turner4e4fbe82016-09-13 17:53:38 +0000176 const CommandData *data = getItem();
Johnny Chene9a56272012-08-09 23:09:42 +0000177
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178 if (level == eDescriptionLevelBrief) {
179 s->Printf(", commands = %s",
180 (data && data->user_source.GetSize() > 0) ? "yes" : "no");
181 return;
182 }
Johnny Chene9a56272012-08-09 23:09:42 +0000183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184 s->IndentMore();
185 s->Indent("watchpoint commands:\n");
Johnny Chene9a56272012-08-09 23:09:42 +0000186
Kate Stoneb9c1b512016-09-06 20:57:50 +0000187 s->IndentMore();
188 if (data && data->user_source.GetSize() > 0) {
189 const size_t num_strings = data->user_source.GetSize();
190 for (size_t i = 0; i < num_strings; ++i) {
191 s->Indent(data->user_source.GetStringAtIndex(i));
192 s->EOL();
Johnny Chene9a56272012-08-09 23:09:42 +0000193 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 } else {
195 s->PutCString("No commands.\n");
196 }
197 s->IndentLess();
198 s->IndentLess();
Johnny Chene9a56272012-08-09 23:09:42 +0000199}