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