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