1 //===-- SBBreakpointLocation.cpp --------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/API/SBBreakpointLocation.h" 10 #include "SBReproducerPrivate.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/Stream.h" 26 #include "lldb/lldb-defines.h" 27 #include "lldb/lldb-types.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 SBBreakpointLocation::SBBreakpointLocation() { 33 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBreakpointLocation); 34 } 35 36 SBBreakpointLocation::SBBreakpointLocation( 37 const lldb::BreakpointLocationSP &break_loc_sp) 38 : m_opaque_wp(break_loc_sp) { 39 LLDB_RECORD_CONSTRUCTOR(SBBreakpointLocation, 40 (const lldb::BreakpointLocationSP &), break_loc_sp); 41 } 42 43 SBBreakpointLocation::SBBreakpointLocation(const SBBreakpointLocation &rhs) 44 : m_opaque_wp(rhs.m_opaque_wp) { 45 LLDB_RECORD_CONSTRUCTOR(SBBreakpointLocation, 46 (const lldb::SBBreakpointLocation &), rhs); 47 } 48 49 const SBBreakpointLocation &SBBreakpointLocation:: 50 operator=(const SBBreakpointLocation &rhs) { 51 LLDB_RECORD_METHOD( 52 const lldb::SBBreakpointLocation &, 53 SBBreakpointLocation, operator=,(const lldb::SBBreakpointLocation &), 54 rhs); 55 56 m_opaque_wp = rhs.m_opaque_wp; 57 return *this; 58 } 59 60 SBBreakpointLocation::~SBBreakpointLocation() {} 61 62 BreakpointLocationSP SBBreakpointLocation::GetSP() const { 63 return m_opaque_wp.lock(); 64 } 65 66 bool SBBreakpointLocation::IsValid() const { 67 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpointLocation, IsValid); 68 69 return bool(GetSP()); 70 } 71 72 SBAddress SBBreakpointLocation::GetAddress() { 73 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBBreakpointLocation, GetAddress); 74 75 BreakpointLocationSP loc_sp = GetSP(); 76 if (loc_sp) { 77 return LLDB_RECORD_RESULT(SBAddress(&loc_sp->GetAddress())); 78 } 79 80 return LLDB_RECORD_RESULT(SBAddress()); 81 } 82 83 addr_t SBBreakpointLocation::GetLoadAddress() { 84 LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBBreakpointLocation, 85 GetLoadAddress); 86 87 addr_t ret_addr = LLDB_INVALID_ADDRESS; 88 BreakpointLocationSP loc_sp = GetSP(); 89 90 if (loc_sp) { 91 std::lock_guard<std::recursive_mutex> guard( 92 loc_sp->GetTarget().GetAPIMutex()); 93 ret_addr = loc_sp->GetLoadAddress(); 94 } 95 96 return ret_addr; 97 } 98 99 void SBBreakpointLocation::SetEnabled(bool enabled) { 100 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetEnabled, (bool), enabled); 101 102 BreakpointLocationSP loc_sp = GetSP(); 103 if (loc_sp) { 104 std::lock_guard<std::recursive_mutex> guard( 105 loc_sp->GetTarget().GetAPIMutex()); 106 loc_sp->SetEnabled(enabled); 107 } 108 } 109 110 bool SBBreakpointLocation::IsEnabled() { 111 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, IsEnabled); 112 113 BreakpointLocationSP loc_sp = GetSP(); 114 if (loc_sp) { 115 std::lock_guard<std::recursive_mutex> guard( 116 loc_sp->GetTarget().GetAPIMutex()); 117 return loc_sp->IsEnabled(); 118 } else 119 return false; 120 } 121 122 uint32_t SBBreakpointLocation::GetHitCount() { 123 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBBreakpointLocation, GetHitCount); 124 125 BreakpointLocationSP loc_sp = GetSP(); 126 if (loc_sp) { 127 std::lock_guard<std::recursive_mutex> guard( 128 loc_sp->GetTarget().GetAPIMutex()); 129 return loc_sp->GetHitCount(); 130 } else 131 return 0; 132 } 133 134 uint32_t SBBreakpointLocation::GetIgnoreCount() { 135 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBBreakpointLocation, GetIgnoreCount); 136 137 BreakpointLocationSP loc_sp = GetSP(); 138 if (loc_sp) { 139 std::lock_guard<std::recursive_mutex> guard( 140 loc_sp->GetTarget().GetAPIMutex()); 141 return loc_sp->GetIgnoreCount(); 142 } else 143 return 0; 144 } 145 146 void SBBreakpointLocation::SetIgnoreCount(uint32_t n) { 147 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetIgnoreCount, (uint32_t), n); 148 149 BreakpointLocationSP loc_sp = GetSP(); 150 if (loc_sp) { 151 std::lock_guard<std::recursive_mutex> guard( 152 loc_sp->GetTarget().GetAPIMutex()); 153 loc_sp->SetIgnoreCount(n); 154 } 155 } 156 157 void SBBreakpointLocation::SetCondition(const char *condition) { 158 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetCondition, (const char *), 159 condition); 160 161 BreakpointLocationSP loc_sp = GetSP(); 162 if (loc_sp) { 163 std::lock_guard<std::recursive_mutex> guard( 164 loc_sp->GetTarget().GetAPIMutex()); 165 loc_sp->SetCondition(condition); 166 } 167 } 168 169 const char *SBBreakpointLocation::GetCondition() { 170 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBBreakpointLocation, GetCondition); 171 172 BreakpointLocationSP loc_sp = GetSP(); 173 if (loc_sp) { 174 std::lock_guard<std::recursive_mutex> guard( 175 loc_sp->GetTarget().GetAPIMutex()); 176 return loc_sp->GetConditionText(); 177 } 178 return NULL; 179 } 180 181 void SBBreakpointLocation::SetAutoContinue(bool auto_continue) { 182 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetAutoContinue, (bool), 183 auto_continue); 184 185 BreakpointLocationSP loc_sp = GetSP(); 186 if (loc_sp) { 187 std::lock_guard<std::recursive_mutex> guard( 188 loc_sp->GetTarget().GetAPIMutex()); 189 loc_sp->SetAutoContinue(auto_continue); 190 } 191 } 192 193 bool SBBreakpointLocation::GetAutoContinue() { 194 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, GetAutoContinue); 195 196 BreakpointLocationSP loc_sp = GetSP(); 197 if (loc_sp) { 198 std::lock_guard<std::recursive_mutex> guard( 199 loc_sp->GetTarget().GetAPIMutex()); 200 return loc_sp->IsAutoContinue(); 201 } 202 return false; 203 } 204 205 void SBBreakpointLocation::SetScriptCallbackFunction( 206 const char *callback_function_name) { 207 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetScriptCallbackFunction, 208 (const char *), callback_function_name); 209 210 BreakpointLocationSP loc_sp = GetSP(); 211 212 if (loc_sp) { 213 std::lock_guard<std::recursive_mutex> guard( 214 loc_sp->GetTarget().GetAPIMutex()); 215 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 216 loc_sp->GetBreakpoint() 217 .GetTarget() 218 .GetDebugger() 219 .GetCommandInterpreter() 220 .GetScriptInterpreter() 221 ->SetBreakpointCommandCallbackFunction(bp_options, 222 callback_function_name); 223 } 224 } 225 226 SBError 227 SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) { 228 LLDB_RECORD_METHOD(lldb::SBError, SBBreakpointLocation, SetScriptCallbackBody, 229 (const char *), callback_body_text); 230 231 BreakpointLocationSP loc_sp = GetSP(); 232 233 SBError sb_error; 234 if (loc_sp) { 235 std::lock_guard<std::recursive_mutex> guard( 236 loc_sp->GetTarget().GetAPIMutex()); 237 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 238 Status error = 239 loc_sp->GetBreakpoint() 240 .GetTarget() 241 .GetDebugger() 242 .GetCommandInterpreter() 243 .GetScriptInterpreter() 244 ->SetBreakpointCommandCallback(bp_options, callback_body_text); 245 sb_error.SetError(error); 246 } else 247 sb_error.SetErrorString("invalid breakpoint"); 248 249 return LLDB_RECORD_RESULT(sb_error); 250 } 251 252 void SBBreakpointLocation::SetCommandLineCommands(SBStringList &commands) { 253 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetCommandLineCommands, 254 (lldb::SBStringList &), commands); 255 256 BreakpointLocationSP loc_sp = GetSP(); 257 if (!loc_sp) 258 return; 259 if (commands.GetSize() == 0) 260 return; 261 262 std::lock_guard<std::recursive_mutex> guard( 263 loc_sp->GetTarget().GetAPIMutex()); 264 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( 265 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); 266 267 loc_sp->GetLocationOptions()->SetCommandDataCallback(cmd_data_up); 268 } 269 270 bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) { 271 LLDB_RECORD_METHOD(bool, SBBreakpointLocation, GetCommandLineCommands, 272 (lldb::SBStringList &), commands); 273 274 BreakpointLocationSP loc_sp = GetSP(); 275 if (!loc_sp) 276 return false; 277 StringList command_list; 278 bool has_commands = 279 loc_sp->GetLocationOptions()->GetCommandLineCallbacks(command_list); 280 if (has_commands) 281 commands.AppendList(command_list); 282 return has_commands; 283 } 284 285 void SBBreakpointLocation::SetThreadID(tid_t thread_id) { 286 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadID, (lldb::tid_t), 287 thread_id); 288 289 BreakpointLocationSP loc_sp = GetSP(); 290 if (loc_sp) { 291 std::lock_guard<std::recursive_mutex> guard( 292 loc_sp->GetTarget().GetAPIMutex()); 293 loc_sp->SetThreadID(thread_id); 294 } 295 } 296 297 tid_t SBBreakpointLocation::GetThreadID() { 298 LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBBreakpointLocation, GetThreadID); 299 300 tid_t tid = LLDB_INVALID_THREAD_ID; 301 BreakpointLocationSP loc_sp = GetSP(); 302 if (loc_sp) { 303 std::lock_guard<std::recursive_mutex> guard( 304 loc_sp->GetTarget().GetAPIMutex()); 305 return loc_sp->GetThreadID(); 306 } 307 return tid; 308 } 309 310 void SBBreakpointLocation::SetThreadIndex(uint32_t index) { 311 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadIndex, (uint32_t), 312 index); 313 314 BreakpointLocationSP loc_sp = GetSP(); 315 if (loc_sp) { 316 std::lock_guard<std::recursive_mutex> guard( 317 loc_sp->GetTarget().GetAPIMutex()); 318 loc_sp->SetThreadIndex(index); 319 } 320 } 321 322 uint32_t SBBreakpointLocation::GetThreadIndex() const { 323 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpointLocation, 324 GetThreadIndex); 325 326 uint32_t thread_idx = UINT32_MAX; 327 BreakpointLocationSP loc_sp = GetSP(); 328 if (loc_sp) { 329 std::lock_guard<std::recursive_mutex> guard( 330 loc_sp->GetTarget().GetAPIMutex()); 331 return loc_sp->GetThreadIndex(); 332 } 333 return thread_idx; 334 } 335 336 void SBBreakpointLocation::SetThreadName(const char *thread_name) { 337 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadName, (const char *), 338 thread_name); 339 340 BreakpointLocationSP loc_sp = GetSP(); 341 if (loc_sp) { 342 std::lock_guard<std::recursive_mutex> guard( 343 loc_sp->GetTarget().GetAPIMutex()); 344 loc_sp->SetThreadName(thread_name); 345 } 346 } 347 348 const char *SBBreakpointLocation::GetThreadName() const { 349 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointLocation, 350 GetThreadName); 351 352 BreakpointLocationSP loc_sp = GetSP(); 353 if (loc_sp) { 354 std::lock_guard<std::recursive_mutex> guard( 355 loc_sp->GetTarget().GetAPIMutex()); 356 return loc_sp->GetThreadName(); 357 } 358 return NULL; 359 } 360 361 void SBBreakpointLocation::SetQueueName(const char *queue_name) { 362 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetQueueName, (const char *), 363 queue_name); 364 365 BreakpointLocationSP loc_sp = GetSP(); 366 if (loc_sp) { 367 std::lock_guard<std::recursive_mutex> guard( 368 loc_sp->GetTarget().GetAPIMutex()); 369 loc_sp->SetQueueName(queue_name); 370 } 371 } 372 373 const char *SBBreakpointLocation::GetQueueName() const { 374 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointLocation, 375 GetQueueName); 376 377 BreakpointLocationSP loc_sp = GetSP(); 378 if (loc_sp) { 379 std::lock_guard<std::recursive_mutex> guard( 380 loc_sp->GetTarget().GetAPIMutex()); 381 loc_sp->GetQueueName(); 382 } 383 return NULL; 384 } 385 386 bool SBBreakpointLocation::IsResolved() { 387 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, IsResolved); 388 389 BreakpointLocationSP loc_sp = GetSP(); 390 if (loc_sp) { 391 std::lock_guard<std::recursive_mutex> guard( 392 loc_sp->GetTarget().GetAPIMutex()); 393 return loc_sp->IsResolved(); 394 } 395 return false; 396 } 397 398 void SBBreakpointLocation::SetLocation( 399 const lldb::BreakpointLocationSP &break_loc_sp) { 400 // Uninstall the callbacks? 401 m_opaque_wp = break_loc_sp; 402 } 403 404 bool SBBreakpointLocation::GetDescription(SBStream &description, 405 DescriptionLevel level) { 406 LLDB_RECORD_METHOD(bool, SBBreakpointLocation, GetDescription, 407 (lldb::SBStream &, lldb::DescriptionLevel), description, 408 level); 409 410 Stream &strm = description.ref(); 411 BreakpointLocationSP loc_sp = GetSP(); 412 413 if (loc_sp) { 414 std::lock_guard<std::recursive_mutex> guard( 415 loc_sp->GetTarget().GetAPIMutex()); 416 loc_sp->GetDescription(&strm, level); 417 strm.EOL(); 418 } else 419 strm.PutCString("No value"); 420 421 return true; 422 } 423 424 break_id_t SBBreakpointLocation::GetID() { 425 LLDB_RECORD_METHOD_NO_ARGS(lldb::break_id_t, SBBreakpointLocation, GetID); 426 427 BreakpointLocationSP loc_sp = GetSP(); 428 if (loc_sp) { 429 std::lock_guard<std::recursive_mutex> guard( 430 loc_sp->GetTarget().GetAPIMutex()); 431 return loc_sp->GetID(); 432 } else 433 return LLDB_INVALID_BREAK_ID; 434 } 435 436 SBBreakpoint SBBreakpointLocation::GetBreakpoint() { 437 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBreakpoint, SBBreakpointLocation, 438 GetBreakpoint); 439 440 BreakpointLocationSP loc_sp = GetSP(); 441 442 SBBreakpoint sb_bp; 443 if (loc_sp) { 444 std::lock_guard<std::recursive_mutex> guard( 445 loc_sp->GetTarget().GetAPIMutex()); 446 sb_bp = loc_sp->GetBreakpoint().shared_from_this(); 447 } 448 449 return LLDB_RECORD_RESULT(sb_bp); 450 } 451