ThreadMemory.cpp revision a46013bde54626b68cd2013b108f73a205f4b29a
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
18using namespace lldb;
19using namespace lldb_private;
20
21ThreadMemory::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
33ThreadMemory::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
52ThreadMemory::~ThreadMemory()
53{
54    DestroyThread();
55}
56
57void
58ThreadMemory::WillResume (StateType resume_state)
59{
60    if (m_backing_thread_sp)
61        m_backing_thread_sp->WillResume(resume_state);
62}
63
64void
65ThreadMemory::ClearStackFrames ()
66{
67    if (m_backing_thread_sp)
68        m_backing_thread_sp->ClearStackFrames();
69    Thread::ClearStackFrames();
70}
71
72RegisterContextSP
73ThreadMemory::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
80RegisterContextSP
81ThreadMemory::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
259lldb::StopInfoSP
260ThreadMemory::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
307void
308ThreadMemory::RefreshStateAfterStop()
309{
310    if (m_backing_thread_sp)
311        return m_backing_thread_sp->RefreshStateAfterStop();
312}
313