1 //===-- 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 10 #include "lldb/Breakpoint/WatchpointOptions.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Stream.h" 17 #include "lldb/Core/StringList.h" 18 #include "lldb/Core/Value.h" 19 #include "lldb/Breakpoint/StoppointCallbackContext.h" 20 #include "lldb/Target/Process.h" 21 #include "lldb/Target/Target.h" 22 #include "lldb/Target/ThreadSpec.h" 23 #include "lldb/Expression/ClangUserExpression.h" 24 25 using namespace lldb; 26 using namespace lldb_private; 27 28 bool 29 WatchpointOptions::NullCallback (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id) 30 { 31 return true; 32 } 33 34 //---------------------------------------------------------------------- 35 // WatchpointOptions constructor 36 //---------------------------------------------------------------------- 37 WatchpointOptions::WatchpointOptions() : 38 m_callback (WatchpointOptions::NullCallback), 39 m_callback_baton_sp (), 40 m_callback_is_synchronous (false), 41 m_thread_spec_ap () 42 { 43 } 44 45 //---------------------------------------------------------------------- 46 // WatchpointOptions copy constructor 47 //---------------------------------------------------------------------- 48 WatchpointOptions::WatchpointOptions(const WatchpointOptions& rhs) : 49 m_callback (rhs.m_callback), 50 m_callback_baton_sp (rhs.m_callback_baton_sp), 51 m_callback_is_synchronous (rhs.m_callback_is_synchronous), 52 m_thread_spec_ap () 53 { 54 if (rhs.m_thread_spec_ap.get() != NULL) 55 m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get())); 56 } 57 58 //---------------------------------------------------------------------- 59 // WatchpointOptions assignment operator 60 //---------------------------------------------------------------------- 61 const WatchpointOptions& 62 WatchpointOptions::operator=(const WatchpointOptions& rhs) 63 { 64 m_callback = rhs.m_callback; 65 m_callback_baton_sp = rhs.m_callback_baton_sp; 66 m_callback_is_synchronous = rhs.m_callback_is_synchronous; 67 if (rhs.m_thread_spec_ap.get() != NULL) 68 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); 69 return *this; 70 } 71 72 WatchpointOptions * 73 WatchpointOptions::CopyOptionsNoCallback (WatchpointOptions &orig) 74 { 75 WatchpointHitCallback orig_callback = orig.m_callback; 76 lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp; 77 bool orig_is_sync = orig.m_callback_is_synchronous; 78 79 orig.ClearCallback(); 80 WatchpointOptions *ret_val = new WatchpointOptions(orig); 81 82 orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync); 83 84 return ret_val; 85 } 86 87 //---------------------------------------------------------------------- 88 // Destructor 89 //---------------------------------------------------------------------- 90 WatchpointOptions::~WatchpointOptions() 91 { 92 } 93 94 //------------------------------------------------------------------ 95 // Callbacks 96 //------------------------------------------------------------------ 97 void 98 WatchpointOptions::SetCallback (WatchpointHitCallback callback, const BatonSP &callback_baton_sp, bool callback_is_synchronous) 99 { 100 m_callback_is_synchronous = callback_is_synchronous; 101 m_callback = callback; 102 m_callback_baton_sp = callback_baton_sp; 103 } 104 105 void 106 WatchpointOptions::ClearCallback () 107 { 108 m_callback = WatchpointOptions::NullCallback; 109 m_callback_is_synchronous = false; 110 m_callback_baton_sp.reset(); 111 } 112 113 Baton * 114 WatchpointOptions::GetBaton () 115 { 116 return m_callback_baton_sp.get(); 117 } 118 119 const Baton * 120 WatchpointOptions::GetBaton () const 121 { 122 return m_callback_baton_sp.get(); 123 } 124 125 bool 126 WatchpointOptions::InvokeCallback (StoppointCallbackContext *context, 127 lldb::user_id_t watch_id) 128 { 129 if (m_callback && context->is_synchronous == IsCallbackSynchronous()) 130 { 131 return m_callback (m_callback_baton_sp ? m_callback_baton_sp->m_data : NULL, 132 context, 133 watch_id); 134 } 135 else 136 return true; 137 } 138 139 bool 140 WatchpointOptions::HasCallback () 141 { 142 return m_callback != WatchpointOptions::NullCallback; 143 } 144 145 const ThreadSpec * 146 WatchpointOptions::GetThreadSpecNoCreate () const 147 { 148 return m_thread_spec_ap.get(); 149 } 150 151 ThreadSpec * 152 WatchpointOptions::GetThreadSpec () 153 { 154 if (m_thread_spec_ap.get() == NULL) 155 m_thread_spec_ap.reset (new ThreadSpec()); 156 157 return m_thread_spec_ap.get(); 158 } 159 160 void 161 WatchpointOptions::SetThreadID (lldb::tid_t thread_id) 162 { 163 GetThreadSpec()->SetTID(thread_id); 164 } 165 166 void 167 WatchpointOptions::GetCallbackDescription (Stream *s, lldb::DescriptionLevel level) const 168 { 169 if (m_callback_baton_sp.get()) 170 { 171 s->EOL(); 172 m_callback_baton_sp->GetDescription (s, level); 173 } 174 } 175 void 176 WatchpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const 177 { 178 179 // Figure out if there are any options not at their default value, and only print 180 // anything if there are: 181 182 if ((GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ())) 183 { 184 if (level == lldb::eDescriptionLevelVerbose) 185 { 186 s->EOL (); 187 s->IndentMore(); 188 s->Indent(); 189 s->PutCString("Watchpoint Options:\n"); 190 s->IndentMore(); 191 s->Indent(); 192 } 193 else 194 s->PutCString(" Options: "); 195 196 if (m_thread_spec_ap.get()) 197 m_thread_spec_ap->GetDescription (s, level); 198 else if (level == eDescriptionLevelBrief) 199 s->PutCString ("thread spec: no "); 200 if (level == lldb::eDescriptionLevelFull) 201 { 202 s->IndentLess(); 203 s->IndentMore(); 204 } 205 } 206 207 GetCallbackDescription(s, level); 208 } 209 210 void 211 WatchpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const 212 { 213 CommandData *data = (CommandData *)m_data; 214 215 if (level == eDescriptionLevelBrief) 216 { 217 s->Printf (", commands = %s", (data && data->user_source.GetSize() > 0) ? "yes" : "no"); 218 return; 219 } 220 221 s->IndentMore (); 222 s->Indent("watchpoint commands:\n"); 223 224 s->IndentMore (); 225 if (data && data->user_source.GetSize() > 0) 226 { 227 const size_t num_strings = data->user_source.GetSize(); 228 for (size_t i = 0; i < num_strings; ++i) 229 { 230 s->Indent(data->user_source.GetStringAtIndex(i)); 231 s->EOL(); 232 } 233 } 234 else 235 { 236 s->PutCString ("No commands.\n"); 237 } 238 s->IndentLess (); 239 s->IndentLess (); 240 } 241 242