blob: 8c74a34cdbec6d61469a47e06a3dde54569052ee [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"
Caroline Tice98f930f2010-09-20 05:20:02 +000014#include "lldb/API/SBStream.h"
Greg Clayton63094e02010-06-23 01:19:29 +000015#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Core/Stream.h"
17#include "lldb/Core/StreamFile.h"
Greg Clayton63094e02010-06-23 01:19:29 +000018#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Target/Thread.h"
20#include "lldb/Target/Process.h"
21#include "lldb/Symbol/SymbolContext.h"
22#include "lldb/Symbol/CompileUnit.h"
Greg Clayton643ee732010-08-04 01:40:35 +000023#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Target/Target.h"
25#include "lldb/Target/ThreadPlan.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026#include "lldb/Target/ThreadPlanStepInstruction.h"
27#include "lldb/Target/ThreadPlanStepOut.h"
28#include "lldb/Target/ThreadPlanStepRange.h"
29#include "lldb/Target/ThreadPlanStepInRange.h"
30
31
Eli Friedman7a62c8b2010-06-09 07:44:37 +000032#include "lldb/API/SBAddress.h"
33#include "lldb/API/SBFrame.h"
34#include "lldb/API/SBSourceManager.h"
35#include "lldb/API/SBDebugger.h"
36#include "lldb/API/SBProcess.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
38using namespace lldb;
39using namespace lldb_private;
40
41SBThread::SBThread () :
Greg Clayton63094e02010-06-23 01:19:29 +000042 m_opaque_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +000043{
44}
45
46//----------------------------------------------------------------------
47// Thread constructor
48//----------------------------------------------------------------------
49SBThread::SBThread (const ThreadSP& lldb_object_sp) :
Greg Clayton63094e02010-06-23 01:19:29 +000050 m_opaque_sp (lldb_object_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000051{
52}
53
54SBThread::SBThread (const SBThread &rhs)
55{
Greg Clayton63094e02010-06-23 01:19:29 +000056 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000057}
58
59//----------------------------------------------------------------------
60// Destructor
61//----------------------------------------------------------------------
62SBThread::~SBThread()
63{
64}
65
66bool
67SBThread::IsValid() const
68{
Greg Clayton63094e02010-06-23 01:19:29 +000069 return m_opaque_sp != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +000070}
71
Greg Clayton43490d12010-07-30 20:12:55 +000072void
73SBThread::Clear ()
74{
75 m_opaque_sp.reset();
76}
77
78
Chris Lattner24943d22010-06-08 16:52:24 +000079StopReason
80SBThread::GetStopReason()
81{
Greg Clayton63094e02010-06-23 01:19:29 +000082 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000083 {
Greg Clayton643ee732010-08-04 01:40:35 +000084 lldb_private::StopInfo *stop_info = m_opaque_sp->GetStopInfo ();
85 if (stop_info)
86 return stop_info->GetStopReason();
Chris Lattner24943d22010-06-08 16:52:24 +000087 }
88 return eStopReasonInvalid;
89}
90
91size_t
92SBThread::GetStopDescription (char *dst, size_t dst_len)
93{
Greg Clayton63094e02010-06-23 01:19:29 +000094 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000095 {
Greg Clayton643ee732010-08-04 01:40:35 +000096 lldb_private::StopInfo *stop_info = m_opaque_sp->GetStopInfo ();
97 if (stop_info)
Chris Lattner24943d22010-06-08 16:52:24 +000098 {
Greg Clayton643ee732010-08-04 01:40:35 +000099 const char *stop_desc = stop_info->GetDescription();
Chris Lattner24943d22010-06-08 16:52:24 +0000100 if (stop_desc)
101 {
102 if (dst)
103 return ::snprintf (dst, dst_len, "%s", stop_desc);
104 else
105 {
106 // NULL dst passed in, return the length needed to contain the description
107 return ::strlen (stop_desc) + 1; // Include the NULL byte for size
108 }
109 }
110 else
111 {
Chris Lattner24943d22010-06-08 16:52:24 +0000112 size_t stop_desc_len = 0;
Greg Clayton643ee732010-08-04 01:40:35 +0000113 switch (stop_info->GetStopReason())
Chris Lattner24943d22010-06-08 16:52:24 +0000114 {
115 case eStopReasonTrace:
116 case eStopReasonPlanComplete:
117 {
118 static char trace_desc[] = "step";
119 stop_desc = trace_desc;
120 stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
121 }
122 break;
123
124 case eStopReasonBreakpoint:
125 {
126 static char bp_desc[] = "breakpoint hit";
127 stop_desc = bp_desc;
128 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
129 }
130 break;
131
132 case eStopReasonWatchpoint:
133 {
134 static char wp_desc[] = "watchpoint hit";
135 stop_desc = wp_desc;
136 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
137 }
138 break;
139
140 case eStopReasonSignal:
141 {
Greg Clayton643ee732010-08-04 01:40:35 +0000142 stop_desc = m_opaque_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info->GetValue());
Chris Lattner24943d22010-06-08 16:52:24 +0000143 if (stop_desc == NULL || stop_desc[0] == '\0')
144 {
145 static char signal_desc[] = "signal";
146 stop_desc = signal_desc;
147 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
148 }
149 }
150 break;
151
152 case eStopReasonException:
153 {
154 char exc_desc[] = "exception";
155 stop_desc = exc_desc;
156 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
157 }
Greg Clayton54e7afa2010-07-09 20:39:50 +0000158 break;
159
160 default:
161 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000162 }
163
164 if (stop_desc && stop_desc[0])
165 {
166 if (dst)
167 return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
168
169 if (stop_desc_len == 0)
170 stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
171
172 return stop_desc_len;
173 }
174 }
175 }
176 }
177 if (dst)
178 *dst = 0;
179 return 0;
180}
181
182void
183SBThread::SetThread (const ThreadSP& lldb_object_sp)
184{
Greg Clayton63094e02010-06-23 01:19:29 +0000185 m_opaque_sp = lldb_object_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000186}
187
188
189lldb::tid_t
190SBThread::GetThreadID () const
191{
Greg Clayton63094e02010-06-23 01:19:29 +0000192 if (m_opaque_sp)
193 return m_opaque_sp->GetID();
Chris Lattner24943d22010-06-08 16:52:24 +0000194 else
195 return LLDB_INVALID_THREAD_ID;
196}
197
198uint32_t
199SBThread::GetIndexID () const
200{
Greg Clayton63094e02010-06-23 01:19:29 +0000201 if (m_opaque_sp)
202 return m_opaque_sp->GetIndexID();
Chris Lattner24943d22010-06-08 16:52:24 +0000203 return LLDB_INVALID_INDEX32;
204}
205const char *
206SBThread::GetName () const
207{
Greg Clayton63094e02010-06-23 01:19:29 +0000208 if (m_opaque_sp)
209 return m_opaque_sp->GetName();
Chris Lattner24943d22010-06-08 16:52:24 +0000210 return NULL;
211}
212
213const char *
214SBThread::GetQueueName () const
215{
Greg Clayton63094e02010-06-23 01:19:29 +0000216 if (m_opaque_sp)
217 return m_opaque_sp->GetQueueName();
Chris Lattner24943d22010-06-08 16:52:24 +0000218 return NULL;
219}
220
221
222void
Chris Lattner24943d22010-06-08 16:52:24 +0000223SBThread::StepOver (lldb::RunMode stop_other_threads)
224{
Greg Clayton63094e02010-06-23 01:19:29 +0000225 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000226 {
227 bool abort_other_plans = true;
Greg Clayton63094e02010-06-23 01:19:29 +0000228 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000229
230 if (frame_sp)
231 {
232 if (frame_sp->HasDebugInformation ())
233 {
234 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000235 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
Chris Lattner24943d22010-06-08 16:52:24 +0000236 eStepTypeOver,
237 sc.line_entry.range,
238 sc,
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000239 stop_other_threads,
240 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000241
242 }
243 else
244 {
Greg Clayton63094e02010-06-23 01:19:29 +0000245 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true,
Chris Lattner24943d22010-06-08 16:52:24 +0000246 abort_other_plans,
247 stop_other_threads);
248 }
249 }
250
Greg Clayton63094e02010-06-23 01:19:29 +0000251 Process &process = m_opaque_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000252 // Why do we need to set the current thread by ID here???
Jim Inghamc8332952010-08-26 21:32:51 +0000253 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000254 process.Resume();
255 }
256}
257
258void
259SBThread::StepInto (lldb::RunMode stop_other_threads)
260{
Greg Clayton63094e02010-06-23 01:19:29 +0000261 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000262 {
263 bool abort_other_plans = true;
264
Greg Clayton63094e02010-06-23 01:19:29 +0000265 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000266
267 if (frame_sp && frame_sp->HasDebugInformation ())
268 {
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000269 bool avoid_code_without_debug_info = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000270 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000271 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000272 eStepTypeInto,
273 sc.line_entry.range,
274 sc,
275 stop_other_threads,
276 avoid_code_without_debug_info);
Chris Lattner24943d22010-06-08 16:52:24 +0000277 }
278 else
279 {
Greg Clayton63094e02010-06-23 01:19:29 +0000280 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false,
Chris Lattner24943d22010-06-08 16:52:24 +0000281 abort_other_plans,
282 stop_other_threads);
283 }
284
Greg Clayton63094e02010-06-23 01:19:29 +0000285 Process &process = m_opaque_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000286 // Why do we need to set the current thread by ID here???
Jim Inghamc8332952010-08-26 21:32:51 +0000287 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000288 process.Resume();
289
290 }
291}
292
293void
294SBThread::StepOut ()
295{
Greg Clayton63094e02010-06-23 01:19:29 +0000296 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000297 {
298 bool abort_other_plans = true;
299 bool stop_other_threads = true;
300
Greg Clayton63094e02010-06-23 01:19:29 +0000301 m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion);
Chris Lattner24943d22010-06-08 16:52:24 +0000302
Greg Clayton63094e02010-06-23 01:19:29 +0000303 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000304 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000305 process.Resume();
306 }
307}
308
309void
310SBThread::StepInstruction (bool step_over)
311{
Greg Clayton63094e02010-06-23 01:19:29 +0000312 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000313 {
Greg Clayton63094e02010-06-23 01:19:29 +0000314 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
315 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000316 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000317 process.Resume();
318 }
319}
320
321void
322SBThread::RunToAddress (lldb::addr_t addr)
323{
Greg Clayton63094e02010-06-23 01:19:29 +0000324 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000325 {
326 bool abort_other_plans = true;
327 bool stop_other_threads = true;
328
329 Address target_addr (NULL, addr);
330
Greg Clayton63094e02010-06-23 01:19:29 +0000331 m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
332 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000333 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000334 process.Resume();
335 }
336
337}
338
Chris Lattner24943d22010-06-08 16:52:24 +0000339SBProcess
340SBThread::GetProcess ()
341{
342 SBProcess process;
Greg Clayton63094e02010-06-23 01:19:29 +0000343 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000344 {
345 // Have to go up to the target so we can get a shared pointer to our process...
Greg Clayton63094e02010-06-23 01:19:29 +0000346 process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000347 }
348 return process;
349}
350
351uint32_t
352SBThread::GetNumFrames ()
353{
Greg Clayton63094e02010-06-23 01:19:29 +0000354 if (m_opaque_sp)
355 return m_opaque_sp->GetStackFrameCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000356 return 0;
357}
358
359SBFrame
360SBThread::GetFrameAtIndex (uint32_t idx)
361{
362 SBFrame sb_frame;
Greg Clayton63094e02010-06-23 01:19:29 +0000363 if (m_opaque_sp)
364 sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000365 return sb_frame;
366}
367
368const lldb::SBThread &
369SBThread::operator = (const lldb::SBThread &rhs)
370{
Greg Clayton63094e02010-06-23 01:19:29 +0000371 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000372 return *this;
373}
374
375bool
376SBThread::operator == (const SBThread &rhs) const
377{
Greg Clayton63094e02010-06-23 01:19:29 +0000378 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000379}
380
381bool
382SBThread::operator != (const SBThread &rhs) const
383{
Greg Clayton63094e02010-06-23 01:19:29 +0000384 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000385}
386
387lldb_private::Thread *
388SBThread::GetLLDBObjectPtr ()
389{
Greg Clayton63094e02010-06-23 01:19:29 +0000390 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000391}
392
393const lldb_private::Thread *
394SBThread::operator->() const
395{
Greg Clayton63094e02010-06-23 01:19:29 +0000396 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000397}
398
399const lldb_private::Thread &
400SBThread::operator*() const
401{
Greg Clayton63094e02010-06-23 01:19:29 +0000402 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000403}
404
405lldb_private::Thread *
406SBThread::operator->()
407{
Greg Clayton63094e02010-06-23 01:19:29 +0000408 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000409}
410
411lldb_private::Thread &
412SBThread::operator*()
413{
Greg Clayton63094e02010-06-23 01:19:29 +0000414 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000415}
Caroline Tice98f930f2010-09-20 05:20:02 +0000416
417bool
418SBThread::GetDescription (SBStream &description)
419{
420 if (m_opaque_sp)
421 {
422 m_opaque_sp->DumpInfo (description.ref(), true, true, true, LLDB_INVALID_INDEX32);
423 description.Printf (" %d frames, (instance name: %s)", GetNumFrames(),
424 m_opaque_sp->GetInstanceName().AsCString());
425 }
426 else
427 description.Printf ("No value");
428
429 return true;
430}