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