blob: c1b5fa47d9331bb6e937ae98e609869e2951c851 [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"
Jason Molenda8132f2d2010-11-04 09:51:29 +000029#include "UnwindLLDB.h"
Chris Lattner24943d22010-06-08 16:52:24 +000030
31using namespace lldb;
32using namespace lldb_private;
33
34//----------------------------------------------------------------------
35// Thread Registers
36//----------------------------------------------------------------------
37
38ThreadGDBRemote::ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid) :
39 Thread(process, tid),
Chris Lattner24943d22010-06-08 16:52:24 +000040 m_thread_name (),
41 m_dispatch_queue_name (),
Jim Ingham71219082010-08-12 02:14:28 +000042 m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
Chris Lattner24943d22010-06-08 16:52:24 +000043{
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());
Jim Inghamcdea2362010-11-18 02:47:07 +000051 DestroyThread();
Chris Lattner24943d22010-06-08 16:52:24 +000052}
53
54
55const char *
56ThreadGDBRemote::GetInfo ()
57{
58 return NULL;
59}
60
61
62const char *
63ThreadGDBRemote::GetName ()
64{
65 if (m_thread_name.empty())
66 return NULL;
67 return m_thread_name.c_str();
68}
69
70
71const char *
72ThreadGDBRemote::GetQueueName ()
73{
74 // Always re-fetch the dispatch queue name since it can change
75 if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
76 return GetGDBProcess().GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name);
77 return NULL;
78}
79
80bool
81ThreadGDBRemote::WillResume (StateType resume_state)
82{
Chris Lattner24943d22010-06-08 16:52:24 +000083 ClearStackFrames();
Greg Clayton8f6be2a2010-10-09 01:40:57 +000084 // Call the Thread::WillResume first. If we stop at a signal, the stop info
85 // class for signal will set the resume signal that we need below. The signal
86 // stuff obeys the Process::UnixSignal defaults.
87 Thread::WillResume(resume_state);
88
Chris Lattner24943d22010-06-08 16:52:24 +000089 int signo = GetResumeSignal();
Greg Clayton643ee732010-08-04 01:40:35 +000090
Chris Lattner24943d22010-06-08 16:52:24 +000091 switch (resume_state)
92 {
93 case eStateSuspended:
94 case eStateStopped:
95 // Don't append anything for threads that should stay stopped.
96 break;
97
98 case eStateRunning:
99 if (m_process.GetUnixSignals().SignalIsValid (signo))
100 GetGDBProcess().m_continue_packet.Printf(";C%2.2x:%4.4x", signo, GetID());
101 else
102 GetGDBProcess().m_continue_packet.Printf(";c:%4.4x", GetID());
103 break;
104
105 case eStateStepping:
106 if (m_process.GetUnixSignals().SignalIsValid (signo))
107 GetGDBProcess().m_continue_packet.Printf(";S%2.2x:%4.4x", signo, GetID());
108 else
109 GetGDBProcess().m_continue_packet.Printf(";s:%4.4x", GetID());
110 break;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000111
112 default:
113 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000114 }
Chris Lattner24943d22010-06-08 16:52:24 +0000115 return true;
116}
117
118void
119ThreadGDBRemote::RefreshStateAfterStop()
120{
121 // Invalidate all registers in our register context
122 GetRegisterContext()->Invalidate();
123}
124
Jason Molenda8132f2d2010-11-04 09:51:29 +0000125// Whether to use the new native unwinder (UnwindLLDB) or the libunwind-remote based unwinder for
126// stack walks on i386/x86_64
Jason Molendadc7422c2010-11-04 22:29:24 +0000127#define USE_NATIVE_UNWINDER
Jason Molenda8132f2d2010-11-04 09:51:29 +0000128
Chris Lattner24943d22010-06-08 16:52:24 +0000129Unwind *
130ThreadGDBRemote::GetUnwinder ()
131{
132 if (m_unwinder_ap.get() == NULL)
133 {
134 const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
135 if (target_arch == ArchSpec("x86_64") || target_arch == ArchSpec("i386"))
136 {
Jason Molenda8132f2d2010-11-04 09:51:29 +0000137#if defined (USE_NATIVE_UNWINDER)
138 m_unwinder_ap.reset (new UnwindLLDB (*this));
139#else
Jason Molenda96829fb2010-11-04 09:46:43 +0000140 m_unwinder_ap.reset (new UnwindLibUnwind (*this, GetGDBProcess().GetLibUnwindAddressSpace()));
Jason Molenda8132f2d2010-11-04 09:51:29 +0000141#endif
Chris Lattner24943d22010-06-08 16:52:24 +0000142 }
143 else
144 {
145 m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
146 }
147 }
148 return m_unwinder_ap.get();
149}
150
Chris Lattner24943d22010-06-08 16:52:24 +0000151void
152ThreadGDBRemote::ClearStackFrames ()
153{
154 Unwind *unwinder = GetUnwinder ();
155 if (unwinder)
156 unwinder->Clear();
157 Thread::ClearStackFrames();
158}
159
160
161bool
162ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread)
163{
164 return thread != 0;
165}
166
167void
168ThreadGDBRemote::Dump(Log *log, uint32_t index)
169{
170}
171
172
173bool
174ThreadGDBRemote::ShouldStop (bool &step_more)
175{
176 return true;
177}
178RegisterContext *
179ThreadGDBRemote::GetRegisterContext ()
180{
181 if (m_reg_context_sp.get() == NULL)
182 m_reg_context_sp.reset (CreateRegisterContextForFrame (NULL));
183 return m_reg_context_sp.get();
184}
185
186RegisterContext *
187ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame)
188{
189 const bool read_all_registers_at_once = false;
190 uint32_t frame_idx = 0;
191
192 if (frame)
Greg Clayton33ed1702010-08-24 00:45:41 +0000193 frame_idx = frame->GetFrameIndex ();
Chris Lattner24943d22010-06-08 16:52:24 +0000194
195 if (frame_idx == 0)
196 return new GDBRemoteRegisterContext (*this, frame, GetGDBProcess().m_register_info, read_all_registers_at_once);
Greg Clayton33ed1702010-08-24 00:45:41 +0000197 else if (m_unwinder_ap.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000198 return m_unwinder_ap->CreateRegisterContextForFrame (frame);
199 return NULL;
200}
201
202bool
203ThreadGDBRemote::SaveFrameZeroState (RegisterCheckpoint &checkpoint)
204{
205 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
206 if (frame_sp)
207 {
208 checkpoint.SetStackID(frame_sp->GetStackID());
209 return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData());
210 }
211 return false;
212}
213
214bool
215ThreadGDBRemote::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint)
216{
217 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
218 if (frame_sp)
219 {
220 bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData());
221 frame_sp->GetRegisterContext()->Invalidate();
222 ClearStackFrames();
223 return ret;
224 }
225 return false;
226}
227
Greg Clayton643ee732010-08-04 01:40:35 +0000228lldb::StopInfoSP
229ThreadGDBRemote::GetPrivateStopReason ()
Chris Lattner24943d22010-06-08 16:52:24 +0000230{
Greg Clayton643ee732010-08-04 01:40:35 +0000231 if (m_actual_stop_info_sp.get() == NULL || m_actual_stop_info_sp->IsValid() == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000232 {
Greg Clayton643ee732010-08-04 01:40:35 +0000233 m_actual_stop_info_sp.reset();
234
Chris Lattner24943d22010-06-08 16:52:24 +0000235 char packet[256];
Greg Clayton54e7afa2010-07-09 20:39:50 +0000236 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000237 StringExtractorGDBRemote stop_packet;
238 if (GetGDBProcess().GetGDBRemote().SendPacketAndWaitForResponse(packet, stop_packet, 1, false))
239 {
240 std::string copy(stop_packet.GetStringRef());
241 GetGDBProcess().SetThreadStopInfo (stop_packet);
Chris Lattner24943d22010-06-08 16:52:24 +0000242 }
243 }
Greg Clayton643ee732010-08-04 01:40:35 +0000244 return m_actual_stop_info_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000245}
246
247