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