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