blob: 3c75e4d682a1e6e606d20e470e936fbef6960791 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SBThread.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
Eli Friedman7a62c8b2010-06-09 07:44:37 +000010#include "lldb/API/SBThread.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12#include "lldb/API/SBSymbolContext.h"
13#include "lldb/API/SBFileSpec.h"
Greg Clayton63094e02010-06-23 01:19:29 +000014#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000015#include "lldb/Core/Stream.h"
16#include "lldb/Core/StreamFile.h"
Greg Clayton63094e02010-06-23 01:19:29 +000017#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Target/Thread.h"
19#include "lldb/Target/Process.h"
20#include "lldb/Symbol/SymbolContext.h"
21#include "lldb/Symbol/CompileUnit.h"
Greg Clayton643ee732010-08-04 01:40:35 +000022#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Target/Target.h"
24#include "lldb/Target/ThreadPlan.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Target/ThreadPlanStepInstruction.h"
26#include "lldb/Target/ThreadPlanStepOut.h"
27#include "lldb/Target/ThreadPlanStepRange.h"
28#include "lldb/Target/ThreadPlanStepInRange.h"
29
30
Eli Friedman7a62c8b2010-06-09 07:44:37 +000031#include "lldb/API/SBAddress.h"
32#include "lldb/API/SBFrame.h"
33#include "lldb/API/SBSourceManager.h"
34#include "lldb/API/SBDebugger.h"
35#include "lldb/API/SBProcess.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036
37using namespace lldb;
38using namespace lldb_private;
39
40SBThread::SBThread () :
Greg Clayton63094e02010-06-23 01:19:29 +000041 m_opaque_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +000042{
43}
44
45//----------------------------------------------------------------------
46// Thread constructor
47//----------------------------------------------------------------------
48SBThread::SBThread (const ThreadSP& lldb_object_sp) :
Greg Clayton63094e02010-06-23 01:19:29 +000049 m_opaque_sp (lldb_object_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000050{
51}
52
53SBThread::SBThread (const SBThread &rhs)
54{
Greg Clayton63094e02010-06-23 01:19:29 +000055 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000056}
57
58//----------------------------------------------------------------------
59// Destructor
60//----------------------------------------------------------------------
61SBThread::~SBThread()
62{
63}
64
65bool
66SBThread::IsValid() const
67{
Greg Clayton63094e02010-06-23 01:19:29 +000068 return m_opaque_sp != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +000069}
70
Greg Clayton43490d12010-07-30 20:12:55 +000071void
72SBThread::Clear ()
73{
74 m_opaque_sp.reset();
75}
76
77
Chris Lattner24943d22010-06-08 16:52:24 +000078StopReason
79SBThread::GetStopReason()
80{
Greg Clayton63094e02010-06-23 01:19:29 +000081 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000082 {
Greg Clayton643ee732010-08-04 01:40:35 +000083 lldb_private::StopInfo *stop_info = m_opaque_sp->GetStopInfo ();
84 if (stop_info)
85 return stop_info->GetStopReason();
Chris Lattner24943d22010-06-08 16:52:24 +000086 }
87 return eStopReasonInvalid;
88}
89
90size_t
91SBThread::GetStopDescription (char *dst, size_t dst_len)
92{
Greg Clayton63094e02010-06-23 01:19:29 +000093 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000094 {
Greg Clayton643ee732010-08-04 01:40:35 +000095 lldb_private::StopInfo *stop_info = m_opaque_sp->GetStopInfo ();
96 if (stop_info)
Chris Lattner24943d22010-06-08 16:52:24 +000097 {
Greg Clayton643ee732010-08-04 01:40:35 +000098 const char *stop_desc = stop_info->GetDescription();
Chris Lattner24943d22010-06-08 16:52:24 +000099 if (stop_desc)
100 {
101 if (dst)
102 return ::snprintf (dst, dst_len, "%s", stop_desc);
103 else
104 {
105 // NULL dst passed in, return the length needed to contain the description
106 return ::strlen (stop_desc) + 1; // Include the NULL byte for size
107 }
108 }
109 else
110 {
Chris Lattner24943d22010-06-08 16:52:24 +0000111 size_t stop_desc_len = 0;
Greg Clayton643ee732010-08-04 01:40:35 +0000112 switch (stop_info->GetStopReason())
Chris Lattner24943d22010-06-08 16:52:24 +0000113 {
114 case eStopReasonTrace:
115 case eStopReasonPlanComplete:
116 {
117 static char trace_desc[] = "step";
118 stop_desc = trace_desc;
119 stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
120 }
121 break;
122
123 case eStopReasonBreakpoint:
124 {
125 static char bp_desc[] = "breakpoint hit";
126 stop_desc = bp_desc;
127 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
128 }
129 break;
130
131 case eStopReasonWatchpoint:
132 {
133 static char wp_desc[] = "watchpoint hit";
134 stop_desc = wp_desc;
135 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
136 }
137 break;
138
139 case eStopReasonSignal:
140 {
Greg Clayton643ee732010-08-04 01:40:35 +0000141 stop_desc = m_opaque_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info->GetValue());
Chris Lattner24943d22010-06-08 16:52:24 +0000142 if (stop_desc == NULL || stop_desc[0] == '\0')
143 {
144 static char signal_desc[] = "signal";
145 stop_desc = signal_desc;
146 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
147 }
148 }
149 break;
150
151 case eStopReasonException:
152 {
153 char exc_desc[] = "exception";
154 stop_desc = exc_desc;
155 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
156 }
Greg Clayton54e7afa2010-07-09 20:39:50 +0000157 break;
158
159 default:
160 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000161 }
162
163 if (stop_desc && stop_desc[0])
164 {
165 if (dst)
166 return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
167
168 if (stop_desc_len == 0)
169 stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
170
171 return stop_desc_len;
172 }
173 }
174 }
175 }
176 if (dst)
177 *dst = 0;
178 return 0;
179}
180
181void
182SBThread::SetThread (const ThreadSP& lldb_object_sp)
183{
Greg Clayton63094e02010-06-23 01:19:29 +0000184 m_opaque_sp = lldb_object_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000185}
186
187
188lldb::tid_t
189SBThread::GetThreadID () const
190{
Greg Clayton63094e02010-06-23 01:19:29 +0000191 if (m_opaque_sp)
192 return m_opaque_sp->GetID();
Chris Lattner24943d22010-06-08 16:52:24 +0000193 else
194 return LLDB_INVALID_THREAD_ID;
195}
196
197uint32_t
198SBThread::GetIndexID () const
199{
Greg Clayton63094e02010-06-23 01:19:29 +0000200 if (m_opaque_sp)
201 return m_opaque_sp->GetIndexID();
Chris Lattner24943d22010-06-08 16:52:24 +0000202 return LLDB_INVALID_INDEX32;
203}
204const char *
205SBThread::GetName () const
206{
Greg Clayton63094e02010-06-23 01:19:29 +0000207 if (m_opaque_sp)
208 return m_opaque_sp->GetName();
Chris Lattner24943d22010-06-08 16:52:24 +0000209 return NULL;
210}
211
212const char *
213SBThread::GetQueueName () const
214{
Greg Clayton63094e02010-06-23 01:19:29 +0000215 if (m_opaque_sp)
216 return m_opaque_sp->GetQueueName();
Chris Lattner24943d22010-06-08 16:52:24 +0000217 return NULL;
218}
219
220
221void
Chris Lattner24943d22010-06-08 16:52:24 +0000222SBThread::StepOver (lldb::RunMode stop_other_threads)
223{
Greg Clayton63094e02010-06-23 01:19:29 +0000224 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000225 {
226 bool abort_other_plans = true;
Greg Clayton63094e02010-06-23 01:19:29 +0000227 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000228
229 if (frame_sp)
230 {
231 if (frame_sp->HasDebugInformation ())
232 {
233 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000234 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
Chris Lattner24943d22010-06-08 16:52:24 +0000235 eStepTypeOver,
236 sc.line_entry.range,
237 sc,
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000238 stop_other_threads,
239 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000240
241 }
242 else
243 {
Greg Clayton63094e02010-06-23 01:19:29 +0000244 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true,
Chris Lattner24943d22010-06-08 16:52:24 +0000245 abort_other_plans,
246 stop_other_threads);
247 }
248 }
249
Greg Clayton63094e02010-06-23 01:19:29 +0000250 Process &process = m_opaque_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000251 // Why do we need to set the current thread by ID here???
Jim Inghamc8332952010-08-26 21:32:51 +0000252 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000253 process.Resume();
254 }
255}
256
257void
258SBThread::StepInto (lldb::RunMode stop_other_threads)
259{
Greg Clayton63094e02010-06-23 01:19:29 +0000260 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000261 {
262 bool abort_other_plans = true;
263
Greg Clayton63094e02010-06-23 01:19:29 +0000264 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000265
266 if (frame_sp && frame_sp->HasDebugInformation ())
267 {
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000268 bool avoid_code_without_debug_info = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000269 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000270 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000271 eStepTypeInto,
272 sc.line_entry.range,
273 sc,
274 stop_other_threads,
275 avoid_code_without_debug_info);
Chris Lattner24943d22010-06-08 16:52:24 +0000276 }
277 else
278 {
Greg Clayton63094e02010-06-23 01:19:29 +0000279 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false,
Chris Lattner24943d22010-06-08 16:52:24 +0000280 abort_other_plans,
281 stop_other_threads);
282 }
283
Greg Clayton63094e02010-06-23 01:19:29 +0000284 Process &process = m_opaque_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000285 // Why do we need to set the current thread by ID here???
Jim Inghamc8332952010-08-26 21:32:51 +0000286 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000287 process.Resume();
288
289 }
290}
291
292void
293SBThread::StepOut ()
294{
Greg Clayton63094e02010-06-23 01:19:29 +0000295 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000296 {
297 bool abort_other_plans = true;
298 bool stop_other_threads = true;
299
Greg Clayton63094e02010-06-23 01:19:29 +0000300 m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion);
Chris Lattner24943d22010-06-08 16:52:24 +0000301
Greg Clayton63094e02010-06-23 01:19:29 +0000302 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000303 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000304 process.Resume();
305 }
306}
307
308void
309SBThread::StepInstruction (bool step_over)
310{
Greg Clayton63094e02010-06-23 01:19:29 +0000311 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000312 {
Greg Clayton63094e02010-06-23 01:19:29 +0000313 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
314 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000315 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000316 process.Resume();
317 }
318}
319
320void
321SBThread::RunToAddress (lldb::addr_t addr)
322{
Greg Clayton63094e02010-06-23 01:19:29 +0000323 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000324 {
325 bool abort_other_plans = true;
326 bool stop_other_threads = true;
327
328 Address target_addr (NULL, addr);
329
Greg Clayton63094e02010-06-23 01:19:29 +0000330 m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
331 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000332 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000333 process.Resume();
334 }
335
336}
337
Chris Lattner24943d22010-06-08 16:52:24 +0000338SBProcess
339SBThread::GetProcess ()
340{
341 SBProcess process;
Greg Clayton63094e02010-06-23 01:19:29 +0000342 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000343 {
344 // Have to go up to the target so we can get a shared pointer to our process...
Greg Clayton63094e02010-06-23 01:19:29 +0000345 process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000346 }
347 return process;
348}
349
350uint32_t
351SBThread::GetNumFrames ()
352{
Greg Clayton63094e02010-06-23 01:19:29 +0000353 if (m_opaque_sp)
354 return m_opaque_sp->GetStackFrameCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000355 return 0;
356}
357
358SBFrame
359SBThread::GetFrameAtIndex (uint32_t idx)
360{
361 SBFrame sb_frame;
Greg Clayton63094e02010-06-23 01:19:29 +0000362 if (m_opaque_sp)
363 sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000364 return sb_frame;
365}
366
367const lldb::SBThread &
368SBThread::operator = (const lldb::SBThread &rhs)
369{
Greg Clayton63094e02010-06-23 01:19:29 +0000370 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000371 return *this;
372}
373
374bool
375SBThread::operator == (const SBThread &rhs) const
376{
Greg Clayton63094e02010-06-23 01:19:29 +0000377 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000378}
379
380bool
381SBThread::operator != (const SBThread &rhs) const
382{
Greg Clayton63094e02010-06-23 01:19:29 +0000383 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000384}
385
386lldb_private::Thread *
387SBThread::GetLLDBObjectPtr ()
388{
Greg Clayton63094e02010-06-23 01:19:29 +0000389 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000390}
391
392const lldb_private::Thread *
393SBThread::operator->() const
394{
Greg Clayton63094e02010-06-23 01:19:29 +0000395 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000396}
397
398const lldb_private::Thread &
399SBThread::operator*() const
400{
Greg Clayton63094e02010-06-23 01:19:29 +0000401 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000402}
403
404lldb_private::Thread *
405SBThread::operator->()
406{
Greg Clayton63094e02010-06-23 01:19:29 +0000407 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000408}
409
410lldb_private::Thread &
411SBThread::operator*()
412{
Greg Clayton63094e02010-06-23 01:19:29 +0000413 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000414}