ThreadMemory.cpp revision 91a9f2127fa8b8e90f6ea1676d11f97f44ce22dd
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
17using namespace lldb;
18using namespace lldb_private;
19
20ThreadMemory::ThreadMemory (Process &process,
21                            tid_t tid,
22                            const ValueObjectSP &thread_info_valobj_sp) :
23    Thread (process, tid),
24    m_thread_info_valobj_sp (thread_info_valobj_sp),
25    m_name(),
26    m_queue()
27{
28}
29
30
31ThreadMemory::ThreadMemory (Process &process,
32                            lldb::tid_t tid,
33                            const char *name,
34                            const char *queue,
35                            lldb::addr_t register_data_addr) :
36    Thread (process, tid),
37    m_thread_info_valobj_sp (),
38    m_name(),
39    m_queue(),
40    m_register_data_addr (register_data_addr)
41{
42    if (name)
43        m_name = name;
44    if (queue)
45        m_queue = queue;
46}
47
48
49ThreadMemory::~ThreadMemory()
50{
51    DestroyThread();
52}
53
54bool
55ThreadMemory::WillResume (StateType resume_state)
56{
57    ClearStackFrames();
58    // Call the Thread::WillResume first. If we stop at a signal, the stop info
59    // class for signal will set the resume signal that we need below. The signal
60    // stuff obeys the Process::UnixSignal defaults.
61    Thread::WillResume(resume_state);
62    return true;
63}
64
65RegisterContextSP
66ThreadMemory::GetRegisterContext ()
67{
68    if (!m_reg_context_sp)
69    {
70        ProcessSP process_sp (GetProcess());
71        if (process_sp)
72        {
73            OperatingSystem *os = process_sp->GetOperatingSystem ();
74            if (os)
75                m_reg_context_sp = os->CreateRegisterContextForThread (this, m_register_data_addr);
76        }
77    }
78    return m_reg_context_sp;
79}
80
81RegisterContextSP
82ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame)
83{
84    RegisterContextSP reg_ctx_sp;
85    uint32_t concrete_frame_idx = 0;
86
87    if (frame)
88        concrete_frame_idx = frame->GetConcreteFrameIndex ();
89
90    if (concrete_frame_idx == 0)
91    {
92        reg_ctx_sp = GetRegisterContext ();
93    }
94    else if (m_unwinder_ap.get())
95    {
96        reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
97    }
98    return reg_ctx_sp;
99}
100
101lldb::StopInfoSP
102ThreadMemory::GetPrivateStopReason ()
103{
104    ProcessSP process_sp (GetProcess());
105
106    if (process_sp)
107    {
108        const uint32_t process_stop_id = process_sp->GetStopID();
109        if (m_thread_stop_reason_stop_id != process_stop_id ||
110            (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
111        {
112            if (IsStillAtLastBreakpointHit())
113                return m_actual_stop_info_sp;
114
115            // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
116            // for this thread, then m_actual_stop_info_sp will not ever contain
117            // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
118            // check will never be able to tell us if we have the correct stop info
119            // for this thread and we will continually send qThreadStopInfo packets
120            // down to the remote GDB server, so we need to keep our own notion
121            // of the stop ID that m_actual_stop_info_sp is valid for (even if it
122            // contains nothing). We use m_thread_stop_reason_stop_id for this below.
123            m_thread_stop_reason_stop_id = process_stop_id;
124            m_actual_stop_info_sp.reset();
125
126            OperatingSystem *os = process_sp->GetOperatingSystem ();
127            if (os)
128                m_actual_stop_info_sp = os->CreateThreadStopReason (this);
129        }
130    }
131    return m_actual_stop_info_sp;
132
133}
134
135void
136ThreadMemory::RefreshStateAfterStop()
137{
138    RegisterContextSP reg_ctx_sp(GetRegisterContext());
139    if (reg_ctx_sp)
140    {
141        const bool force = true;
142        reg_ctx_sp->InvalidateIfNeeded (force);
143    }
144}
145