blob: 73f1d19b6b33192922f4032210e0b35eece5e8f6 [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 Clayton640dc6b2010-11-18 18:52:36 +000015#include "lldb/Breakpoint/BreakpointLocation.h"
Greg Clayton63094e02010-06-23 01:19:29 +000016#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/Stream.h"
18#include "lldb/Core/StreamFile.h"
Greg Clayton63094e02010-06-23 01:19:29 +000019#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Target/Thread.h"
21#include "lldb/Target/Process.h"
22#include "lldb/Symbol/SymbolContext.h"
23#include "lldb/Symbol/CompileUnit.h"
Greg Clayton643ee732010-08-04 01:40:35 +000024#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Target/Target.h"
26#include "lldb/Target/ThreadPlan.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Target/ThreadPlanStepInstruction.h"
28#include "lldb/Target/ThreadPlanStepOut.h"
29#include "lldb/Target/ThreadPlanStepRange.h"
30#include "lldb/Target/ThreadPlanStepInRange.h"
31
32
Eli Friedman7a62c8b2010-06-09 07:44:37 +000033#include "lldb/API/SBAddress.h"
Eli Friedman7a62c8b2010-06-09 07:44:37 +000034#include "lldb/API/SBDebugger.h"
Jim Ingham1586d972011-12-17 01:35:57 +000035#include "lldb/API/SBFrame.h"
Eli Friedman7a62c8b2010-06-09 07:44:37 +000036#include "lldb/API/SBProcess.h"
Jim Ingham1586d972011-12-17 01:35:57 +000037#include "lldb/API/SBValue.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038
39using namespace lldb;
40using namespace lldb_private;
41
Greg Clayton49ce6822010-10-31 03:01:06 +000042//----------------------------------------------------------------------
43// Constructors
44//----------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +000045SBThread::SBThread () :
Greg Clayton90c52142012-01-30 02:53:15 +000046 m_opaque_wp ()
Chris Lattner24943d22010-06-08 16:52:24 +000047{
48}
49
Chris Lattner24943d22010-06-08 16:52:24 +000050SBThread::SBThread (const ThreadSP& lldb_object_sp) :
Greg Clayton90c52142012-01-30 02:53:15 +000051 m_opaque_wp (lldb_object_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000052{
53}
54
Greg Clayton1b284412010-10-30 18:26:59 +000055SBThread::SBThread (const SBThread &rhs) :
Greg Clayton90c52142012-01-30 02:53:15 +000056 m_opaque_wp (rhs.m_opaque_wp)
Chris Lattner24943d22010-06-08 16:52:24 +000057{
Chris Lattner24943d22010-06-08 16:52:24 +000058}
59
60//----------------------------------------------------------------------
Greg Clayton49ce6822010-10-31 03:01:06 +000061// Assignment operator
62//----------------------------------------------------------------------
63
64const lldb::SBThread &
65SBThread::operator = (const SBThread &rhs)
66{
67 if (this != &rhs)
Greg Clayton90c52142012-01-30 02:53:15 +000068 m_opaque_wp = rhs.m_opaque_wp;
Greg Clayton49ce6822010-10-31 03:01:06 +000069 return *this;
70}
71
72//----------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +000073// Destructor
74//----------------------------------------------------------------------
75SBThread::~SBThread()
76{
77}
78
79bool
80SBThread::IsValid() const
81{
Greg Clayton90c52142012-01-30 02:53:15 +000082 return !m_opaque_wp.expired();
Chris Lattner24943d22010-06-08 16:52:24 +000083}
84
Greg Clayton43490d12010-07-30 20:12:55 +000085void
86SBThread::Clear ()
87{
Greg Clayton90c52142012-01-30 02:53:15 +000088 m_opaque_wp.reset();
Greg Clayton43490d12010-07-30 20:12:55 +000089}
90
91
Chris Lattner24943d22010-06-08 16:52:24 +000092StopReason
93SBThread::GetStopReason()
94{
Greg Claytone005f2c2010-11-06 01:53:30 +000095 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +000096
Caroline Tice7826c882010-10-26 03:11:13 +000097 StopReason reason = eStopReasonInvalid;
Greg Clayton90c52142012-01-30 02:53:15 +000098 ThreadSP thread_sp(m_opaque_wp.lock());
99 if (thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000100 {
Greg Clayton90c52142012-01-30 02:53:15 +0000101 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
102 StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
Jim Ingham6297a3a2010-10-20 00:39:53 +0000103 if (stop_info_sp)
Caroline Tice7826c882010-10-26 03:11:13 +0000104 reason = stop_info_sp->GetStopReason();
Chris Lattner24943d22010-06-08 16:52:24 +0000105 }
Caroline Tice7826c882010-10-26 03:11:13 +0000106
107 if (log)
Greg Clayton90c52142012-01-30 02:53:15 +0000108 log->Printf ("SBThread(%p)::GetStopReason () => %s", thread_sp.get(),
Caroline Tice61ba7ec2010-10-26 23:49:36 +0000109 Thread::StopReasonAsCString (reason));
Caroline Tice7826c882010-10-26 03:11:13 +0000110
111 return reason;
Chris Lattner24943d22010-06-08 16:52:24 +0000112}
113
114size_t
Greg Clayton640dc6b2010-11-18 18:52:36 +0000115SBThread::GetStopReasonDataCount ()
116{
Greg Clayton90c52142012-01-30 02:53:15 +0000117 ThreadSP thread_sp(m_opaque_wp.lock());
118 if (thread_sp)
Greg Clayton640dc6b2010-11-18 18:52:36 +0000119 {
Greg Clayton90c52142012-01-30 02:53:15 +0000120 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
121 StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
Greg Clayton640dc6b2010-11-18 18:52:36 +0000122 if (stop_info_sp)
123 {
124 StopReason reason = stop_info_sp->GetStopReason();
125 switch (reason)
126 {
127 case eStopReasonInvalid:
128 case eStopReasonNone:
129 case eStopReasonTrace:
130 case eStopReasonPlanComplete:
131 // There is no data for these stop reasons.
132 return 0;
133
134 case eStopReasonBreakpoint:
135 {
136 break_id_t site_id = stop_info_sp->GetValue();
Greg Clayton90c52142012-01-30 02:53:15 +0000137 lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id));
Greg Clayton640dc6b2010-11-18 18:52:36 +0000138 if (bp_site_sp)
139 return bp_site_sp->GetNumberOfOwners () * 2;
140 else
141 return 0; // Breakpoint must have cleared itself...
142 }
143 break;
144
145 case eStopReasonWatchpoint:
Johnny Chenbcbefa82011-12-17 02:07:52 +0000146 return 1;
Greg Clayton640dc6b2010-11-18 18:52:36 +0000147
148 case eStopReasonSignal:
149 return 1;
150
151 case eStopReasonException:
152 return 1;
153 }
154 }
155 }
156 return 0;
157}
158
159uint64_t
160SBThread::GetStopReasonDataAtIndex (uint32_t idx)
161{
Greg Clayton90c52142012-01-30 02:53:15 +0000162 ThreadSP thread_sp(m_opaque_wp.lock());
163 if (thread_sp)
Greg Clayton640dc6b2010-11-18 18:52:36 +0000164 {
Greg Clayton90c52142012-01-30 02:53:15 +0000165 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
166 StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
Greg Clayton640dc6b2010-11-18 18:52:36 +0000167 if (stop_info_sp)
168 {
169 StopReason reason = stop_info_sp->GetStopReason();
170 switch (reason)
171 {
172 case eStopReasonInvalid:
173 case eStopReasonNone:
174 case eStopReasonTrace:
175 case eStopReasonPlanComplete:
176 // There is no data for these stop reasons.
177 return 0;
178
179 case eStopReasonBreakpoint:
180 {
181 break_id_t site_id = stop_info_sp->GetValue();
Greg Clayton90c52142012-01-30 02:53:15 +0000182 lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id));
Greg Clayton640dc6b2010-11-18 18:52:36 +0000183 if (bp_site_sp)
184 {
185 uint32_t bp_index = idx / 2;
186 BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
187 if (bp_loc_sp)
188 {
189 if (bp_index & 1)
190 {
191 // Odd idx, return the breakpoint location ID
192 return bp_loc_sp->GetID();
193 }
194 else
195 {
196 // Even idx, return the breakpoint ID
197 return bp_loc_sp->GetBreakpoint().GetID();
198 }
199 }
200 }
201 return LLDB_INVALID_BREAK_ID;
202 }
203 break;
204
205 case eStopReasonWatchpoint:
Johnny Chenbcbefa82011-12-17 02:07:52 +0000206 return stop_info_sp->GetValue();
Greg Clayton640dc6b2010-11-18 18:52:36 +0000207
208 case eStopReasonSignal:
209 return stop_info_sp->GetValue();
210
211 case eStopReasonException:
212 return stop_info_sp->GetValue();
213 }
214 }
215 }
216 return 0;
217}
218
219size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000220SBThread::GetStopDescription (char *dst, size_t dst_len)
221{
Greg Claytone005f2c2010-11-06 01:53:30 +0000222 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000223
Greg Clayton90c52142012-01-30 02:53:15 +0000224 ThreadSP thread_sp(m_opaque_wp.lock());
225 if (thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000226 {
Greg Clayton90c52142012-01-30 02:53:15 +0000227 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
228 StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
Jim Ingham6297a3a2010-10-20 00:39:53 +0000229 if (stop_info_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000230 {
Jim Ingham6297a3a2010-10-20 00:39:53 +0000231 const char *stop_desc = stop_info_sp->GetDescription();
Chris Lattner24943d22010-06-08 16:52:24 +0000232 if (stop_desc)
233 {
Caroline Tice7826c882010-10-26 03:11:13 +0000234 if (log)
Greg Claytona66ba462010-10-30 04:51:46 +0000235 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
Greg Clayton90c52142012-01-30 02:53:15 +0000236 thread_sp.get(), stop_desc);
Chris Lattner24943d22010-06-08 16:52:24 +0000237 if (dst)
238 return ::snprintf (dst, dst_len, "%s", stop_desc);
239 else
240 {
241 // NULL dst passed in, return the length needed to contain the description
242 return ::strlen (stop_desc) + 1; // Include the NULL byte for size
243 }
244 }
245 else
246 {
Chris Lattner24943d22010-06-08 16:52:24 +0000247 size_t stop_desc_len = 0;
Jim Ingham6297a3a2010-10-20 00:39:53 +0000248 switch (stop_info_sp->GetStopReason())
Chris Lattner24943d22010-06-08 16:52:24 +0000249 {
250 case eStopReasonTrace:
251 case eStopReasonPlanComplete:
252 {
253 static char trace_desc[] = "step";
254 stop_desc = trace_desc;
255 stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
256 }
257 break;
258
259 case eStopReasonBreakpoint:
260 {
261 static char bp_desc[] = "breakpoint hit";
262 stop_desc = bp_desc;
263 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
264 }
265 break;
266
267 case eStopReasonWatchpoint:
268 {
269 static char wp_desc[] = "watchpoint hit";
270 stop_desc = wp_desc;
271 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
272 }
273 break;
274
275 case eStopReasonSignal:
276 {
Greg Clayton90c52142012-01-30 02:53:15 +0000277 stop_desc = thread_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
Chris Lattner24943d22010-06-08 16:52:24 +0000278 if (stop_desc == NULL || stop_desc[0] == '\0')
279 {
280 static char signal_desc[] = "signal";
281 stop_desc = signal_desc;
282 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
283 }
284 }
285 break;
286
287 case eStopReasonException:
288 {
289 char exc_desc[] = "exception";
290 stop_desc = exc_desc;
291 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
292 }
Greg Clayton54e7afa2010-07-09 20:39:50 +0000293 break;
294
295 default:
296 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000297 }
298
299 if (stop_desc && stop_desc[0])
300 {
Caroline Tice7826c882010-10-26 03:11:13 +0000301 if (log)
Greg Clayton3f5ee7f2010-10-29 04:59:35 +0000302 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
Greg Clayton90c52142012-01-30 02:53:15 +0000303 thread_sp.get(), stop_desc);
Caroline Tice7826c882010-10-26 03:11:13 +0000304
Chris Lattner24943d22010-06-08 16:52:24 +0000305 if (dst)
306 return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
307
308 if (stop_desc_len == 0)
309 stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
310
311 return stop_desc_len;
312 }
313 }
314 }
315 }
316 if (dst)
317 *dst = 0;
318 return 0;
319}
320
Jim Ingham1586d972011-12-17 01:35:57 +0000321SBValue
322SBThread::GetStopReturnValue ()
323{
324 ValueObjectSP return_valobj_sp;
Greg Clayton90c52142012-01-30 02:53:15 +0000325 ThreadSP thread_sp(m_opaque_wp.lock());
326 if (thread_sp)
Jim Ingham1586d972011-12-17 01:35:57 +0000327 {
Greg Clayton90c52142012-01-30 02:53:15 +0000328 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
329 StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
Jim Ingham1586d972011-12-17 01:35:57 +0000330 if (stop_info_sp)
331 {
332 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
333 }
334 }
335
336 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
337 if (log)
Greg Clayton90c52142012-01-30 02:53:15 +0000338 log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", thread_sp.get(),
Jim Ingham1586d972011-12-17 01:35:57 +0000339 return_valobj_sp.get()
340 ? return_valobj_sp->GetValueAsCString()
341 : "<no return value>");
342
343 return SBValue (return_valobj_sp);
344}
345
Chris Lattner24943d22010-06-08 16:52:24 +0000346void
347SBThread::SetThread (const ThreadSP& lldb_object_sp)
348{
Greg Clayton90c52142012-01-30 02:53:15 +0000349 m_opaque_wp = lldb_object_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000350}
351
352
353lldb::tid_t
354SBThread::GetThreadID () const
355{
Greg Claytone005f2c2010-11-06 01:53:30 +0000356 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000357
Greg Claytonbdcda462010-12-20 20:49:23 +0000358 lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
Greg Clayton90c52142012-01-30 02:53:15 +0000359 ThreadSP thread_sp(m_opaque_wp.lock());
360 if (thread_sp)
361 tid = thread_sp->GetID();
Caroline Tice7826c882010-10-26 03:11:13 +0000362
363 if (log)
Greg Clayton90c52142012-01-30 02:53:15 +0000364 log->Printf ("SBThread(%p)::GetThreadID () => 0x%4.4llx", thread_sp.get(), tid);
Caroline Tice7826c882010-10-26 03:11:13 +0000365
Greg Claytonbdcda462010-12-20 20:49:23 +0000366 return tid;
Chris Lattner24943d22010-06-08 16:52:24 +0000367}
368
369uint32_t
370SBThread::GetIndexID () const
371{
Greg Clayton90c52142012-01-30 02:53:15 +0000372 ThreadSP thread_sp(m_opaque_wp.lock());
373 if (thread_sp)
374 return thread_sp->GetIndexID();
Chris Lattner24943d22010-06-08 16:52:24 +0000375 return LLDB_INVALID_INDEX32;
376}
377const char *
378SBThread::GetName () const
379{
Greg Claytona66ba462010-10-30 04:51:46 +0000380 const char *name = NULL;
Greg Clayton90c52142012-01-30 02:53:15 +0000381 ThreadSP thread_sp(m_opaque_wp.lock());
382 if (thread_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000383 {
Greg Clayton90c52142012-01-30 02:53:15 +0000384 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
385 name = thread_sp->GetName();
Greg Claytonbdcda462010-12-20 20:49:23 +0000386 }
Greg Claytona66ba462010-10-30 04:51:46 +0000387
Greg Claytone005f2c2010-11-06 01:53:30 +0000388 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000389 if (log)
Greg Clayton90c52142012-01-30 02:53:15 +0000390 log->Printf ("SBThread(%p)::GetName () => %s", thread_sp.get(), name ? name : "NULL");
Caroline Tice7826c882010-10-26 03:11:13 +0000391
Greg Claytona66ba462010-10-30 04:51:46 +0000392 return name;
Chris Lattner24943d22010-06-08 16:52:24 +0000393}
394
395const char *
396SBThread::GetQueueName () const
397{
Greg Claytona66ba462010-10-30 04:51:46 +0000398 const char *name = NULL;
Greg Clayton90c52142012-01-30 02:53:15 +0000399 ThreadSP thread_sp(m_opaque_wp.lock());
400 if (thread_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000401 {
Greg Clayton90c52142012-01-30 02:53:15 +0000402 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
403 name = thread_sp->GetQueueName();
Greg Claytonbdcda462010-12-20 20:49:23 +0000404 }
Greg Claytona66ba462010-10-30 04:51:46 +0000405
Greg Claytone005f2c2010-11-06 01:53:30 +0000406 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000407 if (log)
Greg Clayton90c52142012-01-30 02:53:15 +0000408 log->Printf ("SBThread(%p)::GetQueueName () => %s", thread_sp.get(), name ? name : "NULL");
Caroline Tice7826c882010-10-26 03:11:13 +0000409
Greg Claytona66ba462010-10-30 04:51:46 +0000410 return name;
Chris Lattner24943d22010-06-08 16:52:24 +0000411}
412
413
414void
Chris Lattner24943d22010-06-08 16:52:24 +0000415SBThread::StepOver (lldb::RunMode stop_other_threads)
416{
Greg Claytone005f2c2010-11-06 01:53:30 +0000417 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000418
Greg Clayton90c52142012-01-30 02:53:15 +0000419 ThreadSP thread_sp(m_opaque_wp.lock());
Caroline Tice7826c882010-10-26 03:11:13 +0000420
Greg Clayton90c52142012-01-30 02:53:15 +0000421 if (log)
422 log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", thread_sp.get(),
423 Thread::RunModeAsCString (stop_other_threads));
424
425 if (thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000426 {
Greg Clayton90c52142012-01-30 02:53:15 +0000427 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000428 bool abort_other_plans = true;
Greg Clayton90c52142012-01-30 02:53:15 +0000429 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000430
431 if (frame_sp)
432 {
433 if (frame_sp->HasDebugInformation ())
434 {
435 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton90c52142012-01-30 02:53:15 +0000436 thread_sp->QueueThreadPlanForStepRange (abort_other_plans,
437 eStepTypeOver,
438 sc.line_entry.range,
439 sc,
440 stop_other_threads,
441 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000442
443 }
444 else
445 {
Greg Clayton90c52142012-01-30 02:53:15 +0000446 thread_sp->QueueThreadPlanForStepSingleInstruction (true,
447 abort_other_plans,
448 stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000449 }
450 }
451
Greg Clayton90c52142012-01-30 02:53:15 +0000452 Process &process = thread_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000453 // Why do we need to set the current thread by ID here???
Greg Clayton90c52142012-01-30 02:53:15 +0000454 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000455 Error error (process.Resume());
456 if (error.Success())
457 {
458 // If we are doing synchronous mode, then wait for the
459 // process to stop yet again!
460 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
461 process.WaitForProcessToStop (NULL);
462 }
Chris Lattner24943d22010-06-08 16:52:24 +0000463 }
464}
465
466void
467SBThread::StepInto (lldb::RunMode stop_other_threads)
468{
Greg Claytone005f2c2010-11-06 01:53:30 +0000469 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000470
Caroline Tice7826c882010-10-26 03:11:13 +0000471
Greg Clayton90c52142012-01-30 02:53:15 +0000472 ThreadSP thread_sp(m_opaque_wp.lock());
473
474 if (log)
475 log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", thread_sp.get(),
476 Thread::RunModeAsCString (stop_other_threads));
477 if (thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000478 {
Greg Clayton90c52142012-01-30 02:53:15 +0000479 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000480 bool abort_other_plans = true;
481
Greg Clayton90c52142012-01-30 02:53:15 +0000482 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000483
484 if (frame_sp && frame_sp->HasDebugInformation ())
485 {
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000486 bool avoid_code_without_debug_info = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000487 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton90c52142012-01-30 02:53:15 +0000488 thread_sp->QueueThreadPlanForStepRange (abort_other_plans,
489 eStepTypeInto,
490 sc.line_entry.range,
491 sc,
492 stop_other_threads,
493 avoid_code_without_debug_info);
Chris Lattner24943d22010-06-08 16:52:24 +0000494 }
495 else
496 {
Greg Clayton90c52142012-01-30 02:53:15 +0000497 thread_sp->QueueThreadPlanForStepSingleInstruction (false,
498 abort_other_plans,
499 stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000500 }
501
Greg Clayton90c52142012-01-30 02:53:15 +0000502 Process &process = thread_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000503 // Why do we need to set the current thread by ID here???
Greg Clayton90c52142012-01-30 02:53:15 +0000504 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000505 Error error (process.Resume());
506 if (error.Success())
507 {
508 // If we are doing synchronous mode, then wait for the
509 // process to stop yet again!
510 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
511 process.WaitForProcessToStop (NULL);
512 }
Chris Lattner24943d22010-06-08 16:52:24 +0000513 }
514}
515
516void
517SBThread::StepOut ()
518{
Greg Claytone005f2c2010-11-06 01:53:30 +0000519 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000520
Greg Clayton90c52142012-01-30 02:53:15 +0000521 ThreadSP thread_sp(m_opaque_wp.lock());
Caroline Tice7826c882010-10-26 03:11:13 +0000522
Greg Clayton90c52142012-01-30 02:53:15 +0000523 if (log)
524 log->Printf ("SBThread(%p)::StepOut ()", thread_sp.get());
525
526 if (thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000527 {
Greg Clayton90c52142012-01-30 02:53:15 +0000528 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000529 bool abort_other_plans = true;
530 bool stop_other_threads = true;
531
Greg Clayton90c52142012-01-30 02:53:15 +0000532 thread_sp->QueueThreadPlanForStepOut (abort_other_plans,
533 NULL,
534 false,
535 stop_other_threads,
536 eVoteYes,
537 eVoteNoOpinion,
538 0);
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000539
Greg Clayton90c52142012-01-30 02:53:15 +0000540 Process &process = thread_sp->GetProcess();
541 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000542 Error error (process.Resume());
543 if (error.Success())
544 {
545 // If we are doing synchronous mode, then wait for the
546 // process to stop yet again!
547 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
548 process.WaitForProcessToStop (NULL);
549 }
550 }
551}
Chris Lattner24943d22010-06-08 16:52:24 +0000552
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000553void
554SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
555{
556 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
557
Greg Clayton90c52142012-01-30 02:53:15 +0000558 ThreadSP thread_sp(m_opaque_wp.lock());
559
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000560 if (log)
561 {
562 SBStream frame_desc_strm;
563 sb_frame.GetDescription (frame_desc_strm);
Greg Clayton90c52142012-01-30 02:53:15 +0000564 log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", thread_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000565 }
566
Greg Clayton90c52142012-01-30 02:53:15 +0000567 if (thread_sp)
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000568 {
Greg Clayton90c52142012-01-30 02:53:15 +0000569 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000570 bool abort_other_plans = true;
571 bool stop_other_threads = true;
572
Greg Clayton90c52142012-01-30 02:53:15 +0000573 thread_sp->QueueThreadPlanForStepOut (abort_other_plans,
574 NULL,
575 false,
576 stop_other_threads,
577 eVoteYes,
578 eVoteNoOpinion,
579 sb_frame->GetFrameIndex());
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000580
Greg Clayton90c52142012-01-30 02:53:15 +0000581 Process &process = thread_sp->GetProcess();
582 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000583 Error error (process.Resume());
584 if (error.Success())
585 {
586 // If we are doing synchronous mode, then wait for the
587 // process to stop yet again!
588 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
589 process.WaitForProcessToStop (NULL);
590 }
Chris Lattner24943d22010-06-08 16:52:24 +0000591 }
592}
593
594void
595SBThread::StepInstruction (bool step_over)
596{
Greg Claytone005f2c2010-11-06 01:53:30 +0000597 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000598
Greg Clayton90c52142012-01-30 02:53:15 +0000599 ThreadSP thread_sp(m_opaque_wp.lock());
Caroline Tice7826c882010-10-26 03:11:13 +0000600
Greg Clayton90c52142012-01-30 02:53:15 +0000601 if (log)
602 log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", thread_sp.get(), step_over);
603
604 if (thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000605 {
Greg Clayton90c52142012-01-30 02:53:15 +0000606 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
607 thread_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
608 Process &process = thread_sp->GetProcess();
609 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000610 Error error (process.Resume());
611 if (error.Success())
612 {
613 // If we are doing synchronous mode, then wait for the
614 // process to stop yet again!
615 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
616 process.WaitForProcessToStop (NULL);
617 }
Chris Lattner24943d22010-06-08 16:52:24 +0000618 }
619}
620
621void
622SBThread::RunToAddress (lldb::addr_t addr)
623{
Greg Claytone005f2c2010-11-06 01:53:30 +0000624 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000625
Greg Clayton90c52142012-01-30 02:53:15 +0000626 ThreadSP thread_sp(m_opaque_wp.lock());
Caroline Tice7826c882010-10-26 03:11:13 +0000627
Greg Clayton90c52142012-01-30 02:53:15 +0000628 if (log)
629 log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", thread_sp.get(), addr);
630
631 if (thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000632 {
633 bool abort_other_plans = true;
634 bool stop_other_threads = true;
635
636 Address target_addr (NULL, addr);
637
Greg Clayton90c52142012-01-30 02:53:15 +0000638 thread_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
639 Process &process = thread_sp->GetProcess();
640 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000641 Error error (process.Resume());
642 if (error.Success())
643 {
644 // If we are doing synchronous mode, then wait for the
645 // process to stop yet again!
646 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
647 process.WaitForProcessToStop (NULL);
648 }
Chris Lattner24943d22010-06-08 16:52:24 +0000649 }
Chris Lattner24943d22010-06-08 16:52:24 +0000650}
651
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000652SBError
653SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
654 lldb::SBFileSpec &sb_file_spec,
655 uint32_t line)
656{
657 SBError sb_error;
658 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
659 char path[PATH_MAX];
Greg Clayton90c52142012-01-30 02:53:15 +0000660
661 ThreadSP thread_sp(m_opaque_wp.lock());
662
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000663 if (log)
664 {
665 SBStream frame_desc_strm;
666 sb_frame.GetDescription (frame_desc_strm);
667 sb_file_spec->GetPath (path, sizeof(path));
668 log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
Greg Clayton90c52142012-01-30 02:53:15 +0000669 thread_sp.get(),
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000670 sb_frame.get(),
671 frame_desc_strm.GetData(),
672 path, line);
673 }
Greg Clayton90c52142012-01-30 02:53:15 +0000674
675 if (thread_sp)
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000676 {
Greg Clayton90c52142012-01-30 02:53:15 +0000677 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000678
679 if (line == 0)
680 {
681 sb_error.SetErrorString("invalid line argument");
682 return sb_error;
683 }
684
685 StackFrameSP frame_sp;
686 if (sb_frame.IsValid())
687 frame_sp = sb_frame.get_sp();
688 else
689 {
Greg Clayton90c52142012-01-30 02:53:15 +0000690 frame_sp = thread_sp->GetSelectedFrame ();
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000691 if (!frame_sp)
Greg Clayton90c52142012-01-30 02:53:15 +0000692 frame_sp = thread_sp->GetStackFrameAtIndex (0);
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000693 }
694
695 SymbolContext frame_sc;
696 if (!frame_sp)
697 {
698 sb_error.SetErrorString("no valid frames in thread to step");
699 return sb_error;
700 }
701
702 // If we have a frame, get its line
703 frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit |
704 eSymbolContextFunction |
705 eSymbolContextLineEntry |
706 eSymbolContextSymbol );
707
708 if (frame_sc.comp_unit == NULL)
709 {
710 sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
711 return sb_error;
712 }
713
714 FileSpec step_file_spec;
715 if (sb_file_spec.IsValid())
716 {
717 // The file spec passed in was valid, so use it
718 step_file_spec = sb_file_spec.ref();
719 }
720 else
721 {
722 if (frame_sc.line_entry.IsValid())
723 step_file_spec = frame_sc.line_entry.file;
724 else
725 {
726 sb_error.SetErrorString("invalid file argument or no file for frame");
727 return sb_error;
728 }
729 }
730
Jim Inghamb07c62a2011-05-08 00:56:32 +0000731 // Grab the current function, then we will make sure the "until" address is
732 // within the function. We discard addresses that are out of the current
733 // function, and then if there are no addresses remaining, give an appropriate
734 // error message.
735
736 bool all_in_function = true;
737 AddressRange fun_range = frame_sc.function->GetAddressRange();
738
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000739 std::vector<addr_t> step_over_until_addrs;
740 const bool abort_other_plans = true;
741 const bool stop_other_threads = true;
742 const bool check_inlines = true;
743 const bool exact = false;
Greg Clayton90c52142012-01-30 02:53:15 +0000744 Target *target = &thread_sp->GetProcess().GetTarget();
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000745
746 SymbolContextList sc_list;
Jim Inghamb07c62a2011-05-08 00:56:32 +0000747 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
748 line,
749 check_inlines,
750 exact,
751 eSymbolContextLineEntry,
752 sc_list);
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000753 if (num_matches > 0)
754 {
755 SymbolContext sc;
756 for (uint32_t i=0; i<num_matches; ++i)
757 {
758 if (sc_list.GetContextAtIndex(i, sc))
759 {
Jim Inghamb07c62a2011-05-08 00:56:32 +0000760 addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000761 if (step_addr != LLDB_INVALID_ADDRESS)
762 {
Jim Inghamb07c62a2011-05-08 00:56:32 +0000763 if (fun_range.ContainsLoadAddress(step_addr, target))
764 step_over_until_addrs.push_back(step_addr);
765 else
766 all_in_function = false;
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000767 }
768 }
769 }
770 }
Jim Inghamb07c62a2011-05-08 00:56:32 +0000771
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000772 if (step_over_until_addrs.empty())
773 {
Jim Inghamb07c62a2011-05-08 00:56:32 +0000774 if (all_in_function)
775 {
776 step_file_spec.GetPath (path, sizeof(path));
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000777 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
Jim Inghamb07c62a2011-05-08 00:56:32 +0000778 }
779 else
Greg Clayton9c236732011-10-26 00:56:27 +0000780 sb_error.SetErrorString ("step until target not in current function");
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000781 }
782 else
783 {
Greg Clayton90c52142012-01-30 02:53:15 +0000784 thread_sp->QueueThreadPlanForStepUntil (abort_other_plans,
785 &step_over_until_addrs[0],
786 step_over_until_addrs.size(),
787 stop_other_threads,
788 frame_sp->GetFrameIndex());
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000789
Greg Clayton90c52142012-01-30 02:53:15 +0000790 thread_sp->GetProcess().GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
791 sb_error.ref() = thread_sp->GetProcess().Resume();
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000792 if (sb_error->Success())
793 {
794 // If we are doing synchronous mode, then wait for the
795 // process to stop yet again!
Greg Clayton90c52142012-01-30 02:53:15 +0000796 if (thread_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false)
797 thread_sp->GetProcess().WaitForProcessToStop (NULL);
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000798 }
799 }
800 }
801 else
802 {
803 sb_error.SetErrorString("this SBThread object is invalid");
804 }
805 return sb_error;
806}
807
808
Greg Clayton123db402011-01-12 02:25:42 +0000809bool
810SBThread::Suspend()
811{
Greg Clayton90c52142012-01-30 02:53:15 +0000812 ThreadSP thread_sp(m_opaque_wp.lock());
813 if (thread_sp)
Greg Clayton123db402011-01-12 02:25:42 +0000814 {
Greg Clayton90c52142012-01-30 02:53:15 +0000815 thread_sp->SetResumeState (eStateSuspended);
Greg Clayton123db402011-01-12 02:25:42 +0000816 return true;
817 }
818 return false;
819}
820
821bool
822SBThread::Resume ()
823{
Greg Clayton90c52142012-01-30 02:53:15 +0000824 ThreadSP thread_sp(m_opaque_wp.lock());
825 if (thread_sp)
Greg Clayton123db402011-01-12 02:25:42 +0000826 {
Greg Clayton90c52142012-01-30 02:53:15 +0000827 thread_sp->SetResumeState (eStateRunning);
Greg Clayton123db402011-01-12 02:25:42 +0000828 return true;
829 }
830 return false;
831}
832
833bool
834SBThread::IsSuspended()
835{
Greg Clayton90c52142012-01-30 02:53:15 +0000836 ThreadSP thread_sp(m_opaque_wp.lock());
837 if (thread_sp)
838 return thread_sp->GetResumeState () == eStateSuspended;
Greg Clayton123db402011-01-12 02:25:42 +0000839 return false;
840}
841
Chris Lattner24943d22010-06-08 16:52:24 +0000842SBProcess
843SBThread::GetProcess ()
844{
Caroline Tice7826c882010-10-26 03:11:13 +0000845
Chris Lattner24943d22010-06-08 16:52:24 +0000846 SBProcess process;
Greg Clayton90c52142012-01-30 02:53:15 +0000847 ThreadSP thread_sp(m_opaque_wp.lock());
848 if (thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000849 {
850 // Have to go up to the target so we can get a shared pointer to our process...
Greg Clayton90c52142012-01-30 02:53:15 +0000851 process.SetProcess(thread_sp->GetProcess().GetTarget().GetProcessSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000852 }
Caroline Tice7826c882010-10-26 03:11:13 +0000853
Greg Claytone005f2c2010-11-06 01:53:30 +0000854 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000855 if (log)
856 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000857 SBStream frame_desc_strm;
858 process.GetDescription (frame_desc_strm);
Greg Clayton90c52142012-01-30 02:53:15 +0000859 log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", thread_sp.get(),
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000860 process.get(), frame_desc_strm.GetData());
Caroline Tice7826c882010-10-26 03:11:13 +0000861 }
862
Chris Lattner24943d22010-06-08 16:52:24 +0000863 return process;
864}
865
866uint32_t
867SBThread::GetNumFrames ()
868{
Greg Claytone005f2c2010-11-06 01:53:30 +0000869 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000870
Caroline Tice7826c882010-10-26 03:11:13 +0000871 uint32_t num_frames = 0;
Greg Clayton90c52142012-01-30 02:53:15 +0000872 ThreadSP thread_sp(m_opaque_wp.lock());
873 if (thread_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000874 {
Greg Clayton90c52142012-01-30 02:53:15 +0000875 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
876 num_frames = thread_sp->GetStackFrameCount();
Greg Claytonbdcda462010-12-20 20:49:23 +0000877 }
Caroline Tice7826c882010-10-26 03:11:13 +0000878
879 if (log)
Greg Clayton90c52142012-01-30 02:53:15 +0000880 log->Printf ("SBThread(%p)::GetNumFrames () => %u", thread_sp.get(), num_frames);
Caroline Tice7826c882010-10-26 03:11:13 +0000881
882 return num_frames;
Chris Lattner24943d22010-06-08 16:52:24 +0000883}
884
885SBFrame
886SBThread::GetFrameAtIndex (uint32_t idx)
887{
Greg Claytone005f2c2010-11-06 01:53:30 +0000888 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000889
Chris Lattner24943d22010-06-08 16:52:24 +0000890 SBFrame sb_frame;
Greg Clayton90c52142012-01-30 02:53:15 +0000891 ThreadSP thread_sp(m_opaque_wp.lock());
892 if (thread_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000893 {
Greg Clayton90c52142012-01-30 02:53:15 +0000894 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
895 sb_frame.SetFrame (thread_sp->GetStackFrameAtIndex (idx));
Greg Claytonbdcda462010-12-20 20:49:23 +0000896 }
Caroline Tice7826c882010-10-26 03:11:13 +0000897
898 if (log)
899 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000900 SBStream frame_desc_strm;
901 sb_frame.GetDescription (frame_desc_strm);
Greg Claytona66ba462010-10-30 04:51:46 +0000902 log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
Greg Clayton90c52142012-01-30 02:53:15 +0000903 thread_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
Caroline Tice7826c882010-10-26 03:11:13 +0000904 }
905
Chris Lattner24943d22010-06-08 16:52:24 +0000906 return sb_frame;
907}
908
Greg Claytonc5157ec2010-12-17 02:26:24 +0000909lldb::SBFrame
910SBThread::GetSelectedFrame ()
911{
912 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
913
914 SBFrame sb_frame;
Greg Clayton90c52142012-01-30 02:53:15 +0000915 ThreadSP thread_sp(m_opaque_wp.lock());
916 if (thread_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000917 {
Greg Clayton90c52142012-01-30 02:53:15 +0000918 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
919 sb_frame.SetFrame (thread_sp->GetSelectedFrame ());
Greg Claytonbdcda462010-12-20 20:49:23 +0000920 }
Greg Claytonc5157ec2010-12-17 02:26:24 +0000921
922 if (log)
923 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000924 SBStream frame_desc_strm;
925 sb_frame.GetDescription (frame_desc_strm);
Greg Claytonc5157ec2010-12-17 02:26:24 +0000926 log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
Greg Clayton90c52142012-01-30 02:53:15 +0000927 thread_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
Greg Claytonc5157ec2010-12-17 02:26:24 +0000928 }
929
930 return sb_frame;
931}
932
933lldb::SBFrame
934SBThread::SetSelectedFrame (uint32_t idx)
935{
936 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
937
938 SBFrame sb_frame;
Greg Clayton90c52142012-01-30 02:53:15 +0000939 ThreadSP thread_sp(m_opaque_wp.lock());
940 if (thread_sp)
Greg Claytonc5157ec2010-12-17 02:26:24 +0000941 {
Greg Clayton90c52142012-01-30 02:53:15 +0000942 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
943 lldb::StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex (idx));
Greg Claytonc5157ec2010-12-17 02:26:24 +0000944 if (frame_sp)
945 {
Greg Clayton90c52142012-01-30 02:53:15 +0000946 thread_sp->SetSelectedFrame (frame_sp.get());
Greg Claytonc5157ec2010-12-17 02:26:24 +0000947 sb_frame.SetFrame (frame_sp);
948 }
949 }
950
951 if (log)
952 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000953 SBStream frame_desc_strm;
954 sb_frame.GetDescription (frame_desc_strm);
Greg Claytonc5157ec2010-12-17 02:26:24 +0000955 log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
Greg Clayton90c52142012-01-30 02:53:15 +0000956 thread_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
Greg Claytonc5157ec2010-12-17 02:26:24 +0000957 }
958 return sb_frame;
959}
960
961
Chris Lattner24943d22010-06-08 16:52:24 +0000962bool
963SBThread::operator == (const SBThread &rhs) const
964{
Greg Clayton90c52142012-01-30 02:53:15 +0000965 return m_opaque_wp.lock().get() == rhs.m_opaque_wp.lock().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000966}
967
968bool
969SBThread::operator != (const SBThread &rhs) const
970{
Greg Clayton90c52142012-01-30 02:53:15 +0000971 return m_opaque_wp.lock().get() != rhs.m_opaque_wp.lock().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000972}
Caroline Tice98f930f2010-09-20 05:20:02 +0000973
974bool
Caroline Tice7826c882010-10-26 03:11:13 +0000975SBThread::GetDescription (SBStream &description) const
976{
Greg Clayton96154be2011-11-13 06:57:31 +0000977 Stream &strm = description.ref();
978
Greg Clayton90c52142012-01-30 02:53:15 +0000979 ThreadSP thread_sp(m_opaque_wp.lock());
980 if (thread_sp)
Caroline Tice7826c882010-10-26 03:11:13 +0000981 {
Greg Clayton90c52142012-01-30 02:53:15 +0000982 strm.Printf("SBThread: tid = 0x%4.4llx", thread_sp->GetID());
Caroline Tice7826c882010-10-26 03:11:13 +0000983 }
984 else
Greg Clayton96154be2011-11-13 06:57:31 +0000985 strm.PutCString ("No value");
Caroline Tice7826c882010-10-26 03:11:13 +0000986
987 return true;
988}