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