blob: 6f7cf7bc4fd3e33eec54cca0ba329d509eb28d69 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ThreadGDBRemote.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
11#include "ThreadGDBRemote.h"
12
13#include "lldb/Core/ArchSpec.h"
14#include "lldb/Core/DataExtractor.h"
15#include "lldb/Core/StreamString.h"
16#include "lldb/Target/Process.h"
17#include "lldb/Target/RegisterContext.h"
Greg Clayton643ee732010-08-04 01:40:35 +000018#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Target/Target.h"
20#include "lldb/Target/Unwind.h"
21#include "lldb/Breakpoint/WatchpointLocation.h"
22
23#include "LibUnwindRegisterContext.h"
24#include "ProcessGDBRemote.h"
25#include "ProcessGDBRemoteLog.h"
Greg Clayton54e7afa2010-07-09 20:39:50 +000026#include "Utility/StringExtractorGDBRemote.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "UnwindLibUnwind.h"
28#include "UnwindMacOSXFrameBackchain.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33//----------------------------------------------------------------------
34// Thread Registers
35//----------------------------------------------------------------------
36
37ThreadGDBRemote::ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid) :
38 Thread(process, tid),
Chris Lattner24943d22010-06-08 16:52:24 +000039 m_thread_name (),
40 m_dispatch_queue_name (),
41 m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
42 m_unwinder_ap ()
43{
44// ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD | GDBR_LOG_VERBOSE, "ThreadGDBRemote::ThreadGDBRemote ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID());
45 ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
46}
47
48ThreadGDBRemote::~ThreadGDBRemote ()
49{
50 ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
51}
52
53
54const char *
55ThreadGDBRemote::GetInfo ()
56{
57 return NULL;
58}
59
60
61const char *
62ThreadGDBRemote::GetName ()
63{
64 if (m_thread_name.empty())
65 return NULL;
66 return m_thread_name.c_str();
67}
68
69
70const char *
71ThreadGDBRemote::GetQueueName ()
72{
73 // Always re-fetch the dispatch queue name since it can change
74 if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
75 return GetGDBProcess().GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name);
76 return NULL;
77}
78
79bool
80ThreadGDBRemote::WillResume (StateType resume_state)
81{
82 // TODO: cache for next time in case we can match things up??
83 ClearStackFrames();
84 int signo = GetResumeSignal();
Greg Clayton643ee732010-08-04 01:40:35 +000085
Chris Lattner24943d22010-06-08 16:52:24 +000086 switch (resume_state)
87 {
88 case eStateSuspended:
89 case eStateStopped:
90 // Don't append anything for threads that should stay stopped.
91 break;
92
93 case eStateRunning:
94 if (m_process.GetUnixSignals().SignalIsValid (signo))
95 GetGDBProcess().m_continue_packet.Printf(";C%2.2x:%4.4x", signo, GetID());
96 else
97 GetGDBProcess().m_continue_packet.Printf(";c:%4.4x", GetID());
98 break;
99
100 case eStateStepping:
101 if (m_process.GetUnixSignals().SignalIsValid (signo))
102 GetGDBProcess().m_continue_packet.Printf(";S%2.2x:%4.4x", signo, GetID());
103 else
104 GetGDBProcess().m_continue_packet.Printf(";s:%4.4x", GetID());
105 break;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000106
107 default:
108 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000109 }
110 Thread::WillResume(resume_state);
111 return true;
112}
113
114void
115ThreadGDBRemote::RefreshStateAfterStop()
116{
117 // Invalidate all registers in our register context
118 GetRegisterContext()->Invalidate();
119}
120
121Unwind *
122ThreadGDBRemote::GetUnwinder ()
123{
124 if (m_unwinder_ap.get() == NULL)
125 {
126 const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
127 if (target_arch == ArchSpec("x86_64") || target_arch == ArchSpec("i386"))
128 {
129 m_unwinder_ap.reset (new UnwindLibUnwind (*this, GetGDBProcess().GetLibUnwindAddressSpace()));
130 }
131 else
132 {
133 m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
134 }
135 }
136 return m_unwinder_ap.get();
137}
138
139uint32_t
140ThreadGDBRemote::GetStackFrameCount()
141{
142 Unwind *unwinder = GetUnwinder ();
143 if (unwinder)
144 return unwinder->GetFrameCount();
145 return 0;
146}
147
148// Make sure that GetStackFrameAtIndex() does NOT call GetStackFrameCount() when
149// getting the stack frame at index zero! This way GetStackFrameCount() (via
150// GetStackFRameData()) can call this function to get the first frame in order
151// to provide the first frame to a lower call for efficiency sake (avoid
152// redundant lookups in the frame symbol context).
153lldb::StackFrameSP
154ThreadGDBRemote::GetStackFrameAtIndex (uint32_t idx)
155{
156
157 StackFrameSP frame_sp (m_frames.GetFrameAtIndex(idx));
158
159 if (frame_sp.get())
160 return frame_sp;
161
162 // Don't try and fetch a frame while process is running
163// FIXME: This check isn't right because IsRunning checks the Public state, but this
164// is work you need to do - for instance in ShouldStop & friends - before the public
165// state has been changed.
166// if (m_process.IsRunning())
167// return frame_sp;
168
169 // Special case the first frame (idx == 0) so that we don't need to
170 // know how many stack frames there are to get it. If we need any other
171 // frames, then we do need to know if "idx" is a valid index.
172 if (idx == 0)
173 {
174 // If this is the first frame, we want to share the thread register
175 // context with the stack frame at index zero.
176 GetRegisterContext();
177 assert (m_reg_context_sp.get());
178 frame_sp.reset (new StackFrame (idx, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), m_reg_context_sp->GetPC()));
179 }
180 else if (idx < GetStackFrameCount())
181 {
182 Unwind *unwinder = GetUnwinder ();
183 if (unwinder)
184 {
185 addr_t pc, cfa;
186 if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
187 frame_sp.reset (new StackFrame (idx, *this, cfa, pc));
188 }
189 }
190 m_frames.SetFrameAtIndex(idx, frame_sp);
191 return frame_sp;
192}
193
194void
195ThreadGDBRemote::ClearStackFrames ()
196{
197 Unwind *unwinder = GetUnwinder ();
198 if (unwinder)
199 unwinder->Clear();
200 Thread::ClearStackFrames();
201}
202
203
204bool
205ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread)
206{
207 return thread != 0;
208}
209
210void
211ThreadGDBRemote::Dump(Log *log, uint32_t index)
212{
213}
214
215
216bool
217ThreadGDBRemote::ShouldStop (bool &step_more)
218{
219 return true;
220}
221RegisterContext *
222ThreadGDBRemote::GetRegisterContext ()
223{
224 if (m_reg_context_sp.get() == NULL)
225 m_reg_context_sp.reset (CreateRegisterContextForFrame (NULL));
226 return m_reg_context_sp.get();
227}
228
229RegisterContext *
230ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame)
231{
232 const bool read_all_registers_at_once = false;
233 uint32_t frame_idx = 0;
234
235 if (frame)
236 frame_idx = frame->GetID();
237
238 if (frame_idx == 0)
239 return new GDBRemoteRegisterContext (*this, frame, GetGDBProcess().m_register_info, read_all_registers_at_once);
240 else if (m_unwinder_ap.get() && frame_idx < m_unwinder_ap->GetFrameCount())
241 return m_unwinder_ap->CreateRegisterContextForFrame (frame);
242 return NULL;
243}
244
245bool
246ThreadGDBRemote::SaveFrameZeroState (RegisterCheckpoint &checkpoint)
247{
248 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
249 if (frame_sp)
250 {
251 checkpoint.SetStackID(frame_sp->GetStackID());
252 return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData());
253 }
254 return false;
255}
256
257bool
258ThreadGDBRemote::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint)
259{
260 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
261 if (frame_sp)
262 {
263 bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData());
264 frame_sp->GetRegisterContext()->Invalidate();
265 ClearStackFrames();
266 return ret;
267 }
268 return false;
269}
270
Greg Clayton643ee732010-08-04 01:40:35 +0000271lldb::StopInfoSP
272ThreadGDBRemote::GetPrivateStopReason ()
Chris Lattner24943d22010-06-08 16:52:24 +0000273{
Greg Clayton643ee732010-08-04 01:40:35 +0000274 if (m_actual_stop_info_sp.get() == NULL || m_actual_stop_info_sp->IsValid() == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000275 {
Greg Clayton643ee732010-08-04 01:40:35 +0000276 m_actual_stop_info_sp.reset();
277
Chris Lattner24943d22010-06-08 16:52:24 +0000278 char packet[256];
Greg Clayton54e7afa2010-07-09 20:39:50 +0000279 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000280 StringExtractorGDBRemote stop_packet;
281 if (GetGDBProcess().GetGDBRemote().SendPacketAndWaitForResponse(packet, stop_packet, 1, false))
282 {
283 std::string copy(stop_packet.GetStringRef());
284 GetGDBProcess().SetThreadStopInfo (stop_packet);
Chris Lattner24943d22010-06-08 16:52:24 +0000285 }
286 }
Greg Clayton643ee732010-08-04 01:40:35 +0000287 return m_actual_stop_info_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000288}
289
290