1 | //===-- ThreadMemory.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 "Plugins/Process/Utility/ThreadMemory.h" |
10 | |
11 | #include "Plugins/Process/Utility/RegisterContextThreadMemory.h" |
12 | #include "lldb/Target/OperatingSystem.h" |
13 | #include "lldb/Target/Process.h" |
14 | #include "lldb/Target/RegisterContext.h" |
15 | #include "lldb/Target/StopInfo.h" |
16 | #include "lldb/Target/Unwind.h" |
17 | |
18 | #include <memory> |
19 | |
20 | using namespace lldb; |
21 | using namespace lldb_private; |
22 | |
23 | ThreadMemoryProvidingNameAndQueue::ThreadMemoryProvidingNameAndQueue( |
24 | Process &process, lldb::tid_t tid, |
25 | const ValueObjectSP &thread_info_valobj_sp) |
26 | : ThreadMemoryProvidingName(process, tid, LLDB_INVALID_ADDRESS, "" ), |
27 | m_thread_info_valobj_sp(thread_info_valobj_sp), m_queue() {} |
28 | |
29 | ThreadMemoryProvidingNameAndQueue::ThreadMemoryProvidingNameAndQueue( |
30 | Process &process, lldb::tid_t tid, llvm::StringRef name, |
31 | llvm::StringRef queue, lldb::addr_t register_data_addr) |
32 | : ThreadMemoryProvidingName(process, tid, register_data_addr, name), |
33 | m_thread_info_valobj_sp(), m_queue(std::string(queue)) {} |
34 | |
35 | ThreadMemory::~ThreadMemory() { DestroyThread(); } |
36 | |
37 | void ThreadMemory::WillResume(StateType resume_state) { |
38 | if (m_backing_thread_sp) |
39 | m_backing_thread_sp->WillResume(resume_state); |
40 | } |
41 | |
42 | void ThreadMemory::ClearStackFrames() { |
43 | if (m_backing_thread_sp) |
44 | m_backing_thread_sp->ClearStackFrames(); |
45 | Thread::ClearStackFrames(); |
46 | } |
47 | |
48 | RegisterContextSP ThreadMemory::GetRegisterContext() { |
49 | if (!m_reg_context_sp) |
50 | m_reg_context_sp = std::make_shared<RegisterContextThreadMemory>( |
51 | args&: *this, args&: m_register_data_addr); |
52 | return m_reg_context_sp; |
53 | } |
54 | |
55 | RegisterContextSP |
56 | ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) { |
57 | uint32_t concrete_frame_idx = 0; |
58 | |
59 | if (frame) |
60 | concrete_frame_idx = frame->GetConcreteFrameIndex(); |
61 | |
62 | if (concrete_frame_idx == 0) |
63 | return GetRegisterContext(); |
64 | return GetUnwinder().CreateRegisterContextForFrame(frame); |
65 | } |
66 | |
67 | bool ThreadMemory::CalculateStopInfo() { |
68 | if (m_backing_thread_sp) { |
69 | lldb::StopInfoSP backing_stop_info_sp( |
70 | m_backing_thread_sp->GetPrivateStopInfo()); |
71 | if (backing_stop_info_sp && |
72 | backing_stop_info_sp->IsValidForOperatingSystemThread(thread&: *this)) { |
73 | backing_stop_info_sp->SetThread(shared_from_this()); |
74 | SetStopInfo(backing_stop_info_sp); |
75 | return true; |
76 | } |
77 | } else { |
78 | ProcessSP process_sp(GetProcess()); |
79 | |
80 | if (process_sp) { |
81 | OperatingSystem *os = process_sp->GetOperatingSystem(); |
82 | if (os) { |
83 | SetStopInfo(os->CreateThreadStopReason(thread: this)); |
84 | return true; |
85 | } |
86 | } |
87 | } |
88 | return false; |
89 | } |
90 | |
91 | void ThreadMemory::RefreshStateAfterStop() { |
92 | if (m_backing_thread_sp) |
93 | return m_backing_thread_sp->RefreshStateAfterStop(); |
94 | |
95 | if (m_reg_context_sp) |
96 | m_reg_context_sp->InvalidateAllRegisters(); |
97 | } |
98 | |