1 //===-- SBBreakpointLocation.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/API/SBBreakpointLocation.h" 11 #include "lldb/API/SBAddress.h" 12 #include "lldb/API/SBDebugger.h" 13 #include "lldb/API/SBDefines.h" 14 #include "lldb/API/SBStream.h" 15 #include "lldb/API/SBStringList.h" 16 17 #include "lldb/Breakpoint/Breakpoint.h" 18 #include "lldb/Breakpoint/BreakpointLocation.h" 19 #include "lldb/Core/Debugger.h" 20 #include "lldb/Core/StreamFile.h" 21 #include "lldb/Interpreter/CommandInterpreter.h" 22 #include "lldb/Interpreter/ScriptInterpreter.h" 23 #include "lldb/Target/Target.h" 24 #include "lldb/Target/ThreadSpec.h" 25 #include "lldb/Utility/Log.h" 26 #include "lldb/Utility/Stream.h" 27 #include "lldb/lldb-defines.h" 28 #include "lldb/lldb-types.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 SBBreakpointLocation::SBBreakpointLocation() {} 34 35 SBBreakpointLocation::SBBreakpointLocation( 36 const lldb::BreakpointLocationSP &break_loc_sp) 37 : m_opaque_wp(break_loc_sp) { 38 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 39 40 if (log) { 41 SBStream sstr; 42 GetDescription(sstr, lldb::eDescriptionLevelBrief); 43 LLDB_LOG(log, "location = {0} ({1})", break_loc_sp.get(), sstr.GetData()); 44 } 45 } 46 47 SBBreakpointLocation::SBBreakpointLocation(const SBBreakpointLocation &rhs) 48 : m_opaque_wp(rhs.m_opaque_wp) {} 49 50 const SBBreakpointLocation &SBBreakpointLocation:: 51 operator=(const SBBreakpointLocation &rhs) { 52 m_opaque_wp = rhs.m_opaque_wp; 53 return *this; 54 } 55 56 SBBreakpointLocation::~SBBreakpointLocation() {} 57 58 BreakpointLocationSP SBBreakpointLocation::GetSP() const { 59 return m_opaque_wp.lock(); 60 } 61 62 bool SBBreakpointLocation::IsValid() const { return bool(GetSP()); } 63 64 SBAddress SBBreakpointLocation::GetAddress() { 65 BreakpointLocationSP loc_sp = GetSP(); 66 if (loc_sp) 67 return SBAddress(&loc_sp->GetAddress()); 68 else 69 return SBAddress(); 70 } 71 72 addr_t SBBreakpointLocation::GetLoadAddress() { 73 addr_t ret_addr = LLDB_INVALID_ADDRESS; 74 BreakpointLocationSP loc_sp = GetSP(); 75 76 if (loc_sp) { 77 std::lock_guard<std::recursive_mutex> guard( 78 loc_sp->GetTarget().GetAPIMutex()); 79 ret_addr = loc_sp->GetLoadAddress(); 80 } 81 82 return ret_addr; 83 } 84 85 void SBBreakpointLocation::SetEnabled(bool enabled) { 86 BreakpointLocationSP loc_sp = GetSP(); 87 if (loc_sp) { 88 std::lock_guard<std::recursive_mutex> guard( 89 loc_sp->GetTarget().GetAPIMutex()); 90 loc_sp->SetEnabled(enabled); 91 } 92 } 93 94 bool SBBreakpointLocation::IsEnabled() { 95 BreakpointLocationSP loc_sp = GetSP(); 96 if (loc_sp) { 97 std::lock_guard<std::recursive_mutex> guard( 98 loc_sp->GetTarget().GetAPIMutex()); 99 return loc_sp->IsEnabled(); 100 } else 101 return false; 102 } 103 104 uint32_t SBBreakpointLocation::GetHitCount() { 105 BreakpointLocationSP loc_sp = GetSP(); 106 if (loc_sp) { 107 std::lock_guard<std::recursive_mutex> guard( 108 loc_sp->GetTarget().GetAPIMutex()); 109 return loc_sp->GetHitCount(); 110 } else 111 return 0; 112 } 113 114 uint32_t SBBreakpointLocation::GetIgnoreCount() { 115 BreakpointLocationSP loc_sp = GetSP(); 116 if (loc_sp) { 117 std::lock_guard<std::recursive_mutex> guard( 118 loc_sp->GetTarget().GetAPIMutex()); 119 return loc_sp->GetIgnoreCount(); 120 } else 121 return 0; 122 } 123 124 void SBBreakpointLocation::SetIgnoreCount(uint32_t n) { 125 BreakpointLocationSP loc_sp = GetSP(); 126 if (loc_sp) { 127 std::lock_guard<std::recursive_mutex> guard( 128 loc_sp->GetTarget().GetAPIMutex()); 129 loc_sp->SetIgnoreCount(n); 130 } 131 } 132 133 void SBBreakpointLocation::SetCondition(const char *condition) { 134 BreakpointLocationSP loc_sp = GetSP(); 135 if (loc_sp) { 136 std::lock_guard<std::recursive_mutex> guard( 137 loc_sp->GetTarget().GetAPIMutex()); 138 loc_sp->SetCondition(condition); 139 } 140 } 141 142 const char *SBBreakpointLocation::GetCondition() { 143 BreakpointLocationSP loc_sp = GetSP(); 144 if (loc_sp) { 145 std::lock_guard<std::recursive_mutex> guard( 146 loc_sp->GetTarget().GetAPIMutex()); 147 return loc_sp->GetConditionText(); 148 } 149 return NULL; 150 } 151 152 void SBBreakpointLocation::SetScriptCallbackFunction( 153 const char *callback_function_name) { 154 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 155 BreakpointLocationSP loc_sp = GetSP(); 156 LLDB_LOG(log, "location = {0}, callback = {1}", loc_sp.get(), 157 callback_function_name); 158 159 if (loc_sp) { 160 std::lock_guard<std::recursive_mutex> guard( 161 loc_sp->GetTarget().GetAPIMutex()); 162 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 163 loc_sp->GetBreakpoint() 164 .GetTarget() 165 .GetDebugger() 166 .GetCommandInterpreter() 167 .GetScriptInterpreter() 168 ->SetBreakpointCommandCallbackFunction(bp_options, 169 callback_function_name); 170 } 171 } 172 173 SBError 174 SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) { 175 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 176 BreakpointLocationSP loc_sp = GetSP(); 177 LLDB_LOG(log, "location = {0}: callback body:\n{1}", loc_sp.get(), 178 callback_body_text); 179 180 SBError sb_error; 181 if (loc_sp) { 182 std::lock_guard<std::recursive_mutex> guard( 183 loc_sp->GetTarget().GetAPIMutex()); 184 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 185 Status error = 186 loc_sp->GetBreakpoint() 187 .GetTarget() 188 .GetDebugger() 189 .GetCommandInterpreter() 190 .GetScriptInterpreter() 191 ->SetBreakpointCommandCallback(bp_options, callback_body_text); 192 sb_error.SetError(error); 193 } else 194 sb_error.SetErrorString("invalid breakpoint"); 195 196 return sb_error; 197 } 198 199 void SBBreakpointLocation::SetCommandLineCommands(SBStringList &commands) { 200 BreakpointLocationSP loc_sp = GetSP(); 201 if (!loc_sp) 202 return; 203 if (commands.GetSize() == 0) 204 return; 205 206 std::lock_guard<std::recursive_mutex> guard( 207 loc_sp->GetTarget().GetAPIMutex()); 208 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( 209 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); 210 211 loc_sp->GetLocationOptions()->SetCommandDataCallback(cmd_data_up); 212 } 213 214 bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) { 215 BreakpointLocationSP loc_sp = GetSP(); 216 if (!loc_sp) 217 return false; 218 StringList command_list; 219 bool has_commands = 220 loc_sp->GetLocationOptions()->GetCommandLineCallbacks(command_list); 221 if (has_commands) 222 commands.AppendList(command_list); 223 return has_commands; 224 } 225 226 void SBBreakpointLocation::SetThreadID(tid_t thread_id) { 227 BreakpointLocationSP loc_sp = GetSP(); 228 if (loc_sp) { 229 std::lock_guard<std::recursive_mutex> guard( 230 loc_sp->GetTarget().GetAPIMutex()); 231 loc_sp->SetThreadID(thread_id); 232 } 233 } 234 235 tid_t SBBreakpointLocation::GetThreadID() { 236 tid_t tid = LLDB_INVALID_THREAD_ID; 237 BreakpointLocationSP loc_sp = GetSP(); 238 if (loc_sp) { 239 std::lock_guard<std::recursive_mutex> guard( 240 loc_sp->GetTarget().GetAPIMutex()); 241 return loc_sp->GetThreadID(); 242 } 243 return tid; 244 } 245 246 void SBBreakpointLocation::SetThreadIndex(uint32_t index) { 247 BreakpointLocationSP loc_sp = GetSP(); 248 if (loc_sp) { 249 std::lock_guard<std::recursive_mutex> guard( 250 loc_sp->GetTarget().GetAPIMutex()); 251 loc_sp->SetThreadIndex(index); 252 } 253 } 254 255 uint32_t SBBreakpointLocation::GetThreadIndex() const { 256 uint32_t thread_idx = UINT32_MAX; 257 BreakpointLocationSP loc_sp = GetSP(); 258 if (loc_sp) { 259 std::lock_guard<std::recursive_mutex> guard( 260 loc_sp->GetTarget().GetAPIMutex()); 261 return loc_sp->GetThreadIndex(); 262 } 263 return thread_idx; 264 } 265 266 void SBBreakpointLocation::SetThreadName(const char *thread_name) { 267 BreakpointLocationSP loc_sp = GetSP(); 268 if (loc_sp) { 269 std::lock_guard<std::recursive_mutex> guard( 270 loc_sp->GetTarget().GetAPIMutex()); 271 loc_sp->SetThreadName(thread_name); 272 } 273 } 274 275 const char *SBBreakpointLocation::GetThreadName() const { 276 BreakpointLocationSP loc_sp = GetSP(); 277 if (loc_sp) { 278 std::lock_guard<std::recursive_mutex> guard( 279 loc_sp->GetTarget().GetAPIMutex()); 280 return loc_sp->GetThreadName(); 281 } 282 return NULL; 283 } 284 285 void SBBreakpointLocation::SetQueueName(const char *queue_name) { 286 BreakpointLocationSP loc_sp = GetSP(); 287 if (loc_sp) { 288 std::lock_guard<std::recursive_mutex> guard( 289 loc_sp->GetTarget().GetAPIMutex()); 290 loc_sp->SetQueueName(queue_name); 291 } 292 } 293 294 const char *SBBreakpointLocation::GetQueueName() const { 295 BreakpointLocationSP loc_sp = GetSP(); 296 if (loc_sp) { 297 std::lock_guard<std::recursive_mutex> guard( 298 loc_sp->GetTarget().GetAPIMutex()); 299 loc_sp->GetQueueName(); 300 } 301 return NULL; 302 } 303 304 bool SBBreakpointLocation::IsResolved() { 305 BreakpointLocationSP loc_sp = GetSP(); 306 if (loc_sp) { 307 std::lock_guard<std::recursive_mutex> guard( 308 loc_sp->GetTarget().GetAPIMutex()); 309 return loc_sp->IsResolved(); 310 } 311 return false; 312 } 313 314 void SBBreakpointLocation::SetLocation( 315 const lldb::BreakpointLocationSP &break_loc_sp) { 316 // Uninstall the callbacks? 317 m_opaque_wp = break_loc_sp; 318 } 319 320 bool SBBreakpointLocation::GetDescription(SBStream &description, 321 DescriptionLevel level) { 322 Stream &strm = description.ref(); 323 BreakpointLocationSP loc_sp = GetSP(); 324 325 if (loc_sp) { 326 std::lock_guard<std::recursive_mutex> guard( 327 loc_sp->GetTarget().GetAPIMutex()); 328 loc_sp->GetDescription(&strm, level); 329 strm.EOL(); 330 } else 331 strm.PutCString("No value"); 332 333 return true; 334 } 335 336 break_id_t SBBreakpointLocation::GetID() { 337 BreakpointLocationSP loc_sp = GetSP(); 338 if (loc_sp) { 339 std::lock_guard<std::recursive_mutex> guard( 340 loc_sp->GetTarget().GetAPIMutex()); 341 return loc_sp->GetID(); 342 } else 343 return LLDB_INVALID_BREAK_ID; 344 } 345 346 SBBreakpoint SBBreakpointLocation::GetBreakpoint() { 347 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 348 BreakpointLocationSP loc_sp = GetSP(); 349 350 SBBreakpoint sb_bp; 351 if (loc_sp) { 352 std::lock_guard<std::recursive_mutex> guard( 353 loc_sp->GetTarget().GetAPIMutex()); 354 sb_bp = loc_sp->GetBreakpoint().shared_from_this(); 355 } 356 357 if (log) { 358 SBStream sstr; 359 sb_bp.GetDescription(sstr); 360 LLDB_LOG(log, "location = {0}, breakpoint = {1} ({2})", loc_sp.get(), 361 sb_bp.GetSP().get(), sstr.GetData()); 362 } 363 return sb_bp; 364 } 365