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