blob: ce439131fb535c4e0c188f477816547d065e555e [file] [log] [blame]
Johnny Chen2341d352012-01-05 21:48:15 +00001//===-- POSIXThread.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
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Johnny Chen2341d352012-01-05 21:48:15 +000012// C Includes
13#include <errno.h>
14
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/Core/Debugger.h"
19#include "lldb/Host/Host.h"
20#include "lldb/Target/Process.h"
21#include "lldb/Target/StopInfo.h"
22#include "lldb/Target/Target.h"
23#include "POSIXStopInfo.h"
24#include "POSIXThread.h"
25#include "ProcessPOSIX.h"
26#include "ProcessPOSIXLog.h"
27#include "ProcessMonitor.h"
28#include "RegisterContext_i386.h"
29#include "RegisterContext_x86_64.h"
30#include "RegisterContextPOSIX.h"
31
32#include "UnwindLLDB.h"
33
Greg Claytone5eaa302012-02-21 18:40:07 +000034using namespace lldb;
Johnny Chen2341d352012-01-05 21:48:15 +000035using namespace lldb_private;
36
37
Greg Clayton5e91e372012-10-12 16:23:23 +000038POSIXThread::POSIXThread(Process &process, lldb::tid_t tid)
Johnny Chen2341d352012-01-05 21:48:15 +000039 : Thread(process, tid),
40 m_frame_ap(0)
41{
42 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
43 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +000044 log->Printf ("POSIXThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid);
Johnny Chen2341d352012-01-05 21:48:15 +000045}
46
47POSIXThread::~POSIXThread()
48{
49 DestroyThread();
50}
51
52ProcessMonitor &
53POSIXThread::GetMonitor()
54{
Greg Claytone5eaa302012-02-21 18:40:07 +000055 ProcessSP base = GetProcess();
56 ProcessPOSIX &process = static_cast<ProcessPOSIX&>(*base);
Johnny Chen2341d352012-01-05 21:48:15 +000057 return process.GetMonitor();
58}
59
60void
61POSIXThread::RefreshStateAfterStop()
62{
63 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
64 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
65 log->Printf ("POSIXThread::%s ()", __FUNCTION__);
66
67 // Let all threads recover from stopping and do any clean up based
68 // on the previous thread state (if any).
Greg Claytone5eaa302012-02-21 18:40:07 +000069 ProcessSP base = GetProcess();
70 ProcessPOSIX &process = static_cast<ProcessPOSIX&>(*base);
Johnny Chen2341d352012-01-05 21:48:15 +000071 process.GetThreadList().RefreshStateAfterStop();
72}
73
74const char *
75POSIXThread::GetInfo()
76{
77 return NULL;
78}
79
80lldb::RegisterContextSP
81POSIXThread::GetRegisterContext()
82{
83 if (!m_reg_context_sp)
84 {
85 ArchSpec arch = Host::GetArchitecture();
86
87 switch (arch.GetCore())
88 {
89 default:
90 assert(false && "CPU type not supported!");
91 break;
92
93 case ArchSpec::eCore_x86_32_i386:
94 case ArchSpec::eCore_x86_32_i486:
95 case ArchSpec::eCore_x86_32_i486sx:
96 m_reg_context_sp.reset(new RegisterContext_i386(*this, 0));
97 break;
98
99 case ArchSpec::eCore_x86_64_x86_64:
100 m_reg_context_sp.reset(new RegisterContext_x86_64(*this, 0));
101 break;
102 }
103 }
104 return m_reg_context_sp;
105}
106
107lldb::RegisterContextSP
108POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
109{
110 lldb::RegisterContextSP reg_ctx_sp;
111 uint32_t concrete_frame_idx = 0;
112
113 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
114 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
115 log->Printf ("POSIXThread::%s ()", __FUNCTION__);
116
117 if (frame)
118 concrete_frame_idx = frame->GetConcreteFrameIndex();
119
120 if (concrete_frame_idx == 0)
121 reg_ctx_sp = GetRegisterContext();
122 else
123 {
124 assert(GetUnwinder());
125 reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
126 }
127
128 return reg_ctx_sp;
129}
130
131lldb::StopInfoSP
132POSIXThread::GetPrivateStopReason()
133{
134 return m_stop_info;
135}
136
137Unwind *
138POSIXThread::GetUnwinder()
139{
140 if (m_unwinder_ap.get() == NULL)
141 m_unwinder_ap.reset(new UnwindLLDB(*this));
142
143 return m_unwinder_ap.get();
144}
145
146bool
147POSIXThread::WillResume(lldb::StateType resume_state)
148{
149 SetResumeState(resume_state);
150
Jim Inghama3da5722012-10-30 17:44:49 +0000151 if (!Thread::WillResume(resume_state))
152 return false;
153
Johnny Chen2341d352012-01-05 21:48:15 +0000154 if (m_unwinder_ap.get())
155 m_unwinder_ap->Clear();
Jim Inghama3da5722012-10-30 17:44:49 +0000156 Thread::ClearStackFrames();
Johnny Chen2341d352012-01-05 21:48:15 +0000157
Jim Inghama3da5722012-10-30 17:44:49 +0000158 return true;
Johnny Chen2341d352012-01-05 21:48:15 +0000159}
160
161bool
162POSIXThread::Resume()
163{
164 lldb::StateType resume_state = GetResumeState();
165 ProcessMonitor &monitor = GetMonitor();
166 bool status;
167
168 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
169 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
170 log->Printf ("POSIXThread::%s ()", __FUNCTION__);
171
172 switch (resume_state)
173 {
174 default:
175 assert(false && "Unexpected state for resume!");
176 status = false;
177 break;
178
179 case lldb::eStateRunning:
180 SetState(resume_state);
181 status = monitor.Resume(GetID(), GetResumeSignal());
182 break;
183
184 case lldb::eStateStepping:
185 SetState(resume_state);
186 status = monitor.SingleStep(GetID(), GetResumeSignal());
187 break;
188 }
189
190 return status;
191}
192
193void
194POSIXThread::Notify(const ProcessMessage &message)
195{
196 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
197 if (log)
198 log->Printf ("POSIXThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind());
199
200 switch (message.GetKind())
201 {
202 default:
203 assert(false && "Unexpected message kind!");
204 break;
205
206 case ProcessMessage::eLimboMessage:
207 LimboNotify(message);
208 break;
209
210 case ProcessMessage::eSignalMessage:
211 SignalNotify(message);
212 break;
213
214 case ProcessMessage::eSignalDeliveredMessage:
215 SignalDeliveredNotify(message);
216 break;
217
218 case ProcessMessage::eTraceMessage:
219 TraceNotify(message);
220 break;
221
222 case ProcessMessage::eBreakpointMessage:
223 BreakNotify(message);
224 break;
225
226 case ProcessMessage::eCrashMessage:
227 CrashNotify(message);
228 break;
Matt Kopecf1fda372013-01-08 16:30:18 +0000229
230 case ProcessMessage::eNewThreadMessage:
231 ThreadNotify(message);
232 break;
Johnny Chen2341d352012-01-05 21:48:15 +0000233 }
234}
235
236void
237POSIXThread::BreakNotify(const ProcessMessage &message)
238{
239 bool status;
240 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
241
242 assert(GetRegisterContext());
243 status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint();
244 assert(status && "Breakpoint update failed!");
245
246 // With our register state restored, resolve the breakpoint object
247 // corresponding to our current PC.
248 assert(GetRegisterContext());
249 lldb::addr_t pc = GetRegisterContext()->GetPC();
250 if (log)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000251 log->Printf ("POSIXThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
Greg Claytone5eaa302012-02-21 18:40:07 +0000252 lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
Johnny Chen2341d352012-01-05 21:48:15 +0000253 assert(bp_site);
254 lldb::break_id_t bp_id = bp_site->GetID();
255 assert(bp_site && bp_site->ValidForThisThread(this));
256
257
258 m_breakpoint = bp_site;
259 m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id);
260}
261
262void
263POSIXThread::TraceNotify(const ProcessMessage &message)
264{
265 m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
266}
267
268void
269POSIXThread::LimboNotify(const ProcessMessage &message)
270{
271 m_stop_info = lldb::StopInfoSP(new POSIXLimboStopInfo(*this));
272}
273
274void
275POSIXThread::SignalNotify(const ProcessMessage &message)
276{
277 int signo = message.GetSignal();
278
279 m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
280 SetResumeSignal(signo);
281}
282
283void
284POSIXThread::SignalDeliveredNotify(const ProcessMessage &message)
285{
286 int signo = message.GetSignal();
287
Matt Kopec3a5ac5a2013-01-08 00:13:33 +0000288 m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
Johnny Chen2341d352012-01-05 21:48:15 +0000289 SetResumeSignal(signo);
290}
291
292void
293POSIXThread::CrashNotify(const ProcessMessage &message)
294{
295 int signo = message.GetSignal();
296
297 assert(message.GetKind() == ProcessMessage::eCrashMessage);
298
299 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
300 if (log)
301 log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason());
302
303 m_stop_info = lldb::StopInfoSP(new POSIXCrashStopInfo(
304 *this, signo, message.GetCrashReason()));
305 SetResumeSignal(signo);
306}
307
Matt Kopecf1fda372013-01-08 16:30:18 +0000308void
309POSIXThread::ThreadNotify(const ProcessMessage &message)
310{
311 m_stop_info = lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this));
312}
313
Johnny Chen2341d352012-01-05 21:48:15 +0000314unsigned
315POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
316{
317 unsigned reg;
318 ArchSpec arch = Host::GetArchitecture();
319
320 switch (arch.GetCore())
321 {
322 default:
323 assert(false && "CPU type not supported!");
324 break;
325
326 case ArchSpec::eCore_x86_32_i386:
327 case ArchSpec::eCore_x86_32_i486:
328 case ArchSpec::eCore_x86_32_i486sx:
329 reg = RegisterContext_i386::GetRegisterIndexFromOffset(offset);
330 break;
331
332 case ArchSpec::eCore_x86_64_x86_64:
333 reg = RegisterContext_x86_64::GetRegisterIndexFromOffset(offset);
334 break;
335 }
336 return reg;
337}
338
339const char *
340POSIXThread::GetRegisterName(unsigned reg)
341{
342 const char * name;
343 ArchSpec arch = Host::GetArchitecture();
344
345 switch (arch.GetCore())
346 {
347 default:
348 assert(false && "CPU type not supported!");
349 break;
350
351 case ArchSpec::eCore_x86_32_i386:
352 case ArchSpec::eCore_x86_32_i486:
353 case ArchSpec::eCore_x86_32_i486sx:
354 name = RegisterContext_i386::GetRegisterName(reg);
355 break;
356
357 case ArchSpec::eCore_x86_64_x86_64:
358 name = RegisterContext_x86_64::GetRegisterName(reg);
359 break;
360 }
361 return name;
362}
363
364const char *
365POSIXThread::GetRegisterNameFromOffset(unsigned offset)
366{
367 return GetRegisterName(GetRegisterIndexFromOffset(offset));
368}
369