1 //===-- ExecutionContext.cpp ----------------------------------------------===// 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 17 using namespace lldb_private; 18 19 ExecutionContext::ExecutionContext() 20 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {} 21 22 ExecutionContext::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 26 ExecutionContext::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 33 ExecutionContext::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 39 ExecutionContext::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 45 ExecutionContext::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 51 ExecutionContext::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 59 ExecutionContext::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 66 ExecutionContext::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 73 ExecutionContext::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 80 ExecutionContext::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 96 ExecutionContext::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 109 ExecutionContext::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 115 ExecutionContext::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 129 ExecutionContext::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 144 ExecutionContext::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 157 ExecutionContext::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 163 ExecutionContext::ExecutionContext(ExecutionContextScope &exe_scope_ref) { 164 exe_scope_ref.CalculateExecutionContext(*this); 165 } 166 167 void ExecutionContext::Clear() { 168 m_target_sp.reset(); 169 m_process_sp.reset(); 170 m_thread_sp.reset(); 171 m_frame_sp.reset(); 172 } 173 174 ExecutionContext::~ExecutionContext() = default; 175 176 uint32_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 184 lldb::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 192 RegisterContext *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 200 Target *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 208 Process *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 216 ExecutionContextScope *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 226 Target &ExecutionContext::GetTargetRef() const { 227 assert(m_target_sp); 228 return *m_target_sp; 229 } 230 231 Process &ExecutionContext::GetProcessRef() const { 232 assert(m_process_sp); 233 return *m_process_sp; 234 } 235 236 Thread &ExecutionContext::GetThreadRef() const { 237 assert(m_thread_sp); 238 return *m_thread_sp; 239 } 240 241 StackFrame &ExecutionContext::GetFrameRef() const { 242 assert(m_frame_sp); 243 return *m_frame_sp; 244 } 245 246 void ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) { 247 m_target_sp = target_sp; 248 } 249 250 void ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) { 251 m_process_sp = process_sp; 252 } 253 254 void ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) { 255 m_thread_sp = thread_sp; 256 } 257 258 void ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) { 259 m_frame_sp = frame_sp; 260 } 261 262 void ExecutionContext::SetTargetPtr(Target *target) { 263 if (target) 264 m_target_sp = target->shared_from_this(); 265 else 266 m_target_sp.reset(); 267 } 268 269 void ExecutionContext::SetProcessPtr(Process *process) { 270 if (process) 271 m_process_sp = process->shared_from_this(); 272 else 273 m_process_sp.reset(); 274 } 275 276 void ExecutionContext::SetThreadPtr(Thread *thread) { 277 if (thread) 278 m_thread_sp = thread->shared_from_this(); 279 else 280 m_thread_sp.reset(); 281 } 282 283 void ExecutionContext::SetFramePtr(StackFrame *frame) { 284 if (frame) 285 m_frame_sp = frame->shared_from_this(); 286 else 287 m_frame_sp.reset(); 288 } 289 290 void 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 301 void 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 311 void 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 326 void 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 347 ExecutionContext &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 357 bool 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 377 bool ExecutionContext::operator!=(const ExecutionContext &rhs) const { 378 return !(*this == rhs); 379 } 380 381 bool ExecutionContext::HasTargetScope() const { 382 return ((bool)m_target_sp && m_target_sp->IsValid()); 383 } 384 385 bool ExecutionContext::HasProcessScope() const { 386 return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid())); 387 } 388 389 bool ExecutionContext::HasThreadScope() const { 390 return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid())); 391 } 392 393 bool ExecutionContext::HasFrameScope() const { 394 return HasThreadScope() && m_frame_sp; 395 } 396 397 ExecutionContextRef::ExecutionContextRef() 398 : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {} 399 400 ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx) 401 : m_target_wp(), m_process_wp(), m_thread_wp(), 402 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { 403 if (exe_ctx) 404 *this = *exe_ctx; 405 } 406 407 ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx) 408 : m_target_wp(), m_process_wp(), m_thread_wp(), 409 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { 410 *this = exe_ctx; 411 } 412 413 ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected) 414 : m_target_wp(), m_process_wp(), m_thread_wp(), 415 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { 416 SetTargetPtr(target, adopt_selected); 417 } 418 419 ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs) 420 : m_target_wp(rhs.m_target_wp), m_process_wp(rhs.m_process_wp), 421 m_thread_wp(rhs.m_thread_wp), m_tid(rhs.m_tid), 422 m_stack_id(rhs.m_stack_id) {} 423 424 ExecutionContextRef &ExecutionContextRef:: 425 operator=(const ExecutionContextRef &rhs) { 426 if (this != &rhs) { 427 m_target_wp = rhs.m_target_wp; 428 m_process_wp = rhs.m_process_wp; 429 m_thread_wp = rhs.m_thread_wp; 430 m_tid = rhs.m_tid; 431 m_stack_id = rhs.m_stack_id; 432 } 433 return *this; 434 } 435 436 ExecutionContextRef &ExecutionContextRef:: 437 operator=(const ExecutionContext &exe_ctx) { 438 m_target_wp = exe_ctx.GetTargetSP(); 439 m_process_wp = exe_ctx.GetProcessSP(); 440 lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP()); 441 m_thread_wp = thread_sp; 442 if (thread_sp) 443 m_tid = thread_sp->GetID(); 444 else 445 m_tid = LLDB_INVALID_THREAD_ID; 446 lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP()); 447 if (frame_sp) 448 m_stack_id = frame_sp->GetStackID(); 449 else 450 m_stack_id.Clear(); 451 return *this; 452 } 453 454 void ExecutionContextRef::Clear() { 455 m_target_wp.reset(); 456 m_process_wp.reset(); 457 ClearThread(); 458 ClearFrame(); 459 } 460 461 ExecutionContextRef::~ExecutionContextRef() = default; 462 463 void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) { 464 m_target_wp = target_sp; 465 } 466 467 void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) { 468 if (process_sp) { 469 m_process_wp = process_sp; 470 SetTargetSP(process_sp->GetTarget().shared_from_this()); 471 } else { 472 m_process_wp.reset(); 473 m_target_wp.reset(); 474 } 475 } 476 477 void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) { 478 if (thread_sp) { 479 m_thread_wp = thread_sp; 480 m_tid = thread_sp->GetID(); 481 SetProcessSP(thread_sp->GetProcess()); 482 } else { 483 ClearThread(); 484 m_process_wp.reset(); 485 m_target_wp.reset(); 486 } 487 } 488 489 void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) { 490 if (frame_sp) { 491 m_stack_id = frame_sp->GetStackID(); 492 SetThreadSP(frame_sp->GetThread()); 493 } else { 494 ClearFrame(); 495 ClearThread(); 496 m_process_wp.reset(); 497 m_target_wp.reset(); 498 } 499 } 500 501 void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) { 502 Clear(); 503 if (target) { 504 lldb::TargetSP target_sp(target->shared_from_this()); 505 if (target_sp) { 506 m_target_wp = target_sp; 507 if (adopt_selected) { 508 lldb::ProcessSP process_sp(target_sp->GetProcessSP()); 509 if (process_sp) { 510 m_process_wp = process_sp; 511 if (process_sp) { 512 // Only fill in the thread and frame if our process is stopped 513 // Don't just check the state, since we might be in the middle of 514 // resuming. 515 Process::StopLocker stop_locker; 516 517 if (stop_locker.TryLock(&process_sp->GetRunLock()) && 518 StateIsStoppedState(process_sp->GetState(), true)) { 519 lldb::ThreadSP thread_sp( 520 process_sp->GetThreadList().GetSelectedThread()); 521 if (!thread_sp) 522 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0); 523 524 if (thread_sp) { 525 SetThreadSP(thread_sp); 526 lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame()); 527 if (!frame_sp) 528 frame_sp = thread_sp->GetStackFrameAtIndex(0); 529 if (frame_sp) 530 SetFrameSP(frame_sp); 531 } 532 } 533 } 534 } 535 } 536 } 537 } 538 } 539 540 void ExecutionContextRef::SetProcessPtr(Process *process) { 541 if (process) { 542 SetProcessSP(process->shared_from_this()); 543 } else { 544 m_process_wp.reset(); 545 m_target_wp.reset(); 546 } 547 } 548 549 void ExecutionContextRef::SetThreadPtr(Thread *thread) { 550 if (thread) { 551 SetThreadSP(thread->shared_from_this()); 552 } else { 553 ClearThread(); 554 m_process_wp.reset(); 555 m_target_wp.reset(); 556 } 557 } 558 559 void ExecutionContextRef::SetFramePtr(StackFrame *frame) { 560 if (frame) 561 SetFrameSP(frame->shared_from_this()); 562 else 563 Clear(); 564 } 565 566 lldb::TargetSP ExecutionContextRef::GetTargetSP() const { 567 lldb::TargetSP target_sp(m_target_wp.lock()); 568 if (target_sp && !target_sp->IsValid()) 569 target_sp.reset(); 570 return target_sp; 571 } 572 573 lldb::ProcessSP ExecutionContextRef::GetProcessSP() const { 574 lldb::ProcessSP process_sp(m_process_wp.lock()); 575 if (process_sp && !process_sp->IsValid()) 576 process_sp.reset(); 577 return process_sp; 578 } 579 580 lldb::ThreadSP ExecutionContextRef::GetThreadSP() const { 581 lldb::ThreadSP thread_sp(m_thread_wp.lock()); 582 583 if (m_tid != LLDB_INVALID_THREAD_ID) { 584 // We check if the thread has been destroyed in cases where clients might 585 // still have shared pointer to a thread, but the thread is not valid 586 // anymore (not part of the process) 587 if (!thread_sp || !thread_sp->IsValid()) { 588 lldb::ProcessSP process_sp(GetProcessSP()); 589 if (process_sp && process_sp->IsValid()) { 590 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid); 591 m_thread_wp = thread_sp; 592 } 593 } 594 } 595 596 // Check that we aren't about to return an invalid thread sp. We might 597 // return a nullptr thread_sp, but don't return an invalid one. 598 599 if (thread_sp && !thread_sp->IsValid()) 600 thread_sp.reset(); 601 602 return thread_sp; 603 } 604 605 lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const { 606 if (m_stack_id.IsValid()) { 607 lldb::ThreadSP thread_sp(GetThreadSP()); 608 if (thread_sp) 609 return thread_sp->GetFrameWithStackID(m_stack_id); 610 } 611 return lldb::StackFrameSP(); 612 } 613 614 ExecutionContext 615 ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const { 616 return ExecutionContext(this, thread_and_frame_only_if_stopped); 617 } 618