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