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(), m_stack_id() { 402 if (exe_ctx) 403 *this = *exe_ctx; 404 } 405 406 ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx) 407 : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() { 408 *this = exe_ctx; 409 } 410 411 ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected) 412 : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() { 413 SetTargetPtr(target, adopt_selected); 414 } 415 416 ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs) 417 : m_target_wp(rhs.m_target_wp), m_process_wp(rhs.m_process_wp), 418 m_thread_wp(rhs.m_thread_wp), m_tid(rhs.m_tid), 419 m_stack_id(rhs.m_stack_id) {} 420 421 ExecutionContextRef &ExecutionContextRef:: 422 operator=(const ExecutionContextRef &rhs) { 423 if (this != &rhs) { 424 m_target_wp = rhs.m_target_wp; 425 m_process_wp = rhs.m_process_wp; 426 m_thread_wp = rhs.m_thread_wp; 427 m_tid = rhs.m_tid; 428 m_stack_id = rhs.m_stack_id; 429 } 430 return *this; 431 } 432 433 ExecutionContextRef &ExecutionContextRef:: 434 operator=(const ExecutionContext &exe_ctx) { 435 m_target_wp = exe_ctx.GetTargetSP(); 436 m_process_wp = exe_ctx.GetProcessSP(); 437 lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP()); 438 m_thread_wp = thread_sp; 439 if (thread_sp) 440 m_tid = thread_sp->GetID(); 441 else 442 m_tid = LLDB_INVALID_THREAD_ID; 443 lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP()); 444 if (frame_sp) 445 m_stack_id = frame_sp->GetStackID(); 446 else 447 m_stack_id.Clear(); 448 return *this; 449 } 450 451 void ExecutionContextRef::Clear() { 452 m_target_wp.reset(); 453 m_process_wp.reset(); 454 ClearThread(); 455 ClearFrame(); 456 } 457 458 ExecutionContextRef::~ExecutionContextRef() = default; 459 460 void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) { 461 m_target_wp = target_sp; 462 } 463 464 void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) { 465 if (process_sp) { 466 m_process_wp = process_sp; 467 SetTargetSP(process_sp->GetTarget().shared_from_this()); 468 } else { 469 m_process_wp.reset(); 470 m_target_wp.reset(); 471 } 472 } 473 474 void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) { 475 if (thread_sp) { 476 m_thread_wp = thread_sp; 477 m_tid = thread_sp->GetID(); 478 SetProcessSP(thread_sp->GetProcess()); 479 } else { 480 ClearThread(); 481 m_process_wp.reset(); 482 m_target_wp.reset(); 483 } 484 } 485 486 void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) { 487 if (frame_sp) { 488 m_stack_id = frame_sp->GetStackID(); 489 SetThreadSP(frame_sp->GetThread()); 490 } else { 491 ClearFrame(); 492 ClearThread(); 493 m_process_wp.reset(); 494 m_target_wp.reset(); 495 } 496 } 497 498 void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) { 499 Clear(); 500 if (target) { 501 lldb::TargetSP target_sp(target->shared_from_this()); 502 if (target_sp) { 503 m_target_wp = target_sp; 504 if (adopt_selected) { 505 lldb::ProcessSP process_sp(target_sp->GetProcessSP()); 506 if (process_sp) { 507 m_process_wp = process_sp; 508 if (process_sp) { 509 // Only fill in the thread and frame if our process is stopped 510 // Don't just check the state, since we might be in the middle of 511 // resuming. 512 Process::StopLocker stop_locker; 513 514 if (stop_locker.TryLock(&process_sp->GetRunLock()) && 515 StateIsStoppedState(process_sp->GetState(), true)) { 516 lldb::ThreadSP thread_sp( 517 process_sp->GetThreadList().GetSelectedThread()); 518 if (!thread_sp) 519 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0); 520 521 if (thread_sp) { 522 SetThreadSP(thread_sp); 523 lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame()); 524 if (!frame_sp) 525 frame_sp = thread_sp->GetStackFrameAtIndex(0); 526 if (frame_sp) 527 SetFrameSP(frame_sp); 528 } 529 } 530 } 531 } 532 } 533 } 534 } 535 } 536 537 void ExecutionContextRef::SetProcessPtr(Process *process) { 538 if (process) { 539 SetProcessSP(process->shared_from_this()); 540 } else { 541 m_process_wp.reset(); 542 m_target_wp.reset(); 543 } 544 } 545 546 void ExecutionContextRef::SetThreadPtr(Thread *thread) { 547 if (thread) { 548 SetThreadSP(thread->shared_from_this()); 549 } else { 550 ClearThread(); 551 m_process_wp.reset(); 552 m_target_wp.reset(); 553 } 554 } 555 556 void ExecutionContextRef::SetFramePtr(StackFrame *frame) { 557 if (frame) 558 SetFrameSP(frame->shared_from_this()); 559 else 560 Clear(); 561 } 562 563 lldb::TargetSP ExecutionContextRef::GetTargetSP() const { 564 lldb::TargetSP target_sp(m_target_wp.lock()); 565 if (target_sp && !target_sp->IsValid()) 566 target_sp.reset(); 567 return target_sp; 568 } 569 570 lldb::ProcessSP ExecutionContextRef::GetProcessSP() const { 571 lldb::ProcessSP process_sp(m_process_wp.lock()); 572 if (process_sp && !process_sp->IsValid()) 573 process_sp.reset(); 574 return process_sp; 575 } 576 577 lldb::ThreadSP ExecutionContextRef::GetThreadSP() const { 578 lldb::ThreadSP thread_sp(m_thread_wp.lock()); 579 580 if (m_tid != LLDB_INVALID_THREAD_ID) { 581 // We check if the thread has been destroyed in cases where clients might 582 // still have shared pointer to a thread, but the thread is not valid 583 // anymore (not part of the process) 584 if (!thread_sp || !thread_sp->IsValid()) { 585 lldb::ProcessSP process_sp(GetProcessSP()); 586 if (process_sp && process_sp->IsValid()) { 587 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid); 588 m_thread_wp = thread_sp; 589 } 590 } 591 } 592 593 // Check that we aren't about to return an invalid thread sp. We might 594 // return a nullptr thread_sp, but don't return an invalid one. 595 596 if (thread_sp && !thread_sp->IsValid()) 597 thread_sp.reset(); 598 599 return thread_sp; 600 } 601 602 lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const { 603 if (m_stack_id.IsValid()) { 604 lldb::ThreadSP thread_sp(GetThreadSP()); 605 if (thread_sp) 606 return thread_sp->GetFrameWithStackID(m_stack_id); 607 } 608 return lldb::StackFrameSP(); 609 } 610 611 ExecutionContext 612 ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const { 613 return ExecutionContext(this, thread_and_frame_only_if_stopped); 614 } 615