blob: a041082e28fbcd121284461e1efcdf1342cd77ca [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{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +000042 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +000043 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{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +000063 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +000064 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
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000113 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000114 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
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000168 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000169 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;
Daniel Malead601e832013-02-13 22:00:44 +0000188 case lldb::eStateStopped:
189 case lldb::eStateSuspended:
190 status = true;
191 break;
Johnny Chen2341d352012-01-05 21:48:15 +0000192 }
193
194 return status;
195}
196
197void
198POSIXThread::Notify(const ProcessMessage &message)
199{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000200 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000201 if (log)
202 log->Printf ("POSIXThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind());
203
204 switch (message.GetKind())
205 {
206 default:
207 assert(false && "Unexpected message kind!");
208 break;
209
210 case ProcessMessage::eLimboMessage:
211 LimboNotify(message);
212 break;
213
214 case ProcessMessage::eSignalMessage:
215 SignalNotify(message);
216 break;
217
218 case ProcessMessage::eSignalDeliveredMessage:
219 SignalDeliveredNotify(message);
220 break;
221
222 case ProcessMessage::eTraceMessage:
223 TraceNotify(message);
224 break;
225
226 case ProcessMessage::eBreakpointMessage:
227 BreakNotify(message);
228 break;
229
230 case ProcessMessage::eCrashMessage:
231 CrashNotify(message);
232 break;
Matt Kopecf1fda372013-01-08 16:30:18 +0000233
234 case ProcessMessage::eNewThreadMessage:
235 ThreadNotify(message);
236 break;
Johnny Chen2341d352012-01-05 21:48:15 +0000237 }
238}
239
240void
241POSIXThread::BreakNotify(const ProcessMessage &message)
242{
243 bool status;
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000244 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000245
246 assert(GetRegisterContext());
247 status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint();
248 assert(status && "Breakpoint update failed!");
249
250 // With our register state restored, resolve the breakpoint object
251 // corresponding to our current PC.
252 assert(GetRegisterContext());
253 lldb::addr_t pc = GetRegisterContext()->GetPC();
254 if (log)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000255 log->Printf ("POSIXThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
Greg Claytone5eaa302012-02-21 18:40:07 +0000256 lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
Johnny Chen2341d352012-01-05 21:48:15 +0000257 assert(bp_site);
258 lldb::break_id_t bp_id = bp_site->GetID();
259 assert(bp_site && bp_site->ValidForThisThread(this));
260
261
262 m_breakpoint = bp_site;
263 m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id);
264}
265
266void
267POSIXThread::TraceNotify(const ProcessMessage &message)
268{
269 m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
270}
271
272void
273POSIXThread::LimboNotify(const ProcessMessage &message)
274{
275 m_stop_info = lldb::StopInfoSP(new POSIXLimboStopInfo(*this));
276}
277
278void
279POSIXThread::SignalNotify(const ProcessMessage &message)
280{
281 int signo = message.GetSignal();
282
283 m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
284 SetResumeSignal(signo);
285}
286
287void
288POSIXThread::SignalDeliveredNotify(const ProcessMessage &message)
289{
290 int signo = message.GetSignal();
291
Matt Kopec3a5ac5a2013-01-08 00:13:33 +0000292 m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
Johnny Chen2341d352012-01-05 21:48:15 +0000293 SetResumeSignal(signo);
294}
295
296void
297POSIXThread::CrashNotify(const ProcessMessage &message)
298{
299 int signo = message.GetSignal();
300
301 assert(message.GetKind() == ProcessMessage::eCrashMessage);
302
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000303 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000304 if (log)
305 log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason());
306
307 m_stop_info = lldb::StopInfoSP(new POSIXCrashStopInfo(
308 *this, signo, message.GetCrashReason()));
309 SetResumeSignal(signo);
310}
311
Matt Kopecf1fda372013-01-08 16:30:18 +0000312void
313POSIXThread::ThreadNotify(const ProcessMessage &message)
314{
315 m_stop_info = lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this));
316}
317
Johnny Chen2341d352012-01-05 21:48:15 +0000318unsigned
319POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
320{
321 unsigned reg;
322 ArchSpec arch = Host::GetArchitecture();
323
324 switch (arch.GetCore())
325 {
326 default:
327 assert(false && "CPU type not supported!");
328 break;
329
330 case ArchSpec::eCore_x86_32_i386:
331 case ArchSpec::eCore_x86_32_i486:
332 case ArchSpec::eCore_x86_32_i486sx:
333 reg = RegisterContext_i386::GetRegisterIndexFromOffset(offset);
334 break;
335
336 case ArchSpec::eCore_x86_64_x86_64:
337 reg = RegisterContext_x86_64::GetRegisterIndexFromOffset(offset);
338 break;
339 }
340 return reg;
341}
342
343const char *
344POSIXThread::GetRegisterName(unsigned reg)
345{
346 const char * name;
347 ArchSpec arch = Host::GetArchitecture();
348
349 switch (arch.GetCore())
350 {
351 default:
352 assert(false && "CPU type not supported!");
353 break;
354
355 case ArchSpec::eCore_x86_32_i386:
356 case ArchSpec::eCore_x86_32_i486:
357 case ArchSpec::eCore_x86_32_i486sx:
358 name = RegisterContext_i386::GetRegisterName(reg);
359 break;
360
361 case ArchSpec::eCore_x86_64_x86_64:
362 name = RegisterContext_x86_64::GetRegisterName(reg);
363 break;
364 }
365 return name;
366}
367
368const char *
369POSIXThread::GetRegisterNameFromOffset(unsigned offset)
370{
371 return GetRegisterName(GetRegisterIndexFromOffset(offset));
372}
373