1 //===-- BreakpointOptions.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/BreakpointOptions.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 BreakpointOptions::NullCallback (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 29 { 30 return true; 31 } 32 33 //---------------------------------------------------------------------- 34 // BreakpointOptions constructor 35 //---------------------------------------------------------------------- 36 BreakpointOptions::BreakpointOptions() : 37 m_callback (BreakpointOptions::NullCallback), 38 m_callback_baton_sp (), 39 m_callback_is_synchronous (false), 40 m_enabled (true), 41 m_one_shot (false), 42 m_ignore_count (0), 43 m_thread_spec_ap (), 44 m_condition_text (), 45 m_condition_text_hash (0) 46 { 47 } 48 49 //---------------------------------------------------------------------- 50 // BreakpointOptions copy constructor 51 //---------------------------------------------------------------------- 52 BreakpointOptions::BreakpointOptions(const BreakpointOptions& rhs) : 53 m_callback (rhs.m_callback), 54 m_callback_baton_sp (rhs.m_callback_baton_sp), 55 m_callback_is_synchronous (rhs.m_callback_is_synchronous), 56 m_enabled (rhs.m_enabled), 57 m_one_shot (rhs.m_one_shot), 58 m_ignore_count (rhs.m_ignore_count), 59 m_thread_spec_ap () 60 { 61 if (rhs.m_thread_spec_ap.get() != NULL) 62 m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get())); 63 m_condition_text = rhs.m_condition_text; 64 m_condition_text_hash = rhs.m_condition_text_hash; 65 } 66 67 //---------------------------------------------------------------------- 68 // BreakpointOptions assignment operator 69 //---------------------------------------------------------------------- 70 const BreakpointOptions& 71 BreakpointOptions::operator=(const BreakpointOptions& rhs) 72 { 73 m_callback = rhs.m_callback; 74 m_callback_baton_sp = rhs.m_callback_baton_sp; 75 m_callback_is_synchronous = rhs.m_callback_is_synchronous; 76 m_enabled = rhs.m_enabled; 77 m_one_shot = rhs.m_one_shot; 78 m_ignore_count = rhs.m_ignore_count; 79 if (rhs.m_thread_spec_ap.get() != NULL) 80 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); 81 m_condition_text = rhs.m_condition_text; 82 m_condition_text_hash = rhs.m_condition_text_hash; 83 return *this; 84 } 85 86 BreakpointOptions * 87 BreakpointOptions::CopyOptionsNoCallback (BreakpointOptions &orig) 88 { 89 BreakpointHitCallback orig_callback = orig.m_callback; 90 lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp; 91 bool orig_is_sync = orig.m_callback_is_synchronous; 92 93 orig.ClearCallback(); 94 BreakpointOptions *ret_val = new BreakpointOptions(orig); 95 96 orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync); 97 98 return ret_val; 99 } 100 101 //---------------------------------------------------------------------- 102 // Destructor 103 //---------------------------------------------------------------------- 104 BreakpointOptions::~BreakpointOptions() 105 { 106 } 107 108 //------------------------------------------------------------------ 109 // Callbacks 110 //------------------------------------------------------------------ 111 void 112 BreakpointOptions::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool callback_is_synchronous) 113 { 114 m_callback_is_synchronous = callback_is_synchronous; 115 m_callback = callback; 116 m_callback_baton_sp = callback_baton_sp; 117 } 118 119 void 120 BreakpointOptions::ClearCallback () 121 { 122 m_callback = BreakpointOptions::NullCallback; 123 m_callback_is_synchronous = false; 124 m_callback_baton_sp.reset(); 125 } 126 127 Baton * 128 BreakpointOptions::GetBaton () 129 { 130 return m_callback_baton_sp.get(); 131 } 132 133 const Baton * 134 BreakpointOptions::GetBaton () const 135 { 136 return m_callback_baton_sp.get(); 137 } 138 139 bool 140 BreakpointOptions::InvokeCallback (StoppointCallbackContext *context, 141 lldb::user_id_t break_id, 142 lldb::user_id_t break_loc_id) 143 { 144 if (m_callback && context->is_synchronous == IsCallbackSynchronous()) 145 { 146 return m_callback (m_callback_baton_sp ? m_callback_baton_sp->m_data : NULL, 147 context, 148 break_id, 149 break_loc_id); 150 } 151 else 152 return true; 153 } 154 155 bool 156 BreakpointOptions::HasCallback () const 157 { 158 return m_callback != BreakpointOptions::NullCallback; 159 } 160 161 void 162 BreakpointOptions::SetCondition (const char *condition) 163 { 164 if (!condition) 165 condition = ""; 166 167 m_condition_text.assign(condition); 168 std::hash<std::string> hasher; 169 m_condition_text_hash = hasher(m_condition_text); 170 } 171 172 const char * 173 BreakpointOptions::GetConditionText (size_t *hash) const 174 { 175 if (!m_condition_text.empty()) 176 { 177 if (hash) 178 *hash = m_condition_text_hash; 179 180 return m_condition_text.c_str(); 181 } 182 else 183 { 184 return NULL; 185 } 186 } 187 188 const ThreadSpec * 189 BreakpointOptions::GetThreadSpecNoCreate () const 190 { 191 return m_thread_spec_ap.get(); 192 } 193 194 ThreadSpec * 195 BreakpointOptions::GetThreadSpec () 196 { 197 if (m_thread_spec_ap.get() == NULL) 198 m_thread_spec_ap.reset (new ThreadSpec()); 199 200 return m_thread_spec_ap.get(); 201 } 202 203 void 204 BreakpointOptions::SetThreadID (lldb::tid_t thread_id) 205 { 206 GetThreadSpec()->SetTID(thread_id); 207 } 208 209 void 210 BreakpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const 211 { 212 213 // Figure out if there are any options not at their default value, and only print 214 // anything if there are: 215 216 if (m_ignore_count != 0 || !m_enabled || m_one_shot || (GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ())) 217 { 218 if (level == lldb::eDescriptionLevelVerbose) 219 { 220 s->EOL (); 221 s->IndentMore(); 222 s->Indent(); 223 s->PutCString("Breakpoint Options:\n"); 224 s->IndentMore(); 225 s->Indent(); 226 } 227 else 228 s->PutCString(" Options: "); 229 230 if (m_ignore_count > 0) 231 s->Printf("ignore: %d ", m_ignore_count); 232 s->Printf("%sabled ", m_enabled ? "en" : "dis"); 233 234 if (m_one_shot) 235 s->Printf ("one-shot "); 236 237 if (m_thread_spec_ap.get()) 238 m_thread_spec_ap->GetDescription (s, level); 239 240 if (level == lldb::eDescriptionLevelFull) 241 { 242 s->IndentLess(); 243 s->IndentMore(); 244 } 245 } 246 247 if (m_callback_baton_sp.get()) 248 { 249 if (level != eDescriptionLevelBrief) 250 { 251 s->EOL(); 252 m_callback_baton_sp->GetDescription (s, level); 253 } 254 } 255 if (!m_condition_text.empty()) 256 { 257 if (level != eDescriptionLevelBrief) 258 { 259 s->EOL(); 260 s->Printf("Condition: %s\n", m_condition_text.c_str()); 261 } 262 } 263 } 264 265 void 266 BreakpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const 267 { 268 CommandData *data = (CommandData *)m_data; 269 270 if (level == eDescriptionLevelBrief) 271 { 272 s->Printf (", commands = %s", (data && data->user_source.GetSize() > 0) ? "yes" : "no"); 273 return; 274 } 275 276 s->IndentMore (); 277 s->Indent("Breakpoint commands:\n"); 278 279 s->IndentMore (); 280 if (data && data->user_source.GetSize() > 0) 281 { 282 const size_t num_strings = data->user_source.GetSize(); 283 for (size_t i = 0; i < num_strings; ++i) 284 { 285 s->Indent(data->user_source.GetStringAtIndex(i)); 286 s->EOL(); 287 } 288 } 289 else 290 { 291 s->PutCString ("No commands.\n"); 292 } 293 s->IndentLess (); 294 s->IndentLess (); 295 } 296 297