1 //===-- ThreadMemory.cpp ----------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "Plugins/Process/Utility/ThreadMemory.h"
11 #include "lldb/Target/OperatingSystem.h"
12 #include "lldb/Target/RegisterContext.h"
13 #include "lldb/Target/Process.h"
14 #include "lldb/Target/StopInfo.h"
15 #include "lldb/Target/Unwind.h"
16 #include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 ThreadMemory::ThreadMemory (Process &process,
22                             tid_t tid,
23                             const ValueObjectSP &thread_info_valobj_sp) :
24     Thread (process, tid),
25     m_backing_thread_sp (),
26     m_thread_info_valobj_sp (thread_info_valobj_sp),
27     m_name(),
28     m_queue()
29 {
30 }
31 
32 
33 ThreadMemory::ThreadMemory (Process &process,
34                             lldb::tid_t tid,
35                             const char *name,
36                             const char *queue,
37                             lldb::addr_t register_data_addr) :
38     Thread (process, tid),
39     m_backing_thread_sp (),
40     m_thread_info_valobj_sp (),
41     m_name(),
42     m_queue(),
43     m_register_data_addr (register_data_addr)
44 {
45     if (name)
46         m_name = name;
47     if (queue)
48         m_queue = queue;
49 }
50 
51 
52 ThreadMemory::~ThreadMemory()
53 {
54     DestroyThread();
55 }
56 
57 void
58 ThreadMemory::WillResume (StateType resume_state)
59 {
60     if (m_backing_thread_sp)
61         m_backing_thread_sp->WillResume(resume_state);
62 }
63 
64 void
65 ThreadMemory::ClearStackFrames ()
66 {
67     if (m_backing_thread_sp)
68         m_backing_thread_sp->ClearStackFrames();
69     Thread::ClearStackFrames();
70 }
71 
72 RegisterContextSP
73 ThreadMemory::GetRegisterContext ()
74 {
75     if (!m_reg_context_sp)
76         m_reg_context_sp.reset (new RegisterContextThreadMemory (*this, m_register_data_addr));
77     return m_reg_context_sp;
78 }
79 
80 RegisterContextSP
81 ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame)
82 {
83     RegisterContextSP reg_ctx_sp;
84     uint32_t concrete_frame_idx = 0;
85 
86     if (frame)
87         concrete_frame_idx = frame->GetConcreteFrameIndex ();
88 
89     if (concrete_frame_idx == 0)
90     {
91         reg_ctx_sp = GetRegisterContext ();
92     }
93     else
94     {
95         Unwind *unwinder = GetUnwinder ();
96         if (unwinder)
97             reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
98     }
99     return reg_ctx_sp;
100 }
101 
102 
103 //class StopInfoThreadMemory : public StopInfo
104 //{
105 //public:
106 //    //------------------------------------------------------------------
107 //    // Constructors and Destructors
108 //    //------------------------------------------------------------------
109 //    StopInfoThreadMemory (Thread &thread,
110 //                          uint64_t value,
111 //                          StopInfoSP &backing_stop_info_sp) :
112 //    StopInfo (thread, value),
113 //    m_backing_stop_info_sp (backing_stop_info_sp)
114 //    {
115 //    }
116 //
117 //    virtual
118 //    ~StopInfoThreadMemory()
119 //    {
120 //    }
121 //
122 //    virtual bool
123 //    IsValid () const
124 //    {
125 //        ThreadSP backing_thread_sp (m_thread.GetBackingThread());
126 //        if (backing_thread_sp)
127 //            return backing_thread_sp->IsValid();
128 //        return StopInfo::IsValid();
129 //    }
130 //
131 //    virtual Thread &
132 //    GetThread()
133 //    {
134 //        return m_thread;
135 //    }
136 //
137 //    virtual const Thread &
138 //    GetThread() const
139 //    {
140 //        return m_thread;
141 //    }
142 //
143 //    virtual uint64_t
144 //    GetValue() const
145 //    {
146 //        if (m_backing_stop_info_sp)
147 //            return m_backing_stop_info_sp->GetValue();
148 //        return StopInfo::GetValue();
149 //    }
150 //
151 //    virtual lldb::StopReason
152 //    GetStopReason () const
153 //    {
154 //        if (m_backing_stop_info_sp)
155 //            return m_backing_stop_info_sp->GetStopReason();
156 //        return eStopReasonNone;
157 //    }
158 //
159 //    // ShouldStopSynchronous will get called before any thread plans are consulted, and if it says we should
160 //    // resume the target, then we will just immediately resume.  This should not run any code in or resume the
161 //    // target.
162 //
163 //    virtual bool
164 //    ShouldStopSynchronous (Event *event_ptr)
165 //    {
166 //        if (m_backing_stop_info_sp)
167 //            return m_backing_stop_info_sp->ShouldStopSynchronous(event_ptr);
168 //        return StopInfo::ShouldStopSynchronous (event_ptr);
169 //    }
170 //
171 //    // If should stop returns false, check if we should notify of this event
172 //    virtual bool
173 //    ShouldNotify (Event *event_ptr)
174 //    {
175 //        if (m_backing_stop_info_sp)
176 //            return m_backing_stop_info_sp->ShouldNotify(event_ptr);
177 //        return StopInfo::ShouldNotify (event_ptr);
178 //    }
179 //
180 //    virtual void
181 //    WillResume (lldb::StateType resume_state)
182 //    {
183 //        if (m_backing_stop_info_sp)
184 //            return m_backing_stop_info_sp->WillResume(resume_state);
185 //        return StopInfo::WillResume (resume_state);
186 //    }
187 //
188 //    virtual const char *
189 //    GetDescription ()
190 //    {
191 //        if (m_backing_stop_info_sp)
192 //            return m_backing_stop_info_sp->GetDescription();
193 //        return StopInfo::GetDescription();
194 //    }
195 //
196 //    virtual void
197 //    SetDescription (const char *desc_cstr)
198 //    {
199 //        if (m_backing_stop_info_sp)
200 //            m_backing_stop_info_sp->SetDescription(desc_cstr);
201 //        StopInfo::SetDescription(desc_cstr);
202 //    }
203 //
204 //    // Sometimes the thread plan logic will know that it wants a given stop to stop or not,
205 //    // regardless of what the ordinary logic for that StopInfo would dictate.  The main example
206 //    // of this is the ThreadPlanCallFunction, which for instance knows - based on how that particular
207 //    // expression was executed - whether it wants all breakpoints to auto-continue or not.
208 //    // Use OverrideShouldStop on the StopInfo to implement this.
209 //
210 //    virtual void
211 //    OverrideShouldStop (bool override_value)
212 //    {
213 //        if (m_backing_stop_info_sp)
214 //            m_backing_stop_info_sp->OverrideShouldStop(override_value);
215 //        StopInfo::OverrideShouldStop (override_value);
216 //    }
217 //
218 //    virtual bool
219 //    GetOverrideShouldStop()
220 //    {
221 //        if (m_backing_stop_info_sp)
222 //            return m_backing_stop_info_sp->GetOverrideShouldStop();
223 //        return StopInfo::GetOverrideShouldStop();
224 //    }
225 //
226 //    virtual bool
227 //    GetOverriddenShouldStopValue ()
228 //    {
229 //        if (m_backing_stop_info_sp)
230 //            return m_backing_stop_info_sp->GetOverriddenShouldStopValue();
231 //        return StopInfo::GetOverriddenShouldStopValue();
232 //    }
233 //
234 //    virtual void
235 //    PerformAction (Event *event_ptr)
236 //    {
237 //        if (m_backing_stop_info_sp)
238 //            return m_backing_stop_info_sp->PerformAction(event_ptr);
239 //        return StopInfo::PerformAction(event_ptr);
240 //    }
241 //
242 //    virtual bool
243 //    ShouldStop (Event *event_ptr)
244 //    {
245 //        if (m_backing_stop_info_sp)
246 //            return m_backing_stop_info_sp->ShouldStop(event_ptr);
247 //        return StopInfo::ShouldStop(event_ptr);
248 //    }
249 //
250 //
251 //protected:
252 //    StopInfoSP m_backing_stop_info_sp;
253 //
254 //private:
255 //    DISALLOW_COPY_AND_ASSIGN (StopInfoThreadMemory);
256 //};
257 
258 
259 lldb::StopInfoSP
260 ThreadMemory::GetPrivateStopReason ()
261 {
262     if (m_actual_stop_info_sp)
263         return m_actual_stop_info_sp;
264 
265     if (m_backing_thread_sp)
266     {
267         lldb::StopInfoSP backing_stop_info_sp (m_backing_thread_sp->GetPrivateStopReason());
268         if (backing_stop_info_sp)
269         {
270             m_actual_stop_info_sp = backing_stop_info_sp;
271             m_actual_stop_info_sp->SetThread (shared_from_this());
272             return m_actual_stop_info_sp;
273         }
274     }
275 
276     ProcessSP process_sp (GetProcess());
277 
278     if (process_sp)
279     {
280         const uint32_t process_stop_id = process_sp->GetStopID();
281         if (m_thread_stop_reason_stop_id != process_stop_id ||
282             (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
283         {
284             if (IsStillAtLastBreakpointHit())
285                 return m_actual_stop_info_sp;
286 
287             // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
288             // for this thread, then m_actual_stop_info_sp will not ever contain
289             // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
290             // check will never be able to tell us if we have the correct stop info
291             // for this thread and we will continually send qThreadStopInfo packets
292             // down to the remote GDB server, so we need to keep our own notion
293             // of the stop ID that m_actual_stop_info_sp is valid for (even if it
294             // contains nothing). We use m_thread_stop_reason_stop_id for this below.
295             m_thread_stop_reason_stop_id = process_stop_id;
296             m_actual_stop_info_sp.reset();
297 
298             OperatingSystem *os = process_sp->GetOperatingSystem ();
299             if (os)
300                 m_actual_stop_info_sp = os->CreateThreadStopReason (this);
301         }
302     }
303     return m_actual_stop_info_sp;
304 
305 }
306 
307 void
308 ThreadMemory::RefreshStateAfterStop()
309 {
310     if (m_backing_thread_sp)
311         return m_backing_thread_sp->RefreshStateAfterStop();
312 }
313