1 //===-- ExecutionContext.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 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/Target/ExecutionContext.h" 15 #include "lldb/Core/State.h" 16 #include "lldb/Target/ExecutionContextScope.h" 17 #include "lldb/Target/Process.h" 18 #include "lldb/Target/StackFrame.h" 19 #include "lldb/Target/Target.h" 20 #include "lldb/Target/Thread.h" 21 22 using namespace lldb_private; 23 24 ExecutionContext::ExecutionContext() 25 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {} 26 27 ExecutionContext::ExecutionContext(const ExecutionContext &rhs) 28 : m_target_sp(rhs.m_target_sp), m_process_sp(rhs.m_process_sp), 29 m_thread_sp(rhs.m_thread_sp), m_frame_sp(rhs.m_frame_sp) {} 30 31 ExecutionContext::ExecutionContext(const lldb::TargetSP &target_sp, 32 bool get_process) 33 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 34 if (target_sp) 35 SetContext(target_sp, get_process); 36 } 37 38 ExecutionContext::ExecutionContext(const lldb::ProcessSP &process_sp) 39 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 40 if (process_sp) 41 SetContext(process_sp); 42 } 43 44 ExecutionContext::ExecutionContext(const lldb::ThreadSP &thread_sp) 45 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 46 if (thread_sp) 47 SetContext(thread_sp); 48 } 49 50 ExecutionContext::ExecutionContext(const lldb::StackFrameSP &frame_sp) 51 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 52 if (frame_sp) 53 SetContext(frame_sp); 54 } 55 56 ExecutionContext::ExecutionContext(const lldb::TargetWP &target_wp, 57 bool get_process) 58 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 59 lldb::TargetSP target_sp(target_wp.lock()); 60 if (target_sp) 61 SetContext(target_sp, get_process); 62 } 63 64 ExecutionContext::ExecutionContext(const lldb::ProcessWP &process_wp) 65 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 66 lldb::ProcessSP process_sp(process_wp.lock()); 67 if (process_sp) 68 SetContext(process_sp); 69 } 70 71 ExecutionContext::ExecutionContext(const lldb::ThreadWP &thread_wp) 72 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 73 lldb::ThreadSP thread_sp(thread_wp.lock()); 74 if (thread_sp) 75 SetContext(thread_sp); 76 } 77 78 ExecutionContext::ExecutionContext(const lldb::StackFrameWP &frame_wp) 79 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 80 lldb::StackFrameSP frame_sp(frame_wp.lock()); 81 if (frame_sp) 82 SetContext(frame_sp); 83 } 84 85 ExecutionContext::ExecutionContext(Target *t, 86 bool fill_current_process_thread_frame) 87 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 88 if (t) { 89 m_target_sp = t->shared_from_this(); 90 if (fill_current_process_thread_frame) { 91 m_process_sp = t->GetProcessSP(); 92 if (m_process_sp) { 93 m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread(); 94 if (m_thread_sp) 95 m_frame_sp = m_thread_sp->GetSelectedFrame(); 96 } 97 } 98 } 99 } 100 101 ExecutionContext::ExecutionContext(Process *process, Thread *thread, 102 StackFrame *frame) 103 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 104 if (process) { 105 m_process_sp = process->shared_from_this(); 106 m_target_sp = process->GetTarget().shared_from_this(); 107 } 108 if (thread) 109 m_thread_sp = thread->shared_from_this(); 110 if (frame) 111 m_frame_sp = frame->shared_from_this(); 112 } 113 114 ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref) 115 : m_target_sp(exe_ctx_ref.GetTargetSP()), 116 m_process_sp(exe_ctx_ref.GetProcessSP()), 117 m_thread_sp(exe_ctx_ref.GetThreadSP()), 118 m_frame_sp(exe_ctx_ref.GetFrameSP()) {} 119 120 ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr, 121 bool thread_and_frame_only_if_stopped) 122 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 123 if (exe_ctx_ref_ptr) { 124 m_target_sp = exe_ctx_ref_ptr->GetTargetSP(); 125 m_process_sp = exe_ctx_ref_ptr->GetProcessSP(); 126 if (!thread_and_frame_only_if_stopped || 127 (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true))) { 128 m_thread_sp = exe_ctx_ref_ptr->GetThreadSP(); 129 m_frame_sp = exe_ctx_ref_ptr->GetFrameSP(); 130 } 131 } 132 } 133 134 ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr, 135 std::unique_lock<std::recursive_mutex> &lock) 136 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 137 if (exe_ctx_ref_ptr) { 138 m_target_sp = exe_ctx_ref_ptr->GetTargetSP(); 139 if (m_target_sp) { 140 lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex()); 141 142 m_process_sp = exe_ctx_ref_ptr->GetProcessSP(); 143 m_thread_sp = exe_ctx_ref_ptr->GetThreadSP(); 144 m_frame_sp = exe_ctx_ref_ptr->GetFrameSP(); 145 } 146 } 147 } 148 149 ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref, 150 std::unique_lock<std::recursive_mutex> &lock) 151 : m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(), 152 m_frame_sp() { 153 if (m_target_sp) { 154 lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex()); 155 156 m_process_sp = exe_ctx_ref.GetProcessSP(); 157 m_thread_sp = exe_ctx_ref.GetThreadSP(); 158 m_frame_sp = exe_ctx_ref.GetFrameSP(); 159 } 160 } 161 162 ExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr) 163 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { 164 if (exe_scope_ptr) 165 exe_scope_ptr->CalculateExecutionContext(*this); 166 } 167 168 ExecutionContext::ExecutionContext(ExecutionContextScope &exe_scope_ref) { 169 exe_scope_ref.CalculateExecutionContext(*this); 170 } 171 172 void ExecutionContext::Clear() { 173 m_target_sp.reset(); 174 m_process_sp.reset(); 175 m_thread_sp.reset(); 176 m_frame_sp.reset(); 177 } 178 179 ExecutionContext::~ExecutionContext() = default; 180 181 uint32_t ExecutionContext::GetAddressByteSize() const { 182 if (m_target_sp && m_target_sp->GetArchitecture().IsValid()) 183 return m_target_sp->GetArchitecture().GetAddressByteSize(); 184 if (m_process_sp) 185 return m_process_sp->GetAddressByteSize(); 186 return sizeof(void *); 187 } 188 189 lldb::ByteOrder ExecutionContext::GetByteOrder() const { 190 if (m_target_sp && m_target_sp->GetArchitecture().IsValid()) 191 m_target_sp->GetArchitecture().GetByteOrder(); 192 if (m_process_sp) 193 m_process_sp->GetByteOrder(); 194 return endian::InlHostByteOrder(); 195 } 196 197 RegisterContext *ExecutionContext::GetRegisterContext() const { 198 if (m_frame_sp) 199 return m_frame_sp->GetRegisterContext().get(); 200 else if (m_thread_sp) 201 return m_thread_sp->GetRegisterContext().get(); 202 return nullptr; 203 } 204 205 Target *ExecutionContext::GetTargetPtr() const { 206 if (m_target_sp) 207 return m_target_sp.get(); 208 if (m_process_sp) 209 return &m_process_sp->GetTarget(); 210 return nullptr; 211 } 212 213 Process *ExecutionContext::GetProcessPtr() const { 214 if (m_process_sp) 215 return m_process_sp.get(); 216 if (m_target_sp) 217 return m_target_sp->GetProcessSP().get(); 218 return nullptr; 219 } 220 221 ExecutionContextScope *ExecutionContext::GetBestExecutionContextScope() const { 222 if (m_frame_sp) 223 return m_frame_sp.get(); 224 if (m_thread_sp) 225 return m_thread_sp.get(); 226 if (m_process_sp) 227 return m_process_sp.get(); 228 return m_target_sp.get(); 229 } 230 231 Target &ExecutionContext::GetTargetRef() const { 232 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) 233 assert(m_target_sp); 234 #endif 235 return *m_target_sp; 236 } 237 238 Process &ExecutionContext::GetProcessRef() const { 239 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) 240 assert(m_process_sp); 241 #endif 242 return *m_process_sp; 243 } 244 245 Thread &ExecutionContext::GetThreadRef() const { 246 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) 247 assert(m_thread_sp); 248 #endif 249 return *m_thread_sp; 250 } 251 252 StackFrame &ExecutionContext::GetFrameRef() const { 253 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) 254 assert(m_frame_sp); 255 #endif 256 return *m_frame_sp; 257 } 258 259 void ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) { 260 m_target_sp = target_sp; 261 } 262 263 void ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) { 264 m_process_sp = process_sp; 265 } 266 267 void ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) { 268 m_thread_sp = thread_sp; 269 } 270 271 void ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) { 272 m_frame_sp = frame_sp; 273 } 274 275 void ExecutionContext::SetTargetPtr(Target *target) { 276 if (target) 277 m_target_sp = target->shared_from_this(); 278 else 279 m_target_sp.reset(); 280 } 281 282 void ExecutionContext::SetProcessPtr(Process *process) { 283 if (process) 284 m_process_sp = process->shared_from_this(); 285 else 286 m_process_sp.reset(); 287 } 288 289 void ExecutionContext::SetThreadPtr(Thread *thread) { 290 if (thread) 291 m_thread_sp = thread->shared_from_this(); 292 else 293 m_thread_sp.reset(); 294 } 295 296 void ExecutionContext::SetFramePtr(StackFrame *frame) { 297 if (frame) 298 m_frame_sp = frame->shared_from_this(); 299 else 300 m_frame_sp.reset(); 301 } 302 303 void ExecutionContext::SetContext(const lldb::TargetSP &target_sp, 304 bool get_process) { 305 m_target_sp = target_sp; 306 if (get_process && target_sp) 307 m_process_sp = target_sp->GetProcessSP(); 308 else 309 m_process_sp.reset(); 310 m_thread_sp.reset(); 311 m_frame_sp.reset(); 312 } 313 314 void ExecutionContext::SetContext(const lldb::ProcessSP &process_sp) { 315 m_process_sp = process_sp; 316 if (process_sp) 317 m_target_sp = process_sp->GetTarget().shared_from_this(); 318 else 319 m_target_sp.reset(); 320 m_thread_sp.reset(); 321 m_frame_sp.reset(); 322 } 323 324 void ExecutionContext::SetContext(const lldb::ThreadSP &thread_sp) { 325 m_frame_sp.reset(); 326 m_thread_sp = thread_sp; 327 if (thread_sp) { 328 m_process_sp = thread_sp->GetProcess(); 329 if (m_process_sp) 330 m_target_sp = m_process_sp->GetTarget().shared_from_this(); 331 else 332 m_target_sp.reset(); 333 } else { 334 m_target_sp.reset(); 335 m_process_sp.reset(); 336 } 337 } 338 339 void ExecutionContext::SetContext(const lldb::StackFrameSP &frame_sp) { 340 m_frame_sp = frame_sp; 341 if (frame_sp) { 342 m_thread_sp = frame_sp->CalculateThread(); 343 if (m_thread_sp) { 344 m_process_sp = m_thread_sp->GetProcess(); 345 if (m_process_sp) 346 m_target_sp = m_process_sp->GetTarget().shared_from_this(); 347 else 348 m_target_sp.reset(); 349 } else { 350 m_target_sp.reset(); 351 m_process_sp.reset(); 352 } 353 } else { 354 m_target_sp.reset(); 355 m_process_sp.reset(); 356 m_thread_sp.reset(); 357 } 358 } 359 360 ExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) { 361 if (this != &rhs) { 362 m_target_sp = rhs.m_target_sp; 363 m_process_sp = rhs.m_process_sp; 364 m_thread_sp = rhs.m_thread_sp; 365 m_frame_sp = rhs.m_frame_sp; 366 } 367 return *this; 368 } 369 370 bool ExecutionContext::operator==(const ExecutionContext &rhs) const { 371 // Check that the frame shared pointers match, or both are valid and their 372 // stack 373 // IDs match since sometimes we get new objects that represent the same 374 // frame within a thread. 375 if ((m_frame_sp == rhs.m_frame_sp) || 376 (m_frame_sp && rhs.m_frame_sp && 377 m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) { 378 // Check that the thread shared pointers match, or both are valid and 379 // their thread IDs match since sometimes we get new objects that 380 // represent the same thread within a process. 381 if ((m_thread_sp == rhs.m_thread_sp) || 382 (m_thread_sp && rhs.m_thread_sp && 383 m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) { 384 // Processes and targets don't change much 385 return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp; 386 } 387 } 388 return false; 389 } 390 391 bool ExecutionContext::operator!=(const ExecutionContext &rhs) const { 392 return !(*this == rhs); 393 } 394 395 bool ExecutionContext::HasTargetScope() const { 396 return ((bool)m_target_sp && m_target_sp->IsValid()); 397 } 398 399 bool ExecutionContext::HasProcessScope() const { 400 return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid())); 401 } 402 403 bool ExecutionContext::HasThreadScope() const { 404 return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid())); 405 } 406 407 bool ExecutionContext::HasFrameScope() const { 408 return HasThreadScope() && m_frame_sp; 409 } 410 411 ExecutionContextRef::ExecutionContextRef() 412 : m_target_wp(), m_process_wp(), m_thread_wp(), 413 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {} 414 415 ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx) 416 : m_target_wp(), m_process_wp(), m_thread_wp(), 417 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { 418 if (exe_ctx) 419 *this = *exe_ctx; 420 } 421 422 ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx) 423 : m_target_wp(), m_process_wp(), m_thread_wp(), 424 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { 425 *this = exe_ctx; 426 } 427 428 ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected) 429 : m_target_wp(), m_process_wp(), m_thread_wp(), 430 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { 431 SetTargetPtr(target, adopt_selected); 432 } 433 434 ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs) 435 : m_target_wp(rhs.m_target_wp), m_process_wp(rhs.m_process_wp), 436 m_thread_wp(rhs.m_thread_wp), m_tid(rhs.m_tid), 437 m_stack_id(rhs.m_stack_id) {} 438 439 ExecutionContextRef &ExecutionContextRef:: 440 operator=(const ExecutionContextRef &rhs) { 441 if (this != &rhs) { 442 m_target_wp = rhs.m_target_wp; 443 m_process_wp = rhs.m_process_wp; 444 m_thread_wp = rhs.m_thread_wp; 445 m_tid = rhs.m_tid; 446 m_stack_id = rhs.m_stack_id; 447 } 448 return *this; 449 } 450 451 ExecutionContextRef &ExecutionContextRef:: 452 operator=(const ExecutionContext &exe_ctx) { 453 m_target_wp = exe_ctx.GetTargetSP(); 454 m_process_wp = exe_ctx.GetProcessSP(); 455 lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP()); 456 m_thread_wp = thread_sp; 457 if (thread_sp) 458 m_tid = thread_sp->GetID(); 459 else 460 m_tid = LLDB_INVALID_THREAD_ID; 461 lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP()); 462 if (frame_sp) 463 m_stack_id = frame_sp->GetStackID(); 464 else 465 m_stack_id.Clear(); 466 return *this; 467 } 468 469 void ExecutionContextRef::Clear() { 470 m_target_wp.reset(); 471 m_process_wp.reset(); 472 ClearThread(); 473 ClearFrame(); 474 } 475 476 ExecutionContextRef::~ExecutionContextRef() = default; 477 478 void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) { 479 m_target_wp = target_sp; 480 } 481 482 void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) { 483 if (process_sp) { 484 m_process_wp = process_sp; 485 SetTargetSP(process_sp->GetTarget().shared_from_this()); 486 } else { 487 m_process_wp.reset(); 488 m_target_wp.reset(); 489 } 490 } 491 492 void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) { 493 if (thread_sp) { 494 m_thread_wp = thread_sp; 495 m_tid = thread_sp->GetID(); 496 SetProcessSP(thread_sp->GetProcess()); 497 } else { 498 ClearThread(); 499 m_process_wp.reset(); 500 m_target_wp.reset(); 501 } 502 } 503 504 void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) { 505 if (frame_sp) { 506 m_stack_id = frame_sp->GetStackID(); 507 SetThreadSP(frame_sp->GetThread()); 508 } else { 509 ClearFrame(); 510 ClearThread(); 511 m_process_wp.reset(); 512 m_target_wp.reset(); 513 } 514 } 515 516 void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) { 517 Clear(); 518 if (target) { 519 lldb::TargetSP target_sp(target->shared_from_this()); 520 if (target_sp) { 521 m_target_wp = target_sp; 522 if (adopt_selected) { 523 lldb::ProcessSP process_sp(target_sp->GetProcessSP()); 524 if (process_sp) { 525 m_process_wp = process_sp; 526 if (process_sp) { 527 // Only fill in the thread and frame if our process is stopped 528 // Don't just check the state, since we might be in the middle of 529 // resuming. 530 Process::StopLocker stop_locker; 531 532 if (stop_locker.TryLock(&process_sp->GetRunLock()) && 533 StateIsStoppedState(process_sp->GetState(), true)) { 534 lldb::ThreadSP thread_sp( 535 process_sp->GetThreadList().GetSelectedThread()); 536 if (!thread_sp) 537 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0); 538 539 if (thread_sp) { 540 SetThreadSP(thread_sp); 541 lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame()); 542 if (!frame_sp) 543 frame_sp = thread_sp->GetStackFrameAtIndex(0); 544 if (frame_sp) 545 SetFrameSP(frame_sp); 546 } 547 } 548 } 549 } 550 } 551 } 552 } 553 } 554 555 void ExecutionContextRef::SetProcessPtr(Process *process) { 556 if (process) { 557 SetProcessSP(process->shared_from_this()); 558 } else { 559 m_process_wp.reset(); 560 m_target_wp.reset(); 561 } 562 } 563 564 void ExecutionContextRef::SetThreadPtr(Thread *thread) { 565 if (thread) { 566 SetThreadSP(thread->shared_from_this()); 567 } else { 568 ClearThread(); 569 m_process_wp.reset(); 570 m_target_wp.reset(); 571 } 572 } 573 574 void ExecutionContextRef::SetFramePtr(StackFrame *frame) { 575 if (frame) 576 SetFrameSP(frame->shared_from_this()); 577 else 578 Clear(); 579 } 580 581 lldb::TargetSP ExecutionContextRef::GetTargetSP() const { 582 lldb::TargetSP target_sp(m_target_wp.lock()); 583 if (target_sp && !target_sp->IsValid()) 584 target_sp.reset(); 585 return target_sp; 586 } 587 588 lldb::ProcessSP ExecutionContextRef::GetProcessSP() const { 589 lldb::ProcessSP process_sp(m_process_wp.lock()); 590 if (process_sp && !process_sp->IsValid()) 591 process_sp.reset(); 592 return process_sp; 593 } 594 595 lldb::ThreadSP ExecutionContextRef::GetThreadSP() const { 596 lldb::ThreadSP thread_sp(m_thread_wp.lock()); 597 598 if (m_tid != LLDB_INVALID_THREAD_ID) { 599 // We check if the thread has been destroyed in cases where clients 600 // might still have shared pointer to a thread, but the thread is 601 // not valid anymore (not part of the process) 602 if (!thread_sp || !thread_sp->IsValid()) { 603 lldb::ProcessSP process_sp(GetProcessSP()); 604 if (process_sp && process_sp->IsValid()) { 605 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid); 606 m_thread_wp = thread_sp; 607 } 608 } 609 } 610 611 // Check that we aren't about to return an invalid thread sp. We might return 612 // a nullptr thread_sp, 613 // but don't return an invalid one. 614 615 if (thread_sp && !thread_sp->IsValid()) 616 thread_sp.reset(); 617 618 return thread_sp; 619 } 620 621 lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const { 622 if (m_stack_id.IsValid()) { 623 lldb::ThreadSP thread_sp(GetThreadSP()); 624 if (thread_sp) 625 return thread_sp->GetFrameWithStackID(m_stack_id); 626 } 627 return lldb::StackFrameSP(); 628 } 629 630 ExecutionContext 631 ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const { 632 return ExecutionContext(this, thread_and_frame_only_if_stopped); 633 } 634