1254721Semaste//===-- BreakpointOptions.cpp -----------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Breakpoint/BreakpointOptions.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste// Project includes 16254721Semaste#include "lldb/Core/Stream.h" 17254721Semaste#include "lldb/Core/StringList.h" 18254721Semaste#include "lldb/Core/Value.h" 19254721Semaste#include "lldb/Breakpoint/StoppointCallbackContext.h" 20254721Semaste#include "lldb/Target/Process.h" 21254721Semaste#include "lldb/Target/Target.h" 22254721Semaste#include "lldb/Target/ThreadSpec.h" 23254721Semaste#include "lldb/Expression/ClangUserExpression.h" 24254721Semaste 25254721Semasteusing namespace lldb; 26254721Semasteusing namespace lldb_private; 27254721Semaste 28254721Semastebool 29254721SemasteBreakpointOptions::NullCallback (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 30254721Semaste{ 31254721Semaste return true; 32254721Semaste} 33254721Semaste 34254721Semaste//---------------------------------------------------------------------- 35254721Semaste// BreakpointOptions constructor 36254721Semaste//---------------------------------------------------------------------- 37254721SemasteBreakpointOptions::BreakpointOptions() : 38254721Semaste m_callback (BreakpointOptions::NullCallback), 39254721Semaste m_callback_baton_sp (), 40254721Semaste m_callback_is_synchronous (false), 41254721Semaste m_enabled (true), 42254721Semaste m_one_shot (false), 43254721Semaste m_ignore_count (0), 44254721Semaste m_thread_spec_ap (), 45254721Semaste m_condition_text (), 46254721Semaste m_condition_text_hash (0) 47254721Semaste{ 48254721Semaste} 49254721Semaste 50254721Semaste//---------------------------------------------------------------------- 51254721Semaste// BreakpointOptions copy constructor 52254721Semaste//---------------------------------------------------------------------- 53254721SemasteBreakpointOptions::BreakpointOptions(const BreakpointOptions& rhs) : 54254721Semaste m_callback (rhs.m_callback), 55254721Semaste m_callback_baton_sp (rhs.m_callback_baton_sp), 56254721Semaste m_callback_is_synchronous (rhs.m_callback_is_synchronous), 57254721Semaste m_enabled (rhs.m_enabled), 58254721Semaste m_one_shot (rhs.m_one_shot), 59254721Semaste m_ignore_count (rhs.m_ignore_count), 60254721Semaste m_thread_spec_ap () 61254721Semaste{ 62254721Semaste if (rhs.m_thread_spec_ap.get() != NULL) 63254721Semaste m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get())); 64254721Semaste m_condition_text = rhs.m_condition_text; 65254721Semaste m_condition_text_hash = rhs.m_condition_text_hash; 66254721Semaste} 67254721Semaste 68254721Semaste//---------------------------------------------------------------------- 69254721Semaste// BreakpointOptions assignment operator 70254721Semaste//---------------------------------------------------------------------- 71254721Semasteconst BreakpointOptions& 72254721SemasteBreakpointOptions::operator=(const BreakpointOptions& rhs) 73254721Semaste{ 74254721Semaste m_callback = rhs.m_callback; 75254721Semaste m_callback_baton_sp = rhs.m_callback_baton_sp; 76254721Semaste m_callback_is_synchronous = rhs.m_callback_is_synchronous; 77254721Semaste m_enabled = rhs.m_enabled; 78254721Semaste m_one_shot = rhs.m_one_shot; 79254721Semaste m_ignore_count = rhs.m_ignore_count; 80254721Semaste if (rhs.m_thread_spec_ap.get() != NULL) 81254721Semaste m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); 82254721Semaste m_condition_text = rhs.m_condition_text; 83254721Semaste m_condition_text_hash = rhs.m_condition_text_hash; 84254721Semaste return *this; 85254721Semaste} 86254721Semaste 87254721SemasteBreakpointOptions * 88254721SemasteBreakpointOptions::CopyOptionsNoCallback (BreakpointOptions &orig) 89254721Semaste{ 90254721Semaste BreakpointHitCallback orig_callback = orig.m_callback; 91254721Semaste lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp; 92254721Semaste bool orig_is_sync = orig.m_callback_is_synchronous; 93254721Semaste 94254721Semaste orig.ClearCallback(); 95254721Semaste BreakpointOptions *ret_val = new BreakpointOptions(orig); 96254721Semaste 97254721Semaste orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync); 98254721Semaste 99254721Semaste return ret_val; 100254721Semaste} 101254721Semaste 102254721Semaste//---------------------------------------------------------------------- 103254721Semaste// Destructor 104254721Semaste//---------------------------------------------------------------------- 105254721SemasteBreakpointOptions::~BreakpointOptions() 106254721Semaste{ 107254721Semaste} 108254721Semaste 109254721Semaste//------------------------------------------------------------------ 110254721Semaste// Callbacks 111254721Semaste//------------------------------------------------------------------ 112254721Semastevoid 113254721SemasteBreakpointOptions::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool callback_is_synchronous) 114254721Semaste{ 115254721Semaste m_callback_is_synchronous = callback_is_synchronous; 116254721Semaste m_callback = callback; 117254721Semaste m_callback_baton_sp = callback_baton_sp; 118254721Semaste} 119254721Semaste 120254721Semastevoid 121254721SemasteBreakpointOptions::ClearCallback () 122254721Semaste{ 123254721Semaste m_callback = BreakpointOptions::NullCallback; 124254721Semaste m_callback_is_synchronous = false; 125254721Semaste m_callback_baton_sp.reset(); 126254721Semaste} 127254721Semaste 128254721SemasteBaton * 129254721SemasteBreakpointOptions::GetBaton () 130254721Semaste{ 131254721Semaste return m_callback_baton_sp.get(); 132254721Semaste} 133254721Semaste 134254721Semasteconst Baton * 135254721SemasteBreakpointOptions::GetBaton () const 136254721Semaste{ 137254721Semaste return m_callback_baton_sp.get(); 138254721Semaste} 139254721Semaste 140254721Semastebool 141254721SemasteBreakpointOptions::InvokeCallback (StoppointCallbackContext *context, 142254721Semaste lldb::user_id_t break_id, 143254721Semaste lldb::user_id_t break_loc_id) 144254721Semaste{ 145254721Semaste if (m_callback && context->is_synchronous == IsCallbackSynchronous()) 146254721Semaste { 147254721Semaste return m_callback (m_callback_baton_sp ? m_callback_baton_sp->m_data : NULL, 148254721Semaste context, 149254721Semaste break_id, 150254721Semaste break_loc_id); 151254721Semaste } 152254721Semaste else 153254721Semaste return true; 154254721Semaste} 155254721Semaste 156254721Semastebool 157254721SemasteBreakpointOptions::HasCallback () 158254721Semaste{ 159254721Semaste return m_callback != BreakpointOptions::NullCallback; 160254721Semaste} 161254721Semaste 162254721Semastevoid 163254721SemasteBreakpointOptions::SetCondition (const char *condition) 164254721Semaste{ 165254721Semaste if (!condition) 166254721Semaste condition = ""; 167254721Semaste 168254721Semaste m_condition_text.assign(condition); 169254721Semaste std::hash<std::string> hasher; 170254721Semaste m_condition_text_hash = hasher(m_condition_text); 171254721Semaste} 172254721Semaste 173254721Semasteconst char * 174254721SemasteBreakpointOptions::GetConditionText (size_t *hash) const 175254721Semaste{ 176254721Semaste if (!m_condition_text.empty()) 177254721Semaste { 178254721Semaste if (hash) 179254721Semaste *hash = m_condition_text_hash; 180254721Semaste 181254721Semaste return m_condition_text.c_str(); 182254721Semaste } 183254721Semaste else 184254721Semaste { 185254721Semaste return NULL; 186254721Semaste } 187254721Semaste} 188254721Semaste 189254721Semasteconst ThreadSpec * 190254721SemasteBreakpointOptions::GetThreadSpecNoCreate () const 191254721Semaste{ 192254721Semaste return m_thread_spec_ap.get(); 193254721Semaste} 194254721Semaste 195254721SemasteThreadSpec * 196254721SemasteBreakpointOptions::GetThreadSpec () 197254721Semaste{ 198254721Semaste if (m_thread_spec_ap.get() == NULL) 199254721Semaste m_thread_spec_ap.reset (new ThreadSpec()); 200254721Semaste 201254721Semaste return m_thread_spec_ap.get(); 202254721Semaste} 203254721Semaste 204254721Semastevoid 205254721SemasteBreakpointOptions::SetThreadID (lldb::tid_t thread_id) 206254721Semaste{ 207254721Semaste GetThreadSpec()->SetTID(thread_id); 208254721Semaste} 209254721Semaste 210254721Semastevoid 211254721SemasteBreakpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const 212254721Semaste{ 213254721Semaste 214254721Semaste // Figure out if there are any options not at their default value, and only print 215254721Semaste // anything if there are: 216254721Semaste 217254721Semaste if (m_ignore_count != 0 || !m_enabled || m_one_shot || (GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ())) 218254721Semaste { 219254721Semaste if (level == lldb::eDescriptionLevelVerbose) 220254721Semaste { 221254721Semaste s->EOL (); 222254721Semaste s->IndentMore(); 223254721Semaste s->Indent(); 224254721Semaste s->PutCString("Breakpoint Options:\n"); 225254721Semaste s->IndentMore(); 226254721Semaste s->Indent(); 227254721Semaste } 228254721Semaste else 229254721Semaste s->PutCString(" Options: "); 230254721Semaste 231254721Semaste if (m_ignore_count > 0) 232254721Semaste s->Printf("ignore: %d ", m_ignore_count); 233254721Semaste s->Printf("%sabled ", m_enabled ? "en" : "dis"); 234254721Semaste 235254721Semaste if (m_one_shot) 236254721Semaste s->Printf ("one-shot "); 237254721Semaste 238254721Semaste if (m_thread_spec_ap.get()) 239254721Semaste m_thread_spec_ap->GetDescription (s, level); 240254721Semaste else if (level == eDescriptionLevelBrief) 241254721Semaste s->PutCString ("thread spec: no "); 242254721Semaste if (level == lldb::eDescriptionLevelFull) 243254721Semaste { 244254721Semaste s->IndentLess(); 245254721Semaste s->IndentMore(); 246254721Semaste } 247254721Semaste } 248254721Semaste 249254721Semaste if (m_callback_baton_sp.get()) 250254721Semaste { 251254721Semaste if (level != eDescriptionLevelBrief) 252254721Semaste { 253254721Semaste s->EOL(); 254254721Semaste m_callback_baton_sp->GetDescription (s, level); 255254721Semaste } 256254721Semaste } 257254721Semaste if (!m_condition_text.empty()) 258254721Semaste { 259254721Semaste if (level != eDescriptionLevelBrief) 260254721Semaste { 261254721Semaste s->EOL(); 262254721Semaste s->Printf("Condition: %s\n", m_condition_text.c_str()); 263254721Semaste } 264254721Semaste } 265254721Semaste} 266254721Semaste 267254721Semastevoid 268254721SemasteBreakpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const 269254721Semaste{ 270254721Semaste CommandData *data = (CommandData *)m_data; 271254721Semaste 272254721Semaste if (level == eDescriptionLevelBrief) 273254721Semaste { 274254721Semaste s->Printf (", commands = %s", (data && data->user_source.GetSize() > 0) ? "yes" : "no"); 275254721Semaste return; 276254721Semaste } 277254721Semaste 278254721Semaste s->IndentMore (); 279254721Semaste s->Indent("Breakpoint commands:\n"); 280254721Semaste 281254721Semaste s->IndentMore (); 282254721Semaste if (data && data->user_source.GetSize() > 0) 283254721Semaste { 284254721Semaste const size_t num_strings = data->user_source.GetSize(); 285254721Semaste for (size_t i = 0; i < num_strings; ++i) 286254721Semaste { 287254721Semaste s->Indent(data->user_source.GetStringAtIndex(i)); 288254721Semaste s->EOL(); 289254721Semaste } 290254721Semaste } 291254721Semaste else 292254721Semaste { 293254721Semaste s->PutCString ("No commands.\n"); 294254721Semaste } 295254721Semaste s->IndentLess (); 296254721Semaste s->IndentLess (); 297254721Semaste} 298254721Semaste 299