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 SetThreadSP (exe_ctx.GetThreadSP()); 540 SetFrameSP (exe_ctx.GetFrameSP()); 541 return *this; 542 } 543 544 void 545 ExecutionContextRef::Clear() 546 { 547 m_target_wp.reset(); 548 m_process_wp.reset(); 549 m_thread_wp.reset(); 550 m_frame_wp.reset(); 551 m_tid = LLDB_INVALID_THREAD_ID; 552 m_stack_id.Clear(); 553 } 554 555 ExecutionContextRef::~ExecutionContextRef() 556 { 557 } 558 559 void 560 ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp) 561 { 562 m_target_wp = target_sp; 563 } 564 565 void 566 ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp) 567 { 568 m_process_wp = process_sp; 569 } 570 571 void 572 ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp) 573 { 574 m_thread_wp = thread_sp; 575 if (thread_sp) 576 m_tid = thread_sp->GetID(); 577 else 578 m_tid = LLDB_INVALID_THREAD_ID; 579 } 580 581 void 582 ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp) 583 { 584 m_frame_wp = frame_sp; 585 if (frame_sp) 586 m_stack_id = frame_sp->GetStackID(); 587 else 588 m_stack_id.Clear(); 589 } 590 591 void 592 ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected) 593 { 594 Clear(); 595 if (target) 596 { 597 lldb::TargetSP target_sp (target->shared_from_this()); 598 if (target_sp) 599 { 600 m_target_wp = target_sp; 601 if (adopt_selected) 602 { 603 lldb::ProcessSP process_sp (target_sp->GetProcessSP()); 604 if (process_sp) 605 { 606 m_process_wp = process_sp; 607 if (process_sp) 608 { 609 lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 610 if (!thread_sp) 611 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0); 612 613 if (thread_sp) 614 { 615 SetThreadSP (thread_sp); 616 lldb::StackFrameSP frame_sp (thread_sp->GetSelectedFrame()); 617 if (!frame_sp) 618 frame_sp = thread_sp->GetStackFrameAtIndex(0); 619 if (frame_sp) 620 SetFrameSP (frame_sp); 621 } 622 } 623 } 624 } 625 } 626 } 627 } 628 629 void 630 ExecutionContextRef::SetProcessPtr (Process *process) 631 { 632 if (process) 633 m_process_wp = process->shared_from_this(); 634 else 635 m_process_wp.reset(); 636 } 637 638 void 639 ExecutionContextRef::SetThreadPtr (Thread *thread) 640 { 641 if (thread) 642 m_thread_wp = thread->shared_from_this(); 643 else 644 m_thread_wp.reset(); 645 } 646 647 void 648 ExecutionContextRef::SetFramePtr (StackFrame *frame) 649 { 650 if (frame) 651 m_frame_wp = frame->shared_from_this(); 652 else 653 m_frame_wp.reset(); 654 } 655 656 657 lldb::ThreadSP 658 ExecutionContextRef::GetThreadSP () const 659 { 660 lldb::ThreadSP thread_sp (m_thread_wp.lock()); 661 if (!thread_sp && m_tid != LLDB_INVALID_THREAD_ID) 662 { 663 lldb::ProcessSP process_sp(GetProcessSP()); 664 if (process_sp) 665 { 666 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid); 667 m_thread_wp = thread_sp; 668 } 669 } 670 return thread_sp; 671 } 672 673 lldb::StackFrameSP 674 ExecutionContextRef::GetFrameSP () const 675 { 676 lldb::StackFrameSP frame_sp (m_frame_wp.lock()); 677 if (!frame_sp && m_stack_id.IsValid()) 678 { 679 lldb::ThreadSP thread_sp (GetThreadSP()); 680 if (thread_sp) 681 { 682 frame_sp = thread_sp->GetFrameWithStackID (m_stack_id); 683 m_frame_wp = frame_sp; 684 } 685 } 686 return frame_sp; 687 } 688 689 ExecutionContext 690 ExecutionContextRef::Lock () const 691 { 692 return ExecutionContext(this); 693 } 694 695 696