SBBreakpointLocation.cpp revision 353358
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 29using namespace lldb; 30using namespace lldb_private; 31 32SBBreakpointLocation::SBBreakpointLocation() { 33 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBreakpointLocation); 34} 35 36SBBreakpointLocation::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 43SBBreakpointLocation::SBBreakpointLocation(const SBBreakpointLocation &rhs) 44 : m_opaque_wp(rhs.m_opaque_wp) { 45 LLDB_RECORD_CONSTRUCTOR(SBBreakpointLocation, 46 (const lldb::SBBreakpointLocation &), rhs); 47} 48 49const SBBreakpointLocation &SBBreakpointLocation:: 50operator=(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 LLDB_RECORD_RESULT(*this); 58} 59 60SBBreakpointLocation::~SBBreakpointLocation() {} 61 62BreakpointLocationSP SBBreakpointLocation::GetSP() const { 63 return m_opaque_wp.lock(); 64} 65 66bool SBBreakpointLocation::IsValid() const { 67 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpointLocation, IsValid); 68 return this->operator bool(); 69} 70SBBreakpointLocation::operator bool() const { 71 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpointLocation, operator bool); 72 73 return bool(GetSP()); 74} 75 76SBAddress 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 87addr_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 103void 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 114bool 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 126uint32_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 138uint32_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 150void 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 161void 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 173const 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 nullptr; 183} 184 185void 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 197bool 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 209void 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 .GetScriptInterpreter() 224 ->SetBreakpointCommandCallbackFunction(bp_options, 225 callback_function_name); 226 } 227} 228 229SBError 230SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) { 231 LLDB_RECORD_METHOD(lldb::SBError, SBBreakpointLocation, SetScriptCallbackBody, 232 (const char *), callback_body_text); 233 234 BreakpointLocationSP loc_sp = GetSP(); 235 236 SBError sb_error; 237 if (loc_sp) { 238 std::lock_guard<std::recursive_mutex> guard( 239 loc_sp->GetTarget().GetAPIMutex()); 240 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 241 Status error = 242 loc_sp->GetBreakpoint() 243 .GetTarget() 244 .GetDebugger() 245 .GetScriptInterpreter() 246 ->SetBreakpointCommandCallback(bp_options, callback_body_text); 247 sb_error.SetError(error); 248 } else 249 sb_error.SetErrorString("invalid breakpoint"); 250 251 return LLDB_RECORD_RESULT(sb_error); 252} 253 254void SBBreakpointLocation::SetCommandLineCommands(SBStringList &commands) { 255 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetCommandLineCommands, 256 (lldb::SBStringList &), commands); 257 258 BreakpointLocationSP loc_sp = GetSP(); 259 if (!loc_sp) 260 return; 261 if (commands.GetSize() == 0) 262 return; 263 264 std::lock_guard<std::recursive_mutex> guard( 265 loc_sp->GetTarget().GetAPIMutex()); 266 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( 267 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); 268 269 loc_sp->GetLocationOptions()->SetCommandDataCallback(cmd_data_up); 270} 271 272bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) { 273 LLDB_RECORD_METHOD(bool, SBBreakpointLocation, GetCommandLineCommands, 274 (lldb::SBStringList &), commands); 275 276 BreakpointLocationSP loc_sp = GetSP(); 277 if (!loc_sp) 278 return false; 279 StringList command_list; 280 bool has_commands = 281 loc_sp->GetLocationOptions()->GetCommandLineCallbacks(command_list); 282 if (has_commands) 283 commands.AppendList(command_list); 284 return has_commands; 285} 286 287void SBBreakpointLocation::SetThreadID(tid_t thread_id) { 288 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadID, (lldb::tid_t), 289 thread_id); 290 291 BreakpointLocationSP loc_sp = GetSP(); 292 if (loc_sp) { 293 std::lock_guard<std::recursive_mutex> guard( 294 loc_sp->GetTarget().GetAPIMutex()); 295 loc_sp->SetThreadID(thread_id); 296 } 297} 298 299tid_t SBBreakpointLocation::GetThreadID() { 300 LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBBreakpointLocation, GetThreadID); 301 302 tid_t tid = LLDB_INVALID_THREAD_ID; 303 BreakpointLocationSP loc_sp = GetSP(); 304 if (loc_sp) { 305 std::lock_guard<std::recursive_mutex> guard( 306 loc_sp->GetTarget().GetAPIMutex()); 307 return loc_sp->GetThreadID(); 308 } 309 return tid; 310} 311 312void SBBreakpointLocation::SetThreadIndex(uint32_t index) { 313 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadIndex, (uint32_t), 314 index); 315 316 BreakpointLocationSP loc_sp = GetSP(); 317 if (loc_sp) { 318 std::lock_guard<std::recursive_mutex> guard( 319 loc_sp->GetTarget().GetAPIMutex()); 320 loc_sp->SetThreadIndex(index); 321 } 322} 323 324uint32_t SBBreakpointLocation::GetThreadIndex() const { 325 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpointLocation, 326 GetThreadIndex); 327 328 uint32_t thread_idx = UINT32_MAX; 329 BreakpointLocationSP loc_sp = GetSP(); 330 if (loc_sp) { 331 std::lock_guard<std::recursive_mutex> guard( 332 loc_sp->GetTarget().GetAPIMutex()); 333 return loc_sp->GetThreadIndex(); 334 } 335 return thread_idx; 336} 337 338void SBBreakpointLocation::SetThreadName(const char *thread_name) { 339 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadName, (const char *), 340 thread_name); 341 342 BreakpointLocationSP loc_sp = GetSP(); 343 if (loc_sp) { 344 std::lock_guard<std::recursive_mutex> guard( 345 loc_sp->GetTarget().GetAPIMutex()); 346 loc_sp->SetThreadName(thread_name); 347 } 348} 349 350const char *SBBreakpointLocation::GetThreadName() const { 351 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointLocation, 352 GetThreadName); 353 354 BreakpointLocationSP loc_sp = GetSP(); 355 if (loc_sp) { 356 std::lock_guard<std::recursive_mutex> guard( 357 loc_sp->GetTarget().GetAPIMutex()); 358 return loc_sp->GetThreadName(); 359 } 360 return nullptr; 361} 362 363void SBBreakpointLocation::SetQueueName(const char *queue_name) { 364 LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetQueueName, (const char *), 365 queue_name); 366 367 BreakpointLocationSP loc_sp = GetSP(); 368 if (loc_sp) { 369 std::lock_guard<std::recursive_mutex> guard( 370 loc_sp->GetTarget().GetAPIMutex()); 371 loc_sp->SetQueueName(queue_name); 372 } 373} 374 375const char *SBBreakpointLocation::GetQueueName() const { 376 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointLocation, 377 GetQueueName); 378 379 BreakpointLocationSP loc_sp = GetSP(); 380 if (loc_sp) { 381 std::lock_guard<std::recursive_mutex> guard( 382 loc_sp->GetTarget().GetAPIMutex()); 383 loc_sp->GetQueueName(); 384 } 385 return nullptr; 386} 387 388bool SBBreakpointLocation::IsResolved() { 389 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, IsResolved); 390 391 BreakpointLocationSP loc_sp = GetSP(); 392 if (loc_sp) { 393 std::lock_guard<std::recursive_mutex> guard( 394 loc_sp->GetTarget().GetAPIMutex()); 395 return loc_sp->IsResolved(); 396 } 397 return false; 398} 399 400void SBBreakpointLocation::SetLocation( 401 const lldb::BreakpointLocationSP &break_loc_sp) { 402 // Uninstall the callbacks? 403 m_opaque_wp = break_loc_sp; 404} 405 406bool SBBreakpointLocation::GetDescription(SBStream &description, 407 DescriptionLevel level) { 408 LLDB_RECORD_METHOD(bool, SBBreakpointLocation, GetDescription, 409 (lldb::SBStream &, lldb::DescriptionLevel), description, 410 level); 411 412 Stream &strm = description.ref(); 413 BreakpointLocationSP loc_sp = GetSP(); 414 415 if (loc_sp) { 416 std::lock_guard<std::recursive_mutex> guard( 417 loc_sp->GetTarget().GetAPIMutex()); 418 loc_sp->GetDescription(&strm, level); 419 strm.EOL(); 420 } else 421 strm.PutCString("No value"); 422 423 return true; 424} 425 426break_id_t SBBreakpointLocation::GetID() { 427 LLDB_RECORD_METHOD_NO_ARGS(lldb::break_id_t, SBBreakpointLocation, GetID); 428 429 BreakpointLocationSP loc_sp = GetSP(); 430 if (loc_sp) { 431 std::lock_guard<std::recursive_mutex> guard( 432 loc_sp->GetTarget().GetAPIMutex()); 433 return loc_sp->GetID(); 434 } else 435 return LLDB_INVALID_BREAK_ID; 436} 437 438SBBreakpoint SBBreakpointLocation::GetBreakpoint() { 439 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBreakpoint, SBBreakpointLocation, 440 GetBreakpoint); 441 442 BreakpointLocationSP loc_sp = GetSP(); 443 444 SBBreakpoint sb_bp; 445 if (loc_sp) { 446 std::lock_guard<std::recursive_mutex> guard( 447 loc_sp->GetTarget().GetAPIMutex()); 448 sb_bp = loc_sp->GetBreakpoint().shared_from_this(); 449 } 450 451 return LLDB_RECORD_RESULT(sb_bp); 452} 453 454namespace lldb_private { 455namespace repro { 456 457template <> 458void RegisterMethods<SBBreakpointLocation>(Registry &R) { 459 LLDB_REGISTER_CONSTRUCTOR(SBBreakpointLocation, ()); 460 LLDB_REGISTER_CONSTRUCTOR(SBBreakpointLocation, 461 (const lldb::BreakpointLocationSP &)); 462 LLDB_REGISTER_CONSTRUCTOR(SBBreakpointLocation, 463 (const lldb::SBBreakpointLocation &)); 464 LLDB_REGISTER_METHOD( 465 const lldb::SBBreakpointLocation &, 466 SBBreakpointLocation, operator=,(const lldb::SBBreakpointLocation &)); 467 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpointLocation, IsValid, ()); 468 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpointLocation, operator bool, ()); 469 LLDB_REGISTER_METHOD(lldb::SBAddress, SBBreakpointLocation, GetAddress, ()); 470 LLDB_REGISTER_METHOD(lldb::addr_t, SBBreakpointLocation, GetLoadAddress, 471 ()); 472 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetEnabled, (bool)); 473 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, IsEnabled, ()); 474 LLDB_REGISTER_METHOD(uint32_t, SBBreakpointLocation, GetHitCount, ()); 475 LLDB_REGISTER_METHOD(uint32_t, SBBreakpointLocation, GetIgnoreCount, ()); 476 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetIgnoreCount, 477 (uint32_t)); 478 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetCondition, 479 (const char *)); 480 LLDB_REGISTER_METHOD(const char *, SBBreakpointLocation, GetCondition, ()); 481 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetAutoContinue, (bool)); 482 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, GetAutoContinue, ()); 483 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetScriptCallbackFunction, 484 (const char *)); 485 LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpointLocation, 486 SetScriptCallbackBody, (const char *)); 487 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetCommandLineCommands, 488 (lldb::SBStringList &)); 489 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, GetCommandLineCommands, 490 (lldb::SBStringList &)); 491 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetThreadID, 492 (lldb::tid_t)); 493 LLDB_REGISTER_METHOD(lldb::tid_t, SBBreakpointLocation, GetThreadID, ()); 494 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetThreadIndex, 495 (uint32_t)); 496 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpointLocation, GetThreadIndex, 497 ()); 498 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetThreadName, 499 (const char *)); 500 LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpointLocation, 501 GetThreadName, ()); 502 LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetQueueName, 503 (const char *)); 504 LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpointLocation, GetQueueName, 505 ()); 506 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, IsResolved, ()); 507 LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, GetDescription, 508 (lldb::SBStream &, lldb::DescriptionLevel)); 509 LLDB_REGISTER_METHOD(lldb::break_id_t, SBBreakpointLocation, GetID, ()); 510 LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointLocation, 511 GetBreakpoint, ()); 512} 513 514} 515} 516