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 return this->operator bool(); 69 } 70 SBBreakpointLocation::operator bool() const { 71 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpointLocation, operator bool); 72 73 return bool(GetSP()); 74 } 75 76 SBAddress SBBreakpointLocation::GetAddress() { 77 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBBreakpointLocation, GetAddress); 78 79 BreakpointLocationSP loc_sp = GetSP(); 80 if (loc_sp) { 81 return LLDB_RECORD_RESULT(SBAddress(&loc_sp->GetAddress())); 82 } 83 84 return LLDB_RECORD_RESULT(SBAddress()); 85 } 86 87 addr_t SBBreakpointLocation::GetLoadAddress() { 88 LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBBreakpointLocation, 89 GetLoadAddress); 90 91 addr_t ret_addr = LLDB_INVALID_ADDRESS; 92 BreakpointLocationSP loc_sp = GetSP(); 93 94 if (loc_sp) { 95 std::lock_guard<std::recursive_mutex> guard( 96 loc_sp->GetTarget().GetAPIMutex()); 97 ret_addr = loc_sp->GetLoadAddress(); 98 } 99 100 return ret_addr; 101 } 102 103 void SBBreakpointLocation::SetEnabled(bool enabled) { 104 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetEnabled, (bool), enabled); 105 106 BreakpointLocationSP loc_sp = GetSP(); 107 if (loc_sp) { 108 std::lock_guard<std::recursive_mutex> guard( 109 loc_sp->GetTarget().GetAPIMutex()); 110 loc_sp->SetEnabled(enabled); 111 } 112 } 113 114 bool SBBreakpointLocation::IsEnabled() { 115 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, IsEnabled); 116 117 BreakpointLocationSP loc_sp = GetSP(); 118 if (loc_sp) { 119 std::lock_guard<std::recursive_mutex> guard( 120 loc_sp->GetTarget().GetAPIMutex()); 121 return loc_sp->IsEnabled(); 122 } else 123 return false; 124 } 125 126 uint32_t SBBreakpointLocation::GetHitCount() { 127 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBBreakpointLocation, GetHitCount); 128 129 BreakpointLocationSP loc_sp = GetSP(); 130 if (loc_sp) { 131 std::lock_guard<std::recursive_mutex> guard( 132 loc_sp->GetTarget().GetAPIMutex()); 133 return loc_sp->GetHitCount(); 134 } else 135 return 0; 136 } 137 138 uint32_t SBBreakpointLocation::GetIgnoreCount() { 139 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBBreakpointLocation, GetIgnoreCount); 140 141 BreakpointLocationSP loc_sp = GetSP(); 142 if (loc_sp) { 143 std::lock_guard<std::recursive_mutex> guard( 144 loc_sp->GetTarget().GetAPIMutex()); 145 return loc_sp->GetIgnoreCount(); 146 } else 147 return 0; 148 } 149 150 void SBBreakpointLocation::SetIgnoreCount(uint32_t n) { 151 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetIgnoreCount, (uint32_t), n); 152 153 BreakpointLocationSP loc_sp = GetSP(); 154 if (loc_sp) { 155 std::lock_guard<std::recursive_mutex> guard( 156 loc_sp->GetTarget().GetAPIMutex()); 157 loc_sp->SetIgnoreCount(n); 158 } 159 } 160 161 void SBBreakpointLocation::SetCondition(const char *condition) { 162 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetCondition, (const char *), 163 condition); 164 165 BreakpointLocationSP loc_sp = GetSP(); 166 if (loc_sp) { 167 std::lock_guard<std::recursive_mutex> guard( 168 loc_sp->GetTarget().GetAPIMutex()); 169 loc_sp->SetCondition(condition); 170 } 171 } 172 173 const char *SBBreakpointLocation::GetCondition() { 174 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBBreakpointLocation, GetCondition); 175 176 BreakpointLocationSP loc_sp = GetSP(); 177 if (loc_sp) { 178 std::lock_guard<std::recursive_mutex> guard( 179 loc_sp->GetTarget().GetAPIMutex()); 180 return loc_sp->GetConditionText(); 181 } 182 return NULL; 183 } 184 185 void SBBreakpointLocation::SetAutoContinue(bool auto_continue) { 186 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetAutoContinue, (bool), 187 auto_continue); 188 189 BreakpointLocationSP loc_sp = GetSP(); 190 if (loc_sp) { 191 std::lock_guard<std::recursive_mutex> guard( 192 loc_sp->GetTarget().GetAPIMutex()); 193 loc_sp->SetAutoContinue(auto_continue); 194 } 195 } 196 197 bool SBBreakpointLocation::GetAutoContinue() { 198 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, GetAutoContinue); 199 200 BreakpointLocationSP loc_sp = GetSP(); 201 if (loc_sp) { 202 std::lock_guard<std::recursive_mutex> guard( 203 loc_sp->GetTarget().GetAPIMutex()); 204 return loc_sp->IsAutoContinue(); 205 } 206 return false; 207 } 208 209 void SBBreakpointLocation::SetScriptCallbackFunction( 210 const char *callback_function_name) { 211 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetScriptCallbackFunction, 212 (const char *), callback_function_name); 213 214 BreakpointLocationSP loc_sp = GetSP(); 215 216 if (loc_sp) { 217 std::lock_guard<std::recursive_mutex> guard( 218 loc_sp->GetTarget().GetAPIMutex()); 219 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 220 loc_sp->GetBreakpoint() 221 .GetTarget() 222 .GetDebugger() 223 .GetCommandInterpreter() 224 .GetScriptInterpreter() 225 ->SetBreakpointCommandCallbackFunction(bp_options, 226 callback_function_name); 227 } 228 } 229 230 SBError 231 SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) { 232 LLDB_RECORD_METHOD(lldb::SBError, SBBreakpointLocation, SetScriptCallbackBody, 233 (const char *), callback_body_text); 234 235 BreakpointLocationSP loc_sp = GetSP(); 236 237 SBError sb_error; 238 if (loc_sp) { 239 std::lock_guard<std::recursive_mutex> guard( 240 loc_sp->GetTarget().GetAPIMutex()); 241 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 242 Status error = 243 loc_sp->GetBreakpoint() 244 .GetTarget() 245 .GetDebugger() 246 .GetCommandInterpreter() 247 .GetScriptInterpreter() 248 ->SetBreakpointCommandCallback(bp_options, callback_body_text); 249 sb_error.SetError(error); 250 } else 251 sb_error.SetErrorString("invalid breakpoint"); 252 253 return LLDB_RECORD_RESULT(sb_error); 254 } 255 256 void SBBreakpointLocation::SetCommandLineCommands(SBStringList &commands) { 257 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetCommandLineCommands, 258 (lldb::SBStringList &), commands); 259 260 BreakpointLocationSP loc_sp = GetSP(); 261 if (!loc_sp) 262 return; 263 if (commands.GetSize() == 0) 264 return; 265 266 std::lock_guard<std::recursive_mutex> guard( 267 loc_sp->GetTarget().GetAPIMutex()); 268 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( 269 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); 270 271 loc_sp->GetLocationOptions()->SetCommandDataCallback(cmd_data_up); 272 } 273 274 bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) { 275 LLDB_RECORD_METHOD(bool, SBBreakpointLocation, GetCommandLineCommands, 276 (lldb::SBStringList &), commands); 277 278 BreakpointLocationSP loc_sp = GetSP(); 279 if (!loc_sp) 280 return false; 281 StringList command_list; 282 bool has_commands = 283 loc_sp->GetLocationOptions()->GetCommandLineCallbacks(command_list); 284 if (has_commands) 285 commands.AppendList(command_list); 286 return has_commands; 287 } 288 289 void SBBreakpointLocation::SetThreadID(tid_t thread_id) { 290 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadID, (lldb::tid_t), 291 thread_id); 292 293 BreakpointLocationSP loc_sp = GetSP(); 294 if (loc_sp) { 295 std::lock_guard<std::recursive_mutex> guard( 296 loc_sp->GetTarget().GetAPIMutex()); 297 loc_sp->SetThreadID(thread_id); 298 } 299 } 300 301 tid_t SBBreakpointLocation::GetThreadID() { 302 LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBBreakpointLocation, GetThreadID); 303 304 tid_t tid = LLDB_INVALID_THREAD_ID; 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->GetThreadID(); 310 } 311 return tid; 312 } 313 314 void SBBreakpointLocation::SetThreadIndex(uint32_t index) { 315 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadIndex, (uint32_t), 316 index); 317 318 BreakpointLocationSP loc_sp = GetSP(); 319 if (loc_sp) { 320 std::lock_guard<std::recursive_mutex> guard( 321 loc_sp->GetTarget().GetAPIMutex()); 322 loc_sp->SetThreadIndex(index); 323 } 324 } 325 326 uint32_t SBBreakpointLocation::GetThreadIndex() const { 327 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpointLocation, 328 GetThreadIndex); 329 330 uint32_t thread_idx = UINT32_MAX; 331 BreakpointLocationSP loc_sp = GetSP(); 332 if (loc_sp) { 333 std::lock_guard<std::recursive_mutex> guard( 334 loc_sp->GetTarget().GetAPIMutex()); 335 return loc_sp->GetThreadIndex(); 336 } 337 return thread_idx; 338 } 339 340 void SBBreakpointLocation::SetThreadName(const char *thread_name) { 341 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadName, (const char *), 342 thread_name); 343 344 BreakpointLocationSP loc_sp = GetSP(); 345 if (loc_sp) { 346 std::lock_guard<std::recursive_mutex> guard( 347 loc_sp->GetTarget().GetAPIMutex()); 348 loc_sp->SetThreadName(thread_name); 349 } 350 } 351 352 const char *SBBreakpointLocation::GetThreadName() const { 353 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointLocation, 354 GetThreadName); 355 356 BreakpointLocationSP loc_sp = GetSP(); 357 if (loc_sp) { 358 std::lock_guard<std::recursive_mutex> guard( 359 loc_sp->GetTarget().GetAPIMutex()); 360 return loc_sp->GetThreadName(); 361 } 362 return NULL; 363 } 364 365 void SBBreakpointLocation::SetQueueName(const char *queue_name) { 366 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetQueueName, (const char *), 367 queue_name); 368 369 BreakpointLocationSP loc_sp = GetSP(); 370 if (loc_sp) { 371 std::lock_guard<std::recursive_mutex> guard( 372 loc_sp->GetTarget().GetAPIMutex()); 373 loc_sp->SetQueueName(queue_name); 374 } 375 } 376 377 const char *SBBreakpointLocation::GetQueueName() const { 378 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointLocation, 379 GetQueueName); 380 381 BreakpointLocationSP loc_sp = GetSP(); 382 if (loc_sp) { 383 std::lock_guard<std::recursive_mutex> guard( 384 loc_sp->GetTarget().GetAPIMutex()); 385 loc_sp->GetQueueName(); 386 } 387 return NULL; 388 } 389 390 bool SBBreakpointLocation::IsResolved() { 391 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, IsResolved); 392 393 BreakpointLocationSP loc_sp = GetSP(); 394 if (loc_sp) { 395 std::lock_guard<std::recursive_mutex> guard( 396 loc_sp->GetTarget().GetAPIMutex()); 397 return loc_sp->IsResolved(); 398 } 399 return false; 400 } 401 402 void SBBreakpointLocation::SetLocation( 403 const lldb::BreakpointLocationSP &break_loc_sp) { 404 // Uninstall the callbacks? 405 m_opaque_wp = break_loc_sp; 406 } 407 408 bool SBBreakpointLocation::GetDescription(SBStream &description, 409 DescriptionLevel level) { 410 LLDB_RECORD_METHOD(bool, SBBreakpointLocation, GetDescription, 411 (lldb::SBStream &, lldb::DescriptionLevel), description, 412 level); 413 414 Stream &strm = description.ref(); 415 BreakpointLocationSP loc_sp = GetSP(); 416 417 if (loc_sp) { 418 std::lock_guard<std::recursive_mutex> guard( 419 loc_sp->GetTarget().GetAPIMutex()); 420 loc_sp->GetDescription(&strm, level); 421 strm.EOL(); 422 } else 423 strm.PutCString("No value"); 424 425 return true; 426 } 427 428 break_id_t SBBreakpointLocation::GetID() { 429 LLDB_RECORD_METHOD_NO_ARGS(lldb::break_id_t, SBBreakpointLocation, GetID); 430 431 BreakpointLocationSP loc_sp = GetSP(); 432 if (loc_sp) { 433 std::lock_guard<std::recursive_mutex> guard( 434 loc_sp->GetTarget().GetAPIMutex()); 435 return loc_sp->GetID(); 436 } else 437 return LLDB_INVALID_BREAK_ID; 438 } 439 440 SBBreakpoint SBBreakpointLocation::GetBreakpoint() { 441 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBreakpoint, SBBreakpointLocation, 442 GetBreakpoint); 443 444 BreakpointLocationSP loc_sp = GetSP(); 445 446 SBBreakpoint sb_bp; 447 if (loc_sp) { 448 std::lock_guard<std::recursive_mutex> guard( 449 loc_sp->GetTarget().GetAPIMutex()); 450 sb_bp = loc_sp->GetBreakpoint().shared_from_this(); 451 } 452 453 return LLDB_RECORD_RESULT(sb_bp); 454 } 455 456 namespace lldb_private { 457 namespace repro { 458 459 template <> 460 void RegisterMethods<SBBreakpointLocation>(Registry &R) { 461 LLDB_REGISTER_CONSTRUCTOR(SBBreakpointLocation, ()); 462 LLDB_REGISTER_CONSTRUCTOR(SBBreakpointLocation, 463 (const lldb::BreakpointLocationSP &)); 464 LLDB_REGISTER_CONSTRUCTOR(SBBreakpointLocation, 465 (const lldb::SBBreakpointLocation &)); 466 LLDB_REGISTER_METHOD( 467 const lldb::SBBreakpointLocation &, 468 SBBreakpointLocation, operator=,(const lldb::SBBreakpointLocation &)); 469 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpointLocation, IsValid, ()); 470 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpointLocation, operator bool, ()); 471 LLDB_REGISTER_METHOD(lldb::SBAddress, SBBreakpointLocation, GetAddress, ()); 472 LLDB_REGISTER_METHOD(lldb::addr_t, SBBreakpointLocation, GetLoadAddress, 473 ()); 474 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetEnabled, (bool)); 475 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, IsEnabled, ()); 476 LLDB_REGISTER_METHOD(uint32_t, SBBreakpointLocation, GetHitCount, ()); 477 LLDB_REGISTER_METHOD(uint32_t, SBBreakpointLocation, GetIgnoreCount, ()); 478 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetIgnoreCount, 479 (uint32_t)); 480 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetCondition, 481 (const char *)); 482 LLDB_REGISTER_METHOD(const char *, SBBreakpointLocation, GetCondition, ()); 483 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetAutoContinue, (bool)); 484 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, GetAutoContinue, ()); 485 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetScriptCallbackFunction, 486 (const char *)); 487 LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpointLocation, 488 SetScriptCallbackBody, (const char *)); 489 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetCommandLineCommands, 490 (lldb::SBStringList &)); 491 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, GetCommandLineCommands, 492 (lldb::SBStringList &)); 493 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetThreadID, 494 (lldb::tid_t)); 495 LLDB_REGISTER_METHOD(lldb::tid_t, SBBreakpointLocation, GetThreadID, ()); 496 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetThreadIndex, 497 (uint32_t)); 498 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpointLocation, GetThreadIndex, 499 ()); 500 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetThreadName, 501 (const char *)); 502 LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpointLocation, 503 GetThreadName, ()); 504 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetQueueName, 505 (const char *)); 506 LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpointLocation, GetQueueName, 507 ()); 508 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, IsResolved, ()); 509 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, GetDescription, 510 (lldb::SBStream &, lldb::DescriptionLevel)); 511 LLDB_REGISTER_METHOD(lldb::break_id_t, SBBreakpointLocation, GetID, ()); 512 LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointLocation, 513 GetBreakpoint, ()); 514 } 515 516 } 517 } 518