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