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 19 using namespace lldb_private; 20 21 ExecutionContext::ExecutionContext() : 22 m_target_sp (), 23 m_process_sp (), 24 m_thread_sp (), 25 m_frame_sp () 26 { 27 } 28 29 ExecutionContext::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 37 ExecutionContext::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 47 ExecutionContext::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 57 ExecutionContext::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 67 ExecutionContext::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 77 ExecutionContext::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 88 ExecutionContext::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 99 ExecutionContext::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 110 ExecutionContext::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 121 ExecutionContext::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 139 ExecutionContext::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 149 ExecutionContext::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 157 ExecutionContext::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 172 ExecutionContext::ExecutionContext (ExecutionContextScope *exe_scope_ptr) : 173 m_target_sp (), 174 m_process_sp (), 175 m_thread_sp (), 176 m_frame_sp () 177 { 178 if (exe_scope_ptr) 179 exe_scope_ptr->CalculateExecutionContext (*this); 180 } 181 182 ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref) 183 { 184 exe_scope_ref.CalculateExecutionContext (*this); 185 } 186 187 void 188 ExecutionContext::Clear() 189 { 190 m_target_sp.reset(); 191 m_process_sp.reset(); 192 m_thread_sp.reset(); 193 m_frame_sp.reset(); 194 } 195 196 ExecutionContext::~ExecutionContext() 197 { 198 } 199 200 uint32_t 201 ExecutionContext::GetAddressByteSize() const 202 { 203 if (m_target_sp && m_target_sp->GetArchitecture().IsValid()) 204 m_target_sp->GetArchitecture().GetAddressByteSize(); 205 if (m_process_sp) 206 m_process_sp->GetAddressByteSize(); 207 return sizeof(void *); 208 } 209 210 211 212 RegisterContext * 213 ExecutionContext::GetRegisterContext () const 214 { 215 if (m_frame_sp) 216 return m_frame_sp->GetRegisterContext().get(); 217 else if (m_thread_sp) 218 return m_thread_sp->GetRegisterContext().get(); 219 return NULL; 220 } 221 222 Target * 223 ExecutionContext::GetTargetPtr () const 224 { 225 if (m_target_sp) 226 return m_target_sp.get(); 227 if (m_process_sp) 228 return &m_process_sp->GetTarget(); 229 return NULL; 230 } 231 232 Process * 233 ExecutionContext::GetProcessPtr () const 234 { 235 if (m_process_sp) 236 return m_process_sp.get(); 237 if (m_target_sp) 238 return m_target_sp->GetProcessSP().get(); 239 return NULL; 240 } 241 242 ExecutionContextScope * 243 ExecutionContext::GetBestExecutionContextScope () const 244 { 245 if (m_frame_sp) 246 return m_frame_sp.get(); 247 if (m_thread_sp) 248 return m_thread_sp.get(); 249 if (m_process_sp) 250 return m_process_sp.get(); 251 return m_target_sp.get(); 252 } 253 254 Target & 255 ExecutionContext::GetTargetRef () const 256 { 257 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 258 assert (m_target_sp.get()); 259 #endif 260 return *m_target_sp; 261 } 262 263 Process & 264 ExecutionContext::GetProcessRef () const 265 { 266 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 267 assert (m_process_sp.get()); 268 #endif 269 return *m_process_sp; 270 } 271 272 Thread & 273 ExecutionContext::GetThreadRef () const 274 { 275 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 276 assert (m_thread_sp.get()); 277 #endif 278 return *m_thread_sp; 279 } 280 281 StackFrame & 282 ExecutionContext::GetFrameRef () const 283 { 284 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 285 assert (m_frame_sp.get()); 286 #endif 287 return *m_frame_sp; 288 } 289 290 void 291 ExecutionContext::SetTargetSP (const lldb::TargetSP &target_sp) 292 { 293 m_target_sp = target_sp; 294 } 295 296 void 297 ExecutionContext::SetProcessSP (const lldb::ProcessSP &process_sp) 298 { 299 m_process_sp = process_sp; 300 } 301 302 void 303 ExecutionContext::SetThreadSP (const lldb::ThreadSP &thread_sp) 304 { 305 m_thread_sp = thread_sp; 306 } 307 308 void 309 ExecutionContext::SetFrameSP (const lldb::StackFrameSP &frame_sp) 310 { 311 m_frame_sp = frame_sp; 312 } 313 314 void 315 ExecutionContext::SetTargetPtr (Target* target) 316 { 317 if (target) 318 m_target_sp = target->shared_from_this(); 319 else 320 m_target_sp.reset(); 321 } 322 323 void 324 ExecutionContext::SetProcessPtr (Process *process) 325 { 326 if (process) 327 m_process_sp = process->shared_from_this(); 328 else 329 m_process_sp.reset(); 330 } 331 332 void 333 ExecutionContext::SetThreadPtr (Thread *thread) 334 { 335 if (thread) 336 m_thread_sp = thread->shared_from_this(); 337 else 338 m_thread_sp.reset(); 339 } 340 341 void 342 ExecutionContext::SetFramePtr (StackFrame *frame) 343 { 344 if (frame) 345 m_frame_sp = frame->shared_from_this(); 346 else 347 m_frame_sp.reset(); 348 } 349 350 void 351 ExecutionContext::SetContext (const lldb::TargetSP &target_sp, bool get_process) 352 { 353 m_target_sp = target_sp; 354 if (get_process && target_sp) 355 m_process_sp = target_sp->GetProcessSP(); 356 else 357 m_process_sp.reset(); 358 m_thread_sp.reset(); 359 m_frame_sp.reset(); 360 } 361 362 void 363 ExecutionContext::SetContext (const lldb::ProcessSP &process_sp) 364 { 365 m_process_sp = process_sp; 366 if (process_sp) 367 m_target_sp = process_sp->GetTarget().shared_from_this(); 368 else 369 m_target_sp.reset(); 370 m_thread_sp.reset(); 371 m_frame_sp.reset(); 372 } 373 374 void 375 ExecutionContext::SetContext (const lldb::ThreadSP &thread_sp) 376 { 377 m_frame_sp.reset(); 378 m_thread_sp = thread_sp; 379 if (thread_sp) 380 { 381 m_process_sp = thread_sp->GetProcess(); 382 if (m_process_sp) 383 m_target_sp = m_process_sp->GetTarget().shared_from_this(); 384 else 385 m_target_sp.reset(); 386 } 387 else 388 { 389 m_target_sp.reset(); 390 m_process_sp.reset(); 391 } 392 } 393 394 void 395 ExecutionContext::SetContext (const lldb::StackFrameSP &frame_sp) 396 { 397 m_frame_sp = frame_sp; 398 if (frame_sp) 399 { 400 m_thread_sp = frame_sp->CalculateThread(); 401 if (m_thread_sp) 402 { 403 m_process_sp = m_thread_sp->GetProcess(); 404 if (m_process_sp) 405 m_target_sp = m_process_sp->GetTarget().shared_from_this(); 406 else 407 m_target_sp.reset(); 408 } 409 else 410 { 411 m_target_sp.reset(); 412 m_process_sp.reset(); 413 } 414 } 415 else 416 { 417 m_target_sp.reset(); 418 m_process_sp.reset(); 419 m_thread_sp.reset(); 420 } 421 } 422 423 ExecutionContext & 424 ExecutionContext::operator =(const ExecutionContext &rhs) 425 { 426 if (this != &rhs) 427 { 428 m_target_sp = rhs.m_target_sp; 429 m_process_sp = rhs.m_process_sp; 430 m_thread_sp = rhs.m_thread_sp; 431 m_frame_sp = rhs.m_frame_sp; 432 } 433 return *this; 434 } 435 436 bool 437 ExecutionContext::operator ==(const ExecutionContext &rhs) const 438 { 439 // Check that the frame shared pointers match, or both are valid and their stack 440 // IDs match since sometimes we get new objects that represent the same 441 // frame within a thread. 442 if ((m_frame_sp == rhs.m_frame_sp) || (m_frame_sp && rhs.m_frame_sp && m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) 443 { 444 // Check that the thread shared pointers match, or both are valid and 445 // their thread IDs match since sometimes we get new objects that 446 // represent the same thread within a process. 447 if ((m_thread_sp == rhs.m_thread_sp) || (m_thread_sp && rhs.m_thread_sp && m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) 448 { 449 // Processes and targets don't change much 450 return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp; 451 } 452 } 453 return false; 454 } 455 456 bool 457 ExecutionContext::operator !=(const ExecutionContext &rhs) const 458 { 459 return !(*this == rhs); 460 } 461 462 463 ExecutionContextRef::ExecutionContextRef() : 464 m_target_wp (), 465 m_process_wp (), 466 m_thread_wp (), 467 m_frame_wp (), 468 m_tid(LLDB_INVALID_THREAD_ID), 469 m_stack_id () 470 { 471 } 472 473 ExecutionContextRef::ExecutionContextRef (const ExecutionContext *exe_ctx) : 474 m_target_wp (), 475 m_process_wp (), 476 m_thread_wp (), 477 m_frame_wp (), 478 m_tid(LLDB_INVALID_THREAD_ID), 479 m_stack_id () 480 { 481 if (exe_ctx) 482 *this = *exe_ctx; 483 } 484 485 ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) : 486 m_target_wp (), 487 m_process_wp (), 488 m_thread_wp (), 489 m_frame_wp (), 490 m_tid(LLDB_INVALID_THREAD_ID), 491 m_stack_id () 492 { 493 *this = exe_ctx; 494 } 495 496 497 ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) : 498 m_target_wp(), 499 m_process_wp(), 500 m_thread_wp(), 501 m_frame_wp(), 502 m_tid(LLDB_INVALID_THREAD_ID), 503 m_stack_id () 504 { 505 SetTargetPtr (target, adopt_selected); 506 } 507 508 509 510 511 ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) : 512 m_target_wp (rhs.m_target_wp), 513 m_process_wp(rhs.m_process_wp), 514 m_thread_wp (rhs.m_thread_wp), 515 m_frame_wp (rhs.m_frame_wp), 516 m_tid (rhs.m_tid), 517 m_stack_id (rhs.m_stack_id) 518 { 519 } 520 521 ExecutionContextRef & 522 ExecutionContextRef::operator =(const ExecutionContextRef &rhs) 523 { 524 if (this != &rhs) 525 { 526 m_target_wp = rhs.m_target_wp; 527 m_process_wp = rhs.m_process_wp; 528 m_thread_wp = rhs.m_thread_wp; 529 m_frame_wp = rhs.m_frame_wp; 530 m_tid = rhs.m_tid; 531 m_stack_id = rhs.m_stack_id; 532 } 533 return *this; 534 } 535 536 ExecutionContextRef & 537 ExecutionContextRef::operator =(const ExecutionContext &exe_ctx) 538 { 539 m_target_wp = exe_ctx.GetTargetSP(); 540 m_process_wp = exe_ctx.GetProcessSP(); 541 lldb::ThreadSP thread_sp (exe_ctx.GetThreadSP()); 542 m_thread_wp = thread_sp; 543 if (thread_sp) 544 m_tid = thread_sp->GetID(); 545 else 546 m_tid = LLDB_INVALID_THREAD_ID; 547 lldb::StackFrameSP frame_sp (exe_ctx.GetFrameSP()); 548 m_frame_wp = frame_sp; 549 if (frame_sp) 550 m_stack_id = frame_sp->GetStackID(); 551 else 552 m_stack_id.Clear(); 553 return *this; 554 } 555 556 void 557 ExecutionContextRef::Clear() 558 { 559 m_target_wp.reset(); 560 m_process_wp.reset(); 561 ClearThread(); 562 ClearFrame(); 563 } 564 565 ExecutionContextRef::~ExecutionContextRef() 566 { 567 } 568 569 void 570 ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp) 571 { 572 m_target_wp = target_sp; 573 } 574 575 void 576 ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp) 577 { 578 if (process_sp) 579 { 580 m_process_wp = process_sp; 581 SetTargetSP (process_sp->GetTarget().shared_from_this()); 582 } 583 else 584 { 585 m_process_wp.reset(); 586 m_target_wp.reset(); 587 } 588 } 589 590 void 591 ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp) 592 { 593 if (thread_sp) 594 { 595 m_thread_wp = thread_sp; 596 m_tid = thread_sp->GetID(); 597 SetProcessSP (thread_sp->GetProcess()); 598 } 599 else 600 { 601 ClearThread(); 602 m_process_wp.reset(); 603 m_target_wp.reset(); 604 } 605 } 606 607 void 608 ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp) 609 { 610 if (frame_sp) 611 { 612 m_frame_wp = frame_sp; 613 m_stack_id = frame_sp->GetStackID(); 614 SetThreadSP (frame_sp->GetThread()); 615 } 616 else 617 { 618 ClearFrame(); 619 ClearThread(); 620 m_process_wp.reset(); 621 m_target_wp.reset(); 622 } 623 624 } 625 626 void 627 ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected) 628 { 629 Clear(); 630 if (target) 631 { 632 lldb::TargetSP target_sp (target->shared_from_this()); 633 if (target_sp) 634 { 635 m_target_wp = target_sp; 636 if (adopt_selected) 637 { 638 lldb::ProcessSP process_sp (target_sp->GetProcessSP()); 639 if (process_sp) 640 { 641 m_process_wp = process_sp; 642 if (process_sp) 643 { 644 // Only fill in the thread and frame if our process is stopped 645 if (StateIsStoppedState (process_sp->GetState(), true)) 646 { 647 lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 648 if (!thread_sp) 649 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0); 650 651 if (thread_sp) 652 { 653 SetThreadSP (thread_sp); 654 lldb::StackFrameSP frame_sp (thread_sp->GetSelectedFrame()); 655 if (!frame_sp) 656 frame_sp = thread_sp->GetStackFrameAtIndex(0); 657 if (frame_sp) 658 SetFrameSP (frame_sp); 659 } 660 } 661 } 662 } 663 } 664 } 665 } 666 } 667 668 void 669 ExecutionContextRef::SetProcessPtr (Process *process) 670 { 671 if (process) 672 { 673 SetProcessSP(process->shared_from_this()); 674 } 675 else 676 { 677 m_process_wp.reset(); 678 m_target_wp.reset(); 679 } 680 } 681 682 void 683 ExecutionContextRef::SetThreadPtr (Thread *thread) 684 { 685 if (thread) 686 { 687 SetThreadSP (thread->shared_from_this()); 688 } 689 else 690 { 691 ClearThread(); 692 m_process_wp.reset(); 693 m_target_wp.reset(); 694 } 695 } 696 697 void 698 ExecutionContextRef::SetFramePtr (StackFrame *frame) 699 { 700 if (frame) 701 SetFrameSP (frame->shared_from_this()); 702 else 703 Clear(); 704 } 705 706 707 lldb::ThreadSP 708 ExecutionContextRef::GetThreadSP () const 709 { 710 lldb::ThreadSP thread_sp (m_thread_wp.lock()); 711 if (m_tid != LLDB_INVALID_THREAD_ID) 712 { 713 // We check if the thread has been destroyed in cases where clients 714 // might still have shared pointer to a thread, but the thread is 715 // not valid anymore (not part of the process) 716 if (!thread_sp || !thread_sp->IsValid()) 717 { 718 lldb::ProcessSP process_sp(GetProcessSP()); 719 if (process_sp) 720 { 721 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid); 722 m_thread_wp = thread_sp; 723 } 724 } 725 } 726 return thread_sp; 727 } 728 729 lldb::StackFrameSP 730 ExecutionContextRef::GetFrameSP () const 731 { 732 lldb::StackFrameSP frame_sp (m_frame_wp.lock()); 733 if (!frame_sp && m_stack_id.IsValid()) 734 { 735 lldb::ThreadSP thread_sp (GetThreadSP()); 736 if (thread_sp) 737 { 738 frame_sp = thread_sp->GetFrameWithStackID (m_stack_id); 739 m_frame_wp = frame_sp; 740 } 741 } 742 return frame_sp; 743 } 744 745 ExecutionContext 746 ExecutionContextRef::Lock () const 747 { 748 return ExecutionContext(this); 749 } 750 751 752