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#include "lldb/Target/ExecutionContext.h" 11 12#include "lldb/Core/State.h" 13#include "lldb/Target/ExecutionContextScope.h" 14#include "lldb/Target/StackFrame.h" 15#include "lldb/Target/Process.h" 16#include "lldb/Target/Target.h" 17#include "lldb/Target/Thread.h" 18 19using namespace lldb_private; 20 21ExecutionContext::ExecutionContext() : 22 m_target_sp (), 23 m_process_sp (), 24 m_thread_sp (), 25 m_frame_sp () 26{ 27} 28 29ExecutionContext::ExecutionContext (const ExecutionContext &rhs) : 30 m_target_sp(rhs.m_target_sp), 31 m_process_sp(rhs.m_process_sp), 32 m_thread_sp(rhs.m_thread_sp), 33 m_frame_sp(rhs.m_frame_sp) 34{ 35} 36 37ExecutionContext::ExecutionContext (const lldb::TargetSP &target_sp, bool get_process) : 38 m_target_sp (), 39 m_process_sp (), 40 m_thread_sp (), 41 m_frame_sp () 42{ 43 if (target_sp) 44 SetContext (target_sp, get_process); 45} 46 47ExecutionContext::ExecutionContext (const lldb::ProcessSP &process_sp) : 48 m_target_sp (), 49 m_process_sp (), 50 m_thread_sp (), 51 m_frame_sp () 52{ 53 if (process_sp) 54 SetContext (process_sp); 55} 56 57ExecutionContext::ExecutionContext (const lldb::ThreadSP &thread_sp) : 58 m_target_sp (), 59 m_process_sp (), 60 m_thread_sp (), 61 m_frame_sp () 62{ 63 if (thread_sp) 64 SetContext (thread_sp); 65} 66 67ExecutionContext::ExecutionContext (const lldb::StackFrameSP &frame_sp) : 68 m_target_sp (), 69 m_process_sp (), 70 m_thread_sp (), 71 m_frame_sp () 72{ 73 if (frame_sp) 74 SetContext (frame_sp); 75} 76 77ExecutionContext::ExecutionContext (const lldb::TargetWP &target_wp, bool get_process) : 78 m_target_sp (), 79 m_process_sp (), 80 m_thread_sp (), 81 m_frame_sp () 82{ 83 lldb::TargetSP target_sp(target_wp.lock()); 84 if (target_sp) 85 SetContext (target_sp, get_process); 86} 87 88ExecutionContext::ExecutionContext (const lldb::ProcessWP &process_wp) : 89 m_target_sp (), 90 m_process_sp (), 91 m_thread_sp (), 92 m_frame_sp () 93{ 94 lldb::ProcessSP process_sp(process_wp.lock()); 95 if (process_sp) 96 SetContext (process_sp); 97} 98 99ExecutionContext::ExecutionContext (const lldb::ThreadWP &thread_wp) : 100 m_target_sp (), 101 m_process_sp (), 102 m_thread_sp (), 103 m_frame_sp () 104{ 105 lldb::ThreadSP thread_sp(thread_wp.lock()); 106 if (thread_sp) 107 SetContext (thread_sp); 108} 109 110ExecutionContext::ExecutionContext (const lldb::StackFrameWP &frame_wp) : 111 m_target_sp (), 112 m_process_sp (), 113 m_thread_sp (), 114 m_frame_sp () 115{ 116 lldb::StackFrameSP frame_sp(frame_wp.lock()); 117 if (frame_sp) 118 SetContext (frame_sp); 119} 120 121ExecutionContext::ExecutionContext (Target* t, bool fill_current_process_thread_frame) : 122 m_target_sp (t->shared_from_this()), 123 m_process_sp (), 124 m_thread_sp (), 125 m_frame_sp () 126{ 127 if (t && fill_current_process_thread_frame) 128 { 129 m_process_sp = t->GetProcessSP(); 130 if (m_process_sp) 131 { 132 m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread(); 133 if (m_thread_sp) 134 m_frame_sp = m_thread_sp->GetSelectedFrame(); 135 } 136 } 137} 138 139ExecutionContext::ExecutionContext(Process* process, Thread *thread, StackFrame *frame) : 140 m_target_sp (), 141 m_process_sp (process->shared_from_this()), 142 m_thread_sp (thread->shared_from_this()), 143 m_frame_sp (frame->shared_from_this()) 144{ 145 if (process) 146 m_target_sp = process->GetTarget().shared_from_this(); 147} 148 149ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref) : 150 m_target_sp (exe_ctx_ref.GetTargetSP()), 151 m_process_sp (exe_ctx_ref.GetProcessSP()), 152 m_thread_sp (exe_ctx_ref.GetThreadSP()), 153 m_frame_sp (exe_ctx_ref.GetFrameSP()) 154{ 155} 156 157ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr) : 158 m_target_sp (), 159 m_process_sp (), 160 m_thread_sp (), 161 m_frame_sp () 162{ 163 if (exe_ctx_ref_ptr) 164 { 165 m_target_sp = exe_ctx_ref_ptr->GetTargetSP(); 166 m_process_sp = exe_ctx_ref_ptr->GetProcessSP(); 167 m_thread_sp = exe_ctx_ref_ptr->GetThreadSP(); 168 m_frame_sp = exe_ctx_ref_ptr->GetFrameSP(); 169 } 170} 171 172ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, Mutex::Locker &locker) : 173 m_target_sp (), 174 m_process_sp (), 175 m_thread_sp (), 176 m_frame_sp () 177{ 178 if (exe_ctx_ref_ptr) 179 { 180 m_target_sp = exe_ctx_ref_ptr->GetTargetSP(); 181 if (m_target_sp) 182 { 183 locker.Lock(m_target_sp->GetAPIMutex()); 184 m_process_sp = exe_ctx_ref_ptr->GetProcessSP(); 185 m_thread_sp = exe_ctx_ref_ptr->GetThreadSP(); 186 m_frame_sp = exe_ctx_ref_ptr->GetFrameSP(); 187 } 188 } 189} 190 191ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker) : 192 m_target_sp (exe_ctx_ref.GetTargetSP()), 193 m_process_sp (), 194 m_thread_sp (), 195 m_frame_sp () 196{ 197 if (m_target_sp) 198 { 199 locker.Lock(m_target_sp->GetAPIMutex()); 200 m_process_sp = exe_ctx_ref.GetProcessSP(); 201 m_thread_sp = exe_ctx_ref.GetThreadSP(); 202 m_frame_sp = exe_ctx_ref.GetFrameSP(); 203 } 204} 205 206ExecutionContext::ExecutionContext (ExecutionContextScope *exe_scope_ptr) : 207 m_target_sp (), 208 m_process_sp (), 209 m_thread_sp (), 210 m_frame_sp () 211{ 212 if (exe_scope_ptr) 213 exe_scope_ptr->CalculateExecutionContext (*this); 214} 215 216ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref) 217{ 218 exe_scope_ref.CalculateExecutionContext (*this); 219} 220 221void 222ExecutionContext::Clear() 223{ 224 m_target_sp.reset(); 225 m_process_sp.reset(); 226 m_thread_sp.reset(); 227 m_frame_sp.reset(); 228} 229 230ExecutionContext::~ExecutionContext() 231{ 232} 233 234uint32_t 235ExecutionContext::GetAddressByteSize() const 236{ 237 if (m_target_sp && m_target_sp->GetArchitecture().IsValid()) 238 m_target_sp->GetArchitecture().GetAddressByteSize(); 239 if (m_process_sp) 240 m_process_sp->GetAddressByteSize(); 241 return sizeof(void *); 242} 243 244 245 246RegisterContext * 247ExecutionContext::GetRegisterContext () const 248{ 249 if (m_frame_sp) 250 return m_frame_sp->GetRegisterContext().get(); 251 else if (m_thread_sp) 252 return m_thread_sp->GetRegisterContext().get(); 253 return NULL; 254} 255 256Target * 257ExecutionContext::GetTargetPtr () const 258{ 259 if (m_target_sp) 260 return m_target_sp.get(); 261 if (m_process_sp) 262 return &m_process_sp->GetTarget(); 263 return NULL; 264} 265 266Process * 267ExecutionContext::GetProcessPtr () const 268{ 269 if (m_process_sp) 270 return m_process_sp.get(); 271 if (m_target_sp) 272 return m_target_sp->GetProcessSP().get(); 273 return NULL; 274} 275 276ExecutionContextScope * 277ExecutionContext::GetBestExecutionContextScope () const 278{ 279 if (m_frame_sp) 280 return m_frame_sp.get(); 281 if (m_thread_sp) 282 return m_thread_sp.get(); 283 if (m_process_sp) 284 return m_process_sp.get(); 285 return m_target_sp.get(); 286} 287 288Target & 289ExecutionContext::GetTargetRef () const 290{ 291#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 292 assert (m_target_sp.get()); 293#endif 294 return *m_target_sp; 295} 296 297Process & 298ExecutionContext::GetProcessRef () const 299{ 300#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 301 assert (m_process_sp.get()); 302#endif 303 return *m_process_sp; 304} 305 306Thread & 307ExecutionContext::GetThreadRef () const 308{ 309#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 310 assert (m_thread_sp.get()); 311#endif 312 return *m_thread_sp; 313} 314 315StackFrame & 316ExecutionContext::GetFrameRef () const 317{ 318#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 319 assert (m_frame_sp.get()); 320#endif 321 return *m_frame_sp; 322} 323 324void 325ExecutionContext::SetTargetSP (const lldb::TargetSP &target_sp) 326{ 327 m_target_sp = target_sp; 328} 329 330void 331ExecutionContext::SetProcessSP (const lldb::ProcessSP &process_sp) 332{ 333 m_process_sp = process_sp; 334} 335 336void 337ExecutionContext::SetThreadSP (const lldb::ThreadSP &thread_sp) 338{ 339 m_thread_sp = thread_sp; 340} 341 342void 343ExecutionContext::SetFrameSP (const lldb::StackFrameSP &frame_sp) 344{ 345 m_frame_sp = frame_sp; 346} 347 348void 349ExecutionContext::SetTargetPtr (Target* target) 350{ 351 if (target) 352 m_target_sp = target->shared_from_this(); 353 else 354 m_target_sp.reset(); 355} 356 357void 358ExecutionContext::SetProcessPtr (Process *process) 359{ 360 if (process) 361 m_process_sp = process->shared_from_this(); 362 else 363 m_process_sp.reset(); 364} 365 366void 367ExecutionContext::SetThreadPtr (Thread *thread) 368{ 369 if (thread) 370 m_thread_sp = thread->shared_from_this(); 371 else 372 m_thread_sp.reset(); 373} 374 375void 376ExecutionContext::SetFramePtr (StackFrame *frame) 377{ 378 if (frame) 379 m_frame_sp = frame->shared_from_this(); 380 else 381 m_frame_sp.reset(); 382} 383 384void 385ExecutionContext::SetContext (const lldb::TargetSP &target_sp, bool get_process) 386{ 387 m_target_sp = target_sp; 388 if (get_process && target_sp) 389 m_process_sp = target_sp->GetProcessSP(); 390 else 391 m_process_sp.reset(); 392 m_thread_sp.reset(); 393 m_frame_sp.reset(); 394} 395 396void 397ExecutionContext::SetContext (const lldb::ProcessSP &process_sp) 398{ 399 m_process_sp = process_sp; 400 if (process_sp) 401 m_target_sp = process_sp->GetTarget().shared_from_this(); 402 else 403 m_target_sp.reset(); 404 m_thread_sp.reset(); 405 m_frame_sp.reset(); 406} 407 408void 409ExecutionContext::SetContext (const lldb::ThreadSP &thread_sp) 410{ 411 m_frame_sp.reset(); 412 m_thread_sp = thread_sp; 413 if (thread_sp) 414 { 415 m_process_sp = thread_sp->GetProcess(); 416 if (m_process_sp) 417 m_target_sp = m_process_sp->GetTarget().shared_from_this(); 418 else 419 m_target_sp.reset(); 420 } 421 else 422 { 423 m_target_sp.reset(); 424 m_process_sp.reset(); 425 } 426} 427 428void 429ExecutionContext::SetContext (const lldb::StackFrameSP &frame_sp) 430{ 431 m_frame_sp = frame_sp; 432 if (frame_sp) 433 { 434 m_thread_sp = frame_sp->CalculateThread(); 435 if (m_thread_sp) 436 { 437 m_process_sp = m_thread_sp->GetProcess(); 438 if (m_process_sp) 439 m_target_sp = m_process_sp->GetTarget().shared_from_this(); 440 else 441 m_target_sp.reset(); 442 } 443 else 444 { 445 m_target_sp.reset(); 446 m_process_sp.reset(); 447 } 448 } 449 else 450 { 451 m_target_sp.reset(); 452 m_process_sp.reset(); 453 m_thread_sp.reset(); 454 } 455} 456 457ExecutionContext & 458ExecutionContext::operator =(const ExecutionContext &rhs) 459{ 460 if (this != &rhs) 461 { 462 m_target_sp = rhs.m_target_sp; 463 m_process_sp = rhs.m_process_sp; 464 m_thread_sp = rhs.m_thread_sp; 465 m_frame_sp = rhs.m_frame_sp; 466 } 467 return *this; 468} 469 470bool 471ExecutionContext::operator ==(const ExecutionContext &rhs) const 472{ 473 // Check that the frame shared pointers match, or both are valid and their stack 474 // IDs match since sometimes we get new objects that represent the same 475 // frame within a thread. 476 if ((m_frame_sp == rhs.m_frame_sp) || (m_frame_sp && rhs.m_frame_sp && m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) 477 { 478 // Check that the thread shared pointers match, or both are valid and 479 // their thread IDs match since sometimes we get new objects that 480 // represent the same thread within a process. 481 if ((m_thread_sp == rhs.m_thread_sp) || (m_thread_sp && rhs.m_thread_sp && m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) 482 { 483 // Processes and targets don't change much 484 return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp; 485 } 486 } 487 return false; 488} 489 490bool 491ExecutionContext::operator !=(const ExecutionContext &rhs) const 492{ 493 return !(*this == rhs); 494} 495 496bool 497ExecutionContext::HasTargetScope () const 498{ 499 return ((bool) m_target_sp 500 && m_target_sp->IsValid()); 501} 502 503bool 504ExecutionContext::HasProcessScope () const 505{ 506 return (HasTargetScope() 507 && ((bool) m_process_sp && m_process_sp->IsValid())); 508} 509 510bool 511ExecutionContext::HasThreadScope () const 512{ 513 return (HasProcessScope() 514 && ((bool) m_thread_sp && m_thread_sp->IsValid())); 515} 516 517bool 518ExecutionContext::HasFrameScope () const 519{ 520 return HasThreadScope() && m_frame_sp; 521} 522 523ExecutionContextRef::ExecutionContextRef() : 524 m_target_wp (), 525 m_process_wp (), 526 m_thread_wp (), 527 m_tid(LLDB_INVALID_THREAD_ID), 528 m_stack_id () 529{ 530} 531 532ExecutionContextRef::ExecutionContextRef (const ExecutionContext *exe_ctx) : 533 m_target_wp (), 534 m_process_wp (), 535 m_thread_wp (), 536 m_tid(LLDB_INVALID_THREAD_ID), 537 m_stack_id () 538{ 539 if (exe_ctx) 540 *this = *exe_ctx; 541} 542 543ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) : 544 m_target_wp (), 545 m_process_wp (), 546 m_thread_wp (), 547 m_tid(LLDB_INVALID_THREAD_ID), 548 m_stack_id () 549{ 550 *this = exe_ctx; 551} 552 553 554ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) : 555 m_target_wp(), 556 m_process_wp(), 557 m_thread_wp(), 558 m_tid(LLDB_INVALID_THREAD_ID), 559 m_stack_id () 560{ 561 SetTargetPtr (target, adopt_selected); 562} 563 564 565 566 567ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) : 568 m_target_wp (rhs.m_target_wp), 569 m_process_wp(rhs.m_process_wp), 570 m_thread_wp (rhs.m_thread_wp), 571 m_tid (rhs.m_tid), 572 m_stack_id (rhs.m_stack_id) 573{ 574} 575 576ExecutionContextRef & 577ExecutionContextRef::operator =(const ExecutionContextRef &rhs) 578{ 579 if (this != &rhs) 580 { 581 m_target_wp = rhs.m_target_wp; 582 m_process_wp = rhs.m_process_wp; 583 m_thread_wp = rhs.m_thread_wp; 584 m_tid = rhs.m_tid; 585 m_stack_id = rhs.m_stack_id; 586 } 587 return *this; 588} 589 590ExecutionContextRef & 591ExecutionContextRef::operator =(const ExecutionContext &exe_ctx) 592{ 593 m_target_wp = exe_ctx.GetTargetSP(); 594 m_process_wp = exe_ctx.GetProcessSP(); 595 lldb::ThreadSP thread_sp (exe_ctx.GetThreadSP()); 596 m_thread_wp = thread_sp; 597 if (thread_sp) 598 m_tid = thread_sp->GetID(); 599 else 600 m_tid = LLDB_INVALID_THREAD_ID; 601 lldb::StackFrameSP frame_sp (exe_ctx.GetFrameSP()); 602 if (frame_sp) 603 m_stack_id = frame_sp->GetStackID(); 604 else 605 m_stack_id.Clear(); 606 return *this; 607} 608 609void 610ExecutionContextRef::Clear() 611{ 612 m_target_wp.reset(); 613 m_process_wp.reset(); 614 ClearThread(); 615 ClearFrame(); 616} 617 618ExecutionContextRef::~ExecutionContextRef() 619{ 620} 621 622void 623ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp) 624{ 625 m_target_wp = target_sp; 626} 627 628void 629ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp) 630{ 631 if (process_sp) 632 { 633 m_process_wp = process_sp; 634 SetTargetSP (process_sp->GetTarget().shared_from_this()); 635 } 636 else 637 { 638 m_process_wp.reset(); 639 m_target_wp.reset(); 640 } 641} 642 643void 644ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp) 645{ 646 if (thread_sp) 647 { 648 m_thread_wp = thread_sp; 649 m_tid = thread_sp->GetID(); 650 SetProcessSP (thread_sp->GetProcess()); 651 } 652 else 653 { 654 ClearThread(); 655 m_process_wp.reset(); 656 m_target_wp.reset(); 657 } 658} 659 660void 661ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp) 662{ 663 if (frame_sp) 664 { 665 m_stack_id = frame_sp->GetStackID(); 666 SetThreadSP (frame_sp->GetThread()); 667 } 668 else 669 { 670 ClearFrame(); 671 ClearThread(); 672 m_process_wp.reset(); 673 m_target_wp.reset(); 674 } 675 676} 677 678void 679ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected) 680{ 681 Clear(); 682 if (target) 683 { 684 lldb::TargetSP target_sp (target->shared_from_this()); 685 if (target_sp) 686 { 687 m_target_wp = target_sp; 688 if (adopt_selected) 689 { 690 lldb::ProcessSP process_sp (target_sp->GetProcessSP()); 691 if (process_sp) 692 { 693 m_process_wp = process_sp; 694 if (process_sp) 695 { 696 // Only fill in the thread and frame if our process is stopped 697 if (StateIsStoppedState (process_sp->GetState(), true)) 698 { 699 lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 700 if (!thread_sp) 701 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0); 702 703 if (thread_sp) 704 { 705 SetThreadSP (thread_sp); 706 lldb::StackFrameSP frame_sp (thread_sp->GetSelectedFrame()); 707 if (!frame_sp) 708 frame_sp = thread_sp->GetStackFrameAtIndex(0); 709 if (frame_sp) 710 SetFrameSP (frame_sp); 711 } 712 } 713 } 714 } 715 } 716 } 717 } 718} 719 720void 721ExecutionContextRef::SetProcessPtr (Process *process) 722{ 723 if (process) 724 { 725 SetProcessSP(process->shared_from_this()); 726 } 727 else 728 { 729 m_process_wp.reset(); 730 m_target_wp.reset(); 731 } 732} 733 734void 735ExecutionContextRef::SetThreadPtr (Thread *thread) 736{ 737 if (thread) 738 { 739 SetThreadSP (thread->shared_from_this()); 740 } 741 else 742 { 743 ClearThread(); 744 m_process_wp.reset(); 745 m_target_wp.reset(); 746 } 747} 748 749void 750ExecutionContextRef::SetFramePtr (StackFrame *frame) 751{ 752 if (frame) 753 SetFrameSP (frame->shared_from_this()); 754 else 755 Clear(); 756} 757 758lldb::TargetSP 759ExecutionContextRef::GetTargetSP () const 760{ 761 lldb::TargetSP target_sp(m_target_wp.lock()); 762 if (target_sp && !target_sp->IsValid()) 763 target_sp.reset(); 764 return target_sp; 765} 766 767lldb::ProcessSP 768ExecutionContextRef::GetProcessSP () const 769{ 770 lldb::ProcessSP process_sp(m_process_wp.lock()); 771 if (process_sp && !process_sp->IsValid()) 772 process_sp.reset(); 773 return process_sp; 774} 775 776lldb::ThreadSP 777ExecutionContextRef::GetThreadSP () const 778{ 779 lldb::ThreadSP thread_sp (m_thread_wp.lock()); 780 781 if (m_tid != LLDB_INVALID_THREAD_ID) 782 { 783 // We check if the thread has been destroyed in cases where clients 784 // might still have shared pointer to a thread, but the thread is 785 // not valid anymore (not part of the process) 786 if (!thread_sp || !thread_sp->IsValid()) 787 { 788 lldb::ProcessSP process_sp(GetProcessSP()); 789 if (process_sp && process_sp->IsValid()) 790 { 791 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid); 792 m_thread_wp = thread_sp; 793 } 794 } 795 } 796 797 // Check that we aren't about to return an invalid thread sp. We might return a NULL thread_sp, 798 // but don't return an invalid one. 799 800 if (thread_sp && !thread_sp->IsValid()) 801 thread_sp.reset(); 802 803 return thread_sp; 804} 805 806lldb::StackFrameSP 807ExecutionContextRef::GetFrameSP () const 808{ 809 if (m_stack_id.IsValid()) 810 { 811 lldb::ThreadSP thread_sp (GetThreadSP()); 812 if (thread_sp) 813 return thread_sp->GetFrameWithStackID (m_stack_id); 814 } 815 return lldb::StackFrameSP(); 816} 817 818ExecutionContext 819ExecutionContextRef::Lock () const 820{ 821 return ExecutionContext(this); 822} 823 824 825