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 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 m_target_sp->GetArchitecture().GetByteOrder(); 187 if (m_process_sp) 188 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 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) 228 assert(m_target_sp); 229 #endif 230 return *m_target_sp; 231 } 232 233 Process &ExecutionContext::GetProcessRef() const { 234 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) 235 assert(m_process_sp); 236 #endif 237 return *m_process_sp; 238 } 239 240 Thread &ExecutionContext::GetThreadRef() const { 241 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) 242 assert(m_thread_sp); 243 #endif 244 return *m_thread_sp; 245 } 246 247 StackFrame &ExecutionContext::GetFrameRef() const { 248 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) 249 assert(m_frame_sp); 250 #endif 251 return *m_frame_sp; 252 } 253 254 void ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) { 255 m_target_sp = target_sp; 256 } 257 258 void ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) { 259 m_process_sp = process_sp; 260 } 261 262 void ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) { 263 m_thread_sp = thread_sp; 264 } 265 266 void ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) { 267 m_frame_sp = frame_sp; 268 } 269 270 void ExecutionContext::SetTargetPtr(Target *target) { 271 if (target) 272 m_target_sp = target->shared_from_this(); 273 else 274 m_target_sp.reset(); 275 } 276 277 void ExecutionContext::SetProcessPtr(Process *process) { 278 if (process) 279 m_process_sp = process->shared_from_this(); 280 else 281 m_process_sp.reset(); 282 } 283 284 void ExecutionContext::SetThreadPtr(Thread *thread) { 285 if (thread) 286 m_thread_sp = thread->shared_from_this(); 287 else 288 m_thread_sp.reset(); 289 } 290 291 void ExecutionContext::SetFramePtr(StackFrame *frame) { 292 if (frame) 293 m_frame_sp = frame->shared_from_this(); 294 else 295 m_frame_sp.reset(); 296 } 297 298 void ExecutionContext::SetContext(const lldb::TargetSP &target_sp, 299 bool get_process) { 300 m_target_sp = target_sp; 301 if (get_process && target_sp) 302 m_process_sp = target_sp->GetProcessSP(); 303 else 304 m_process_sp.reset(); 305 m_thread_sp.reset(); 306 m_frame_sp.reset(); 307 } 308 309 void ExecutionContext::SetContext(const lldb::ProcessSP &process_sp) { 310 m_process_sp = process_sp; 311 if (process_sp) 312 m_target_sp = process_sp->GetTarget().shared_from_this(); 313 else 314 m_target_sp.reset(); 315 m_thread_sp.reset(); 316 m_frame_sp.reset(); 317 } 318 319 void ExecutionContext::SetContext(const lldb::ThreadSP &thread_sp) { 320 m_frame_sp.reset(); 321 m_thread_sp = thread_sp; 322 if (thread_sp) { 323 m_process_sp = thread_sp->GetProcess(); 324 if (m_process_sp) 325 m_target_sp = m_process_sp->GetTarget().shared_from_this(); 326 else 327 m_target_sp.reset(); 328 } else { 329 m_target_sp.reset(); 330 m_process_sp.reset(); 331 } 332 } 333 334 void ExecutionContext::SetContext(const lldb::StackFrameSP &frame_sp) { 335 m_frame_sp = frame_sp; 336 if (frame_sp) { 337 m_thread_sp = frame_sp->CalculateThread(); 338 if (m_thread_sp) { 339 m_process_sp = m_thread_sp->GetProcess(); 340 if (m_process_sp) 341 m_target_sp = m_process_sp->GetTarget().shared_from_this(); 342 else 343 m_target_sp.reset(); 344 } else { 345 m_target_sp.reset(); 346 m_process_sp.reset(); 347 } 348 } else { 349 m_target_sp.reset(); 350 m_process_sp.reset(); 351 m_thread_sp.reset(); 352 } 353 } 354 355 ExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) { 356 if (this != &rhs) { 357 m_target_sp = rhs.m_target_sp; 358 m_process_sp = rhs.m_process_sp; 359 m_thread_sp = rhs.m_thread_sp; 360 m_frame_sp = rhs.m_frame_sp; 361 } 362 return *this; 363 } 364 365 bool ExecutionContext::operator==(const ExecutionContext &rhs) const { 366 // Check that the frame shared pointers match, or both are valid and their 367 // stack IDs match since sometimes we get new objects that represent the same 368 // frame within a thread. 369 if ((m_frame_sp == rhs.m_frame_sp) || 370 (m_frame_sp && rhs.m_frame_sp && 371 m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) { 372 // Check that the thread shared pointers match, or both are valid and their 373 // thread IDs match since sometimes we get new objects that represent the 374 // same thread within a process. 375 if ((m_thread_sp == rhs.m_thread_sp) || 376 (m_thread_sp && rhs.m_thread_sp && 377 m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) { 378 // Processes and targets don't change much 379 return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp; 380 } 381 } 382 return false; 383 } 384 385 bool ExecutionContext::operator!=(const ExecutionContext &rhs) const { 386 return !(*this == rhs); 387 } 388 389 bool ExecutionContext::HasTargetScope() const { 390 return ((bool)m_target_sp && m_target_sp->IsValid()); 391 } 392 393 bool ExecutionContext::HasProcessScope() const { 394 return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid())); 395 } 396 397 bool ExecutionContext::HasThreadScope() const { 398 return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid())); 399 } 400 401 bool ExecutionContext::HasFrameScope() const { 402 return HasThreadScope() && m_frame_sp; 403 } 404 405 ExecutionContextRef::ExecutionContextRef() 406 : m_target_wp(), m_process_wp(), m_thread_wp(), 407 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {} 408 409 ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx) 410 : m_target_wp(), m_process_wp(), m_thread_wp(), 411 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { 412 if (exe_ctx) 413 *this = *exe_ctx; 414 } 415 416 ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx) 417 : m_target_wp(), m_process_wp(), m_thread_wp(), 418 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { 419 *this = exe_ctx; 420 } 421 422 ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected) 423 : m_target_wp(), m_process_wp(), m_thread_wp(), 424 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() { 425 SetTargetPtr(target, adopt_selected); 426 } 427 428 ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs) 429 : m_target_wp(rhs.m_target_wp), m_process_wp(rhs.m_process_wp), 430 m_thread_wp(rhs.m_thread_wp), m_tid(rhs.m_tid), 431 m_stack_id(rhs.m_stack_id) {} 432 433 ExecutionContextRef &ExecutionContextRef:: 434 operator=(const ExecutionContextRef &rhs) { 435 if (this != &rhs) { 436 m_target_wp = rhs.m_target_wp; 437 m_process_wp = rhs.m_process_wp; 438 m_thread_wp = rhs.m_thread_wp; 439 m_tid = rhs.m_tid; 440 m_stack_id = rhs.m_stack_id; 441 } 442 return *this; 443 } 444 445 ExecutionContextRef &ExecutionContextRef:: 446 operator=(const ExecutionContext &exe_ctx) { 447 m_target_wp = exe_ctx.GetTargetSP(); 448 m_process_wp = exe_ctx.GetProcessSP(); 449 lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP()); 450 m_thread_wp = thread_sp; 451 if (thread_sp) 452 m_tid = thread_sp->GetID(); 453 else 454 m_tid = LLDB_INVALID_THREAD_ID; 455 lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP()); 456 if (frame_sp) 457 m_stack_id = frame_sp->GetStackID(); 458 else 459 m_stack_id.Clear(); 460 return *this; 461 } 462 463 void ExecutionContextRef::Clear() { 464 m_target_wp.reset(); 465 m_process_wp.reset(); 466 ClearThread(); 467 ClearFrame(); 468 } 469 470 ExecutionContextRef::~ExecutionContextRef() = default; 471 472 void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) { 473 m_target_wp = target_sp; 474 } 475 476 void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) { 477 if (process_sp) { 478 m_process_wp = process_sp; 479 SetTargetSP(process_sp->GetTarget().shared_from_this()); 480 } else { 481 m_process_wp.reset(); 482 m_target_wp.reset(); 483 } 484 } 485 486 void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) { 487 if (thread_sp) { 488 m_thread_wp = thread_sp; 489 m_tid = thread_sp->GetID(); 490 SetProcessSP(thread_sp->GetProcess()); 491 } else { 492 ClearThread(); 493 m_process_wp.reset(); 494 m_target_wp.reset(); 495 } 496 } 497 498 void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) { 499 if (frame_sp) { 500 m_stack_id = frame_sp->GetStackID(); 501 SetThreadSP(frame_sp->GetThread()); 502 } else { 503 ClearFrame(); 504 ClearThread(); 505 m_process_wp.reset(); 506 m_target_wp.reset(); 507 } 508 } 509 510 void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) { 511 Clear(); 512 if (target) { 513 lldb::TargetSP target_sp(target->shared_from_this()); 514 if (target_sp) { 515 m_target_wp = target_sp; 516 if (adopt_selected) { 517 lldb::ProcessSP process_sp(target_sp->GetProcessSP()); 518 if (process_sp) { 519 m_process_wp = process_sp; 520 if (process_sp) { 521 // Only fill in the thread and frame if our process is stopped 522 // Don't just check the state, since we might be in the middle of 523 // resuming. 524 Process::StopLocker stop_locker; 525 526 if (stop_locker.TryLock(&process_sp->GetRunLock()) && 527 StateIsStoppedState(process_sp->GetState(), true)) { 528 lldb::ThreadSP thread_sp( 529 process_sp->GetThreadList().GetSelectedThread()); 530 if (!thread_sp) 531 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0); 532 533 if (thread_sp) { 534 SetThreadSP(thread_sp); 535 lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame()); 536 if (!frame_sp) 537 frame_sp = thread_sp->GetStackFrameAtIndex(0); 538 if (frame_sp) 539 SetFrameSP(frame_sp); 540 } 541 } 542 } 543 } 544 } 545 } 546 } 547 } 548 549 void ExecutionContextRef::SetProcessPtr(Process *process) { 550 if (process) { 551 SetProcessSP(process->shared_from_this()); 552 } else { 553 m_process_wp.reset(); 554 m_target_wp.reset(); 555 } 556 } 557 558 void ExecutionContextRef::SetThreadPtr(Thread *thread) { 559 if (thread) { 560 SetThreadSP(thread->shared_from_this()); 561 } else { 562 ClearThread(); 563 m_process_wp.reset(); 564 m_target_wp.reset(); 565 } 566 } 567 568 void ExecutionContextRef::SetFramePtr(StackFrame *frame) { 569 if (frame) 570 SetFrameSP(frame->shared_from_this()); 571 else 572 Clear(); 573 } 574 575 lldb::TargetSP ExecutionContextRef::GetTargetSP() const { 576 lldb::TargetSP target_sp(m_target_wp.lock()); 577 if (target_sp && !target_sp->IsValid()) 578 target_sp.reset(); 579 return target_sp; 580 } 581 582 lldb::ProcessSP ExecutionContextRef::GetProcessSP() const { 583 lldb::ProcessSP process_sp(m_process_wp.lock()); 584 if (process_sp && !process_sp->IsValid()) 585 process_sp.reset(); 586 return process_sp; 587 } 588 589 lldb::ThreadSP ExecutionContextRef::GetThreadSP() const { 590 lldb::ThreadSP thread_sp(m_thread_wp.lock()); 591 592 if (m_tid != LLDB_INVALID_THREAD_ID) { 593 // We check if the thread has been destroyed in cases where clients might 594 // still have shared pointer to a thread, but the thread is not valid 595 // anymore (not part of the process) 596 if (!thread_sp || !thread_sp->IsValid()) { 597 lldb::ProcessSP process_sp(GetProcessSP()); 598 if (process_sp && process_sp->IsValid()) { 599 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid); 600 m_thread_wp = thread_sp; 601 } 602 } 603 } 604 605 // Check that we aren't about to return an invalid thread sp. We might 606 // return a nullptr thread_sp, but don't return an invalid one. 607 608 if (thread_sp && !thread_sp->IsValid()) 609 thread_sp.reset(); 610 611 return thread_sp; 612 } 613 614 lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const { 615 if (m_stack_id.IsValid()) { 616 lldb::ThreadSP thread_sp(GetThreadSP()); 617 if (thread_sp) 618 return thread_sp->GetFrameWithStackID(m_stack_id); 619 } 620 return lldb::StackFrameSP(); 621 } 622 623 ExecutionContext 624 ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const { 625 return ExecutionContext(this, thread_and_frame_only_if_stopped); 626 } 627