1255801Sdes//===-- BreakpointOptions.cpp -----------------------------------*- C++ -*-===// 2255801Sdes// 3255801Sdes// The LLVM Compiler Infrastructure 4255801Sdes// 5255801Sdes// This file is distributed under the University of Illinois Open Source 6255801Sdes// License. See LICENSE.TXT for details. 7255801Sdes// 8255801Sdes//===----------------------------------------------------------------------===// 9255801Sdes 10255801Sdes#include "lldb/Breakpoint/BreakpointOptions.h" 11255801Sdes 12255801Sdes// C Includes 13255801Sdes// C++ Includes 14255801Sdes// Other libraries and framework includes 15255801Sdes// Project includes 16255801Sdes#include "lldb/Core/Stream.h" 17255801Sdes#include "lldb/Core/StringList.h" 18255801Sdes#include "lldb/Core/Value.h" 19255801Sdes#include "lldb/Breakpoint/StoppointCallbackContext.h" 20255801Sdes#include "lldb/Target/Process.h" 21255801Sdes#include "lldb/Target/Target.h" 22255801Sdes#include "lldb/Target/ThreadSpec.h" 23255801Sdes#include "lldb/Expression/ClangUserExpression.h" 24255801Sdes 25255801Sdesusing namespace lldb; 26255801Sdesusing namespace lldb_private; 27255801Sdes 28255801Sdesbool 29255801SdesBreakpointOptions::NullCallback (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 30255801Sdes{ 31255801Sdes return true; 32255801Sdes} 33255801Sdes 34255801Sdes//---------------------------------------------------------------------- 35255801Sdes// BreakpointOptions constructor 36255801Sdes//---------------------------------------------------------------------- 37255801SdesBreakpointOptions::BreakpointOptions() : 38255801Sdes m_callback (BreakpointOptions::NullCallback), 39255801Sdes m_callback_baton_sp (), 40255801Sdes m_callback_is_synchronous (false), 41255801Sdes m_enabled (true), 42255801Sdes m_one_shot (false), 43255801Sdes m_ignore_count (0), 44255801Sdes m_thread_spec_ap (), 45255801Sdes m_condition_text (), 46255801Sdes m_condition_text_hash (0) 47255801Sdes{ 48255801Sdes} 49255801Sdes 50255801Sdes//---------------------------------------------------------------------- 51255801Sdes// BreakpointOptions copy constructor 52255801Sdes//---------------------------------------------------------------------- 53255801SdesBreakpointOptions::BreakpointOptions(const BreakpointOptions& rhs) : 54255801Sdes m_callback (rhs.m_callback), 55255801Sdes m_callback_baton_sp (rhs.m_callback_baton_sp), 56255801Sdes m_callback_is_synchronous (rhs.m_callback_is_synchronous), 57255801Sdes m_enabled (rhs.m_enabled), 58255801Sdes m_one_shot (rhs.m_one_shot), 59255801Sdes m_ignore_count (rhs.m_ignore_count), 60255801Sdes m_thread_spec_ap () 61255801Sdes{ 62255801Sdes if (rhs.m_thread_spec_ap.get() != NULL) 63255801Sdes m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get())); 64255801Sdes m_condition_text = rhs.m_condition_text; 65255801Sdes m_condition_text_hash = rhs.m_condition_text_hash; 66255801Sdes} 67255801Sdes 68255801Sdes//---------------------------------------------------------------------- 69255801Sdes// BreakpointOptions assignment operator 70255801Sdes//---------------------------------------------------------------------- 71255801Sdesconst BreakpointOptions& 72255801SdesBreakpointOptions::operator=(const BreakpointOptions& rhs) 73255801Sdes{ 74255801Sdes m_callback = rhs.m_callback; 75255801Sdes m_callback_baton_sp = rhs.m_callback_baton_sp; 76255801Sdes m_callback_is_synchronous = rhs.m_callback_is_synchronous; 77255801Sdes m_enabled = rhs.m_enabled; 78255801Sdes m_one_shot = rhs.m_one_shot; 79255801Sdes m_ignore_count = rhs.m_ignore_count; 80255801Sdes if (rhs.m_thread_spec_ap.get() != NULL) 81255801Sdes m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); 82255801Sdes m_condition_text = rhs.m_condition_text; 83255801Sdes m_condition_text_hash = rhs.m_condition_text_hash; 84255801Sdes return *this; 85255801Sdes} 86255801Sdes 87255801SdesBreakpointOptions * 88255801SdesBreakpointOptions::CopyOptionsNoCallback (BreakpointOptions &orig) 89255801Sdes{ 90255801Sdes BreakpointHitCallback orig_callback = orig.m_callback; 91255801Sdes lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp; 92255801Sdes bool orig_is_sync = orig.m_callback_is_synchronous; 93255801Sdes 94255801Sdes orig.ClearCallback(); 95255801Sdes BreakpointOptions *ret_val = new BreakpointOptions(orig); 96255801Sdes 97255801Sdes orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync); 98255801Sdes 99255801Sdes return ret_val; 100255801Sdes} 101255801Sdes 102255801Sdes//---------------------------------------------------------------------- 103255801Sdes// Destructor 104255801Sdes//---------------------------------------------------------------------- 105255801SdesBreakpointOptions::~BreakpointOptions() 106255801Sdes{ 107255801Sdes} 108255801Sdes 109255801Sdes//------------------------------------------------------------------ 110255801Sdes// Callbacks 111255801Sdes//------------------------------------------------------------------ 112255801Sdesvoid 113255801SdesBreakpointOptions::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool callback_is_synchronous) 114255801Sdes{ 115255801Sdes m_callback_is_synchronous = callback_is_synchronous; 116255801Sdes m_callback = callback; 117255801Sdes m_callback_baton_sp = callback_baton_sp; 118255801Sdes} 119255801Sdes 120255801Sdesvoid 121255801SdesBreakpointOptions::ClearCallback () 122255801Sdes{ 123255801Sdes m_callback = BreakpointOptions::NullCallback; 124255801Sdes m_callback_is_synchronous = false; 125255801Sdes m_callback_baton_sp.reset(); 126255801Sdes} 127255801Sdes 128255801SdesBaton * 129255801SdesBreakpointOptions::GetBaton () 130255801Sdes{ 131255801Sdes return m_callback_baton_sp.get(); 132255801Sdes} 133255801Sdes 134255801Sdesconst Baton * 135255801SdesBreakpointOptions::GetBaton () const 136255801Sdes{ 137255801Sdes return m_callback_baton_sp.get(); 138255801Sdes} 139255801Sdes 140255801Sdesbool 141255801SdesBreakpointOptions::InvokeCallback (StoppointCallbackContext *context, 142255801Sdes lldb::user_id_t break_id, 143255801Sdes lldb::user_id_t break_loc_id) 144255801Sdes{ 145255801Sdes if (m_callback && context->is_synchronous == IsCallbackSynchronous()) 146255801Sdes { 147255801Sdes return m_callback (m_callback_baton_sp ? m_callback_baton_sp->m_data : NULL, 148255801Sdes context, 149255801Sdes break_id, 150255801Sdes break_loc_id); 151255801Sdes } 152255801Sdes else 153255801Sdes return true; 154255801Sdes} 155255801Sdes 156255801Sdesbool 157255801SdesBreakpointOptions::HasCallback () 158255801Sdes{ 159255801Sdes return m_callback != BreakpointOptions::NullCallback; 160255801Sdes} 161255801Sdes 162255801Sdesvoid 163255801SdesBreakpointOptions::SetCondition (const char *condition) 164255801Sdes{ 165255801Sdes if (!condition) 166255801Sdes condition = ""; 167255801Sdes 168255801Sdes m_condition_text.assign(condition); 169255801Sdes std::hash<std::string> hasher; 170255801Sdes m_condition_text_hash = hasher(m_condition_text); 171255801Sdes} 172255801Sdes 173255801Sdesconst char * 174255801SdesBreakpointOptions::GetConditionText (size_t *hash) const 175255801Sdes{ 176255801Sdes if (!m_condition_text.empty()) 177255801Sdes { 178255801Sdes if (hash) 179255801Sdes *hash = m_condition_text_hash; 180255801Sdes 181255801Sdes return m_condition_text.c_str(); 182255801Sdes } 183255801Sdes else 184255801Sdes { 185255801Sdes return NULL; 186255801Sdes } 187255801Sdes} 188255801Sdes 189255801Sdesconst ThreadSpec * 190255801SdesBreakpointOptions::GetThreadSpecNoCreate () const 191255801Sdes{ 192255801Sdes return m_thread_spec_ap.get(); 193255801Sdes} 194255801Sdes 195255801SdesThreadSpec * 196255801SdesBreakpointOptions::GetThreadSpec () 197255801Sdes{ 198255801Sdes if (m_thread_spec_ap.get() == NULL) 199255801Sdes m_thread_spec_ap.reset (new ThreadSpec()); 200255801Sdes 201255801Sdes return m_thread_spec_ap.get(); 202255801Sdes} 203255801Sdes 204255801Sdesvoid 205255801SdesBreakpointOptions::SetThreadID (lldb::tid_t thread_id) 206255801Sdes{ 207255801Sdes GetThreadSpec()->SetTID(thread_id); 208255801Sdes} 209255801Sdes 210255801Sdesvoid 211255801SdesBreakpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const 212255801Sdes{ 213255801Sdes 214255801Sdes // Figure out if there are any options not at their default value, and only print 215255801Sdes // anything if there are: 216255801Sdes 217255801Sdes if (m_ignore_count != 0 || !m_enabled || m_one_shot || (GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ())) 218255801Sdes { 219255801Sdes if (level == lldb::eDescriptionLevelVerbose) 220255801Sdes { 221255801Sdes s->EOL (); 222255801Sdes s->IndentMore(); 223255801Sdes s->Indent(); 224255801Sdes s->PutCString("Breakpoint Options:\n"); 225255801Sdes s->IndentMore(); 226255801Sdes s->Indent(); 227255801Sdes } 228255801Sdes else 229255801Sdes s->PutCString(" Options: "); 230255801Sdes 231255801Sdes if (m_ignore_count > 0) 232255801Sdes s->Printf("ignore: %d ", m_ignore_count); 233255801Sdes s->Printf("%sabled ", m_enabled ? "en" : "dis"); 234255801Sdes 235255801Sdes if (m_one_shot) 236255801Sdes s->Printf ("one-shot "); 237255801Sdes 238255801Sdes if (m_thread_spec_ap.get()) 239255801Sdes m_thread_spec_ap->GetDescription (s, level); 240255801Sdes else if (level == eDescriptionLevelBrief) 241255801Sdes s->PutCString ("thread spec: no "); 242255801Sdes if (level == lldb::eDescriptionLevelFull) 243255801Sdes { 244255801Sdes s->IndentLess(); 245255801Sdes s->IndentMore(); 246255801Sdes } 247255801Sdes } 248255801Sdes 249255801Sdes if (m_callback_baton_sp.get()) 250255801Sdes { 251255801Sdes if (level != eDescriptionLevelBrief) 252255801Sdes { 253255801Sdes s->EOL(); 254255801Sdes m_callback_baton_sp->GetDescription (s, level); 255255801Sdes } 256255801Sdes } 257255801Sdes if (!m_condition_text.empty()) 258255801Sdes { 259255801Sdes if (level != eDescriptionLevelBrief) 260255801Sdes { 261255801Sdes s->EOL(); 262255801Sdes s->Printf("Condition: %s\n", m_condition_text.c_str()); 263255801Sdes } 264255801Sdes } 265255801Sdes} 266255801Sdes 267255801Sdesvoid 268255801SdesBreakpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const 269255801Sdes{ 270255801Sdes CommandData *data = (CommandData *)m_data; 271255801Sdes 272255801Sdes if (level == eDescriptionLevelBrief) 273255801Sdes { 274255801Sdes s->Printf (", commands = %s", (data && data->user_source.GetSize() > 0) ? "yes" : "no"); 275255801Sdes return; 276255801Sdes } 277255801Sdes 278255801Sdes s->IndentMore (); 279255801Sdes s->Indent("Breakpoint commands:\n"); 280255801Sdes 281255801Sdes s->IndentMore (); 282255801Sdes if (data && data->user_source.GetSize() > 0) 283255801Sdes { 284255801Sdes const size_t num_strings = data->user_source.GetSize(); 285255801Sdes for (size_t i = 0; i < num_strings; ++i) 286255801Sdes { 287255801Sdes s->Indent(data->user_source.GetStringAtIndex(i)); 288255801Sdes s->EOL(); 289255801Sdes } 290255801Sdes } 291255801Sdes else 292255801Sdes { 293255801Sdes s->PutCString ("No commands.\n"); 294255801Sdes } 295255801Sdes s->IndentLess (); 296255801Sdes s->IndentLess (); 297255801Sdes} 298 299