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