blob: 006efc79132e3f2ead8f46a78f8e2ed4729b5ac1 [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,
Greg Clayton1a3083a2010-10-06 03:53:16 +0000236 eStepTypeOver,
237 sc.line_entry.range,
238 sc,
239 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,
Greg Clayton1a3083a2010-10-06 03:53:16 +0000246 abort_other_plans,
247 stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000248 }
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());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000254 Error error (process.Resume());
255 if (error.Success())
256 {
257 // If we are doing synchronous mode, then wait for the
258 // process to stop yet again!
259 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
260 process.WaitForProcessToStop (NULL);
261 }
Chris Lattner24943d22010-06-08 16:52:24 +0000262 }
263}
264
265void
266SBThread::StepInto (lldb::RunMode stop_other_threads)
267{
Greg Clayton63094e02010-06-23 01:19:29 +0000268 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000269 {
270 bool abort_other_plans = true;
271
Greg Clayton63094e02010-06-23 01:19:29 +0000272 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000273
274 if (frame_sp && frame_sp->HasDebugInformation ())
275 {
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000276 bool avoid_code_without_debug_info = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000277 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000278 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
Greg Clayton1a3083a2010-10-06 03:53:16 +0000279 eStepTypeInto,
280 sc.line_entry.range,
281 sc,
282 stop_other_threads,
283 avoid_code_without_debug_info);
Chris Lattner24943d22010-06-08 16:52:24 +0000284 }
285 else
286 {
Greg Clayton63094e02010-06-23 01:19:29 +0000287 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false,
Greg Clayton1a3083a2010-10-06 03:53:16 +0000288 abort_other_plans,
289 stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000290 }
291
Greg Clayton63094e02010-06-23 01:19:29 +0000292 Process &process = m_opaque_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000293 // Why do we need to set the current thread by ID here???
Jim Inghamc8332952010-08-26 21:32:51 +0000294 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000295 Error error (process.Resume());
296 if (error.Success())
297 {
298 // If we are doing synchronous mode, then wait for the
299 // process to stop yet again!
300 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
301 process.WaitForProcessToStop (NULL);
302 }
Chris Lattner24943d22010-06-08 16:52:24 +0000303 }
304}
305
306void
307SBThread::StepOut ()
308{
Greg Clayton63094e02010-06-23 01:19:29 +0000309 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000310 {
311 bool abort_other_plans = true;
312 bool stop_other_threads = true;
313
Greg Clayton63094e02010-06-23 01:19:29 +0000314 m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion);
Chris Lattner24943d22010-06-08 16:52:24 +0000315
Greg Clayton63094e02010-06-23 01:19:29 +0000316 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000317 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000318 Error error (process.Resume());
319 if (error.Success())
320 {
321 // If we are doing synchronous mode, then wait for the
322 // process to stop yet again!
323 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
324 process.WaitForProcessToStop (NULL);
325 }
Chris Lattner24943d22010-06-08 16:52:24 +0000326 }
327}
328
329void
330SBThread::StepInstruction (bool step_over)
331{
Greg Clayton63094e02010-06-23 01:19:29 +0000332 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000333 {
Greg Clayton63094e02010-06-23 01:19:29 +0000334 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
335 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000336 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000337 Error error (process.Resume());
338 if (error.Success())
339 {
340 // If we are doing synchronous mode, then wait for the
341 // process to stop yet again!
342 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
343 process.WaitForProcessToStop (NULL);
344 }
Chris Lattner24943d22010-06-08 16:52:24 +0000345 }
346}
347
348void
349SBThread::RunToAddress (lldb::addr_t addr)
350{
Greg Clayton63094e02010-06-23 01:19:29 +0000351 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000352 {
353 bool abort_other_plans = true;
354 bool stop_other_threads = true;
355
356 Address target_addr (NULL, addr);
357
Greg Clayton63094e02010-06-23 01:19:29 +0000358 m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
359 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000360 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000361 Error error (process.Resume());
362 if (error.Success())
363 {
364 // If we are doing synchronous mode, then wait for the
365 // process to stop yet again!
366 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
367 process.WaitForProcessToStop (NULL);
368 }
Chris Lattner24943d22010-06-08 16:52:24 +0000369 }
370
371}
372
Chris Lattner24943d22010-06-08 16:52:24 +0000373SBProcess
374SBThread::GetProcess ()
375{
376 SBProcess process;
Greg Clayton63094e02010-06-23 01:19:29 +0000377 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000378 {
379 // Have to go up to the target so we can get a shared pointer to our process...
Greg Clayton63094e02010-06-23 01:19:29 +0000380 process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000381 }
382 return process;
383}
384
385uint32_t
386SBThread::GetNumFrames ()
387{
Greg Clayton63094e02010-06-23 01:19:29 +0000388 if (m_opaque_sp)
389 return m_opaque_sp->GetStackFrameCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000390 return 0;
391}
392
393SBFrame
394SBThread::GetFrameAtIndex (uint32_t idx)
395{
396 SBFrame sb_frame;
Greg Clayton63094e02010-06-23 01:19:29 +0000397 if (m_opaque_sp)
398 sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000399 return sb_frame;
400}
401
402const lldb::SBThread &
403SBThread::operator = (const lldb::SBThread &rhs)
404{
Greg Clayton63094e02010-06-23 01:19:29 +0000405 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000406 return *this;
407}
408
409bool
410SBThread::operator == (const SBThread &rhs) const
411{
Greg Clayton63094e02010-06-23 01:19:29 +0000412 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000413}
414
415bool
416SBThread::operator != (const SBThread &rhs) const
417{
Greg Clayton63094e02010-06-23 01:19:29 +0000418 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000419}
420
421lldb_private::Thread *
422SBThread::GetLLDBObjectPtr ()
423{
Greg Clayton63094e02010-06-23 01:19:29 +0000424 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000425}
426
427const lldb_private::Thread *
428SBThread::operator->() const
429{
Greg Clayton63094e02010-06-23 01:19:29 +0000430 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000431}
432
433const lldb_private::Thread &
434SBThread::operator*() const
435{
Greg Clayton63094e02010-06-23 01:19:29 +0000436 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000437}
438
439lldb_private::Thread *
440SBThread::operator->()
441{
Greg Clayton63094e02010-06-23 01:19:29 +0000442 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000443}
444
445lldb_private::Thread &
446SBThread::operator*()
447{
Greg Clayton63094e02010-06-23 01:19:29 +0000448 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000449}
Caroline Tice98f930f2010-09-20 05:20:02 +0000450
451bool
452SBThread::GetDescription (SBStream &description)
453{
454 if (m_opaque_sp)
Greg Claytond8c62532010-10-07 04:19:01 +0000455 {
456 StreamString strm;
457 description.Printf("SBThread: tid = 0x%4.4x", m_opaque_sp->GetID());
458 }
Caroline Tice98f930f2010-09-20 05:20:02 +0000459 else
460 description.Printf ("No value");
461
462 return true;
463}