blob: 2760e6585a7df3ff3473b5913773abd33c4cea7b [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"
34#include "lldb/API/SBFrame.h"
35#include "lldb/API/SBSourceManager.h"
36#include "lldb/API/SBDebugger.h"
37#include "lldb/API/SBProcess.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 Clayton63094e02010-06-23 01:19:29 +000046 m_opaque_sp ()
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 Clayton63094e02010-06-23 01:19:29 +000051 m_opaque_sp (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) :
56 m_opaque_sp (rhs.m_opaque_sp)
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)
68 m_opaque_sp = rhs.m_opaque_sp;
69 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 Clayton63094e02010-06-23 01:19:29 +000082 return m_opaque_sp != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +000083}
84
Greg Clayton43490d12010-07-30 20:12:55 +000085void
86SBThread::Clear ()
87{
88 m_opaque_sp.reset();
89}
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 Clayton63094e02010-06-23 01:19:29 +000098 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000099 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000100 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Jim Ingham6297a3a2010-10-20 00:39:53 +0000101 StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
102 if (stop_info_sp)
Caroline Tice7826c882010-10-26 03:11:13 +0000103 reason = stop_info_sp->GetStopReason();
Chris Lattner24943d22010-06-08 16:52:24 +0000104 }
Caroline Tice7826c882010-10-26 03:11:13 +0000105
106 if (log)
Greg Claytona66ba462010-10-30 04:51:46 +0000107 log->Printf ("SBThread(%p)::GetStopReason () => %s", m_opaque_sp.get(),
Caroline Tice61ba7ec2010-10-26 23:49:36 +0000108 Thread::StopReasonAsCString (reason));
Caroline Tice7826c882010-10-26 03:11:13 +0000109
110 return reason;
Chris Lattner24943d22010-06-08 16:52:24 +0000111}
112
113size_t
Greg Clayton640dc6b2010-11-18 18:52:36 +0000114SBThread::GetStopReasonDataCount ()
115{
116 if (m_opaque_sp)
117 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000118 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Clayton640dc6b2010-11-18 18:52:36 +0000119 StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
120 if (stop_info_sp)
121 {
122 StopReason reason = stop_info_sp->GetStopReason();
123 switch (reason)
124 {
125 case eStopReasonInvalid:
126 case eStopReasonNone:
127 case eStopReasonTrace:
128 case eStopReasonPlanComplete:
129 // There is no data for these stop reasons.
130 return 0;
131
132 case eStopReasonBreakpoint:
133 {
134 break_id_t site_id = stop_info_sp->GetValue();
135 lldb::BreakpointSiteSP bp_site_sp (m_opaque_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id));
136 if (bp_site_sp)
137 return bp_site_sp->GetNumberOfOwners () * 2;
138 else
139 return 0; // Breakpoint must have cleared itself...
140 }
141 break;
142
143 case eStopReasonWatchpoint:
144 assert (!"implement watchpoint support in SBThread::GetStopReasonDataCount ()");
145 return 0; // We don't have watchpoint support yet...
146
147 case eStopReasonSignal:
148 return 1;
149
150 case eStopReasonException:
151 return 1;
152 }
153 }
154 }
155 return 0;
156}
157
158uint64_t
159SBThread::GetStopReasonDataAtIndex (uint32_t idx)
160{
161 if (m_opaque_sp)
162 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000163 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Clayton640dc6b2010-11-18 18:52:36 +0000164 StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
165 if (stop_info_sp)
166 {
167 StopReason reason = stop_info_sp->GetStopReason();
168 switch (reason)
169 {
170 case eStopReasonInvalid:
171 case eStopReasonNone:
172 case eStopReasonTrace:
173 case eStopReasonPlanComplete:
174 // There is no data for these stop reasons.
175 return 0;
176
177 case eStopReasonBreakpoint:
178 {
179 break_id_t site_id = stop_info_sp->GetValue();
180 lldb::BreakpointSiteSP bp_site_sp (m_opaque_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id));
181 if (bp_site_sp)
182 {
183 uint32_t bp_index = idx / 2;
184 BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
185 if (bp_loc_sp)
186 {
187 if (bp_index & 1)
188 {
189 // Odd idx, return the breakpoint location ID
190 return bp_loc_sp->GetID();
191 }
192 else
193 {
194 // Even idx, return the breakpoint ID
195 return bp_loc_sp->GetBreakpoint().GetID();
196 }
197 }
198 }
199 return LLDB_INVALID_BREAK_ID;
200 }
201 break;
202
203 case eStopReasonWatchpoint:
204 assert (!"implement watchpoint support in SBThread::GetStopReasonDataCount ()");
205 return 0; // We don't have watchpoint support yet...
206
207 case eStopReasonSignal:
208 return stop_info_sp->GetValue();
209
210 case eStopReasonException:
211 return stop_info_sp->GetValue();
212 }
213 }
214 }
215 return 0;
216}
217
218size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000219SBThread::GetStopDescription (char *dst, size_t dst_len)
220{
Greg Claytone005f2c2010-11-06 01:53:30 +0000221 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000222
Greg Clayton63094e02010-06-23 01:19:29 +0000223 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000224 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000225 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Jim Ingham6297a3a2010-10-20 00:39:53 +0000226 StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
227 if (stop_info_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000228 {
Jim Ingham6297a3a2010-10-20 00:39:53 +0000229 const char *stop_desc = stop_info_sp->GetDescription();
Chris Lattner24943d22010-06-08 16:52:24 +0000230 if (stop_desc)
231 {
Caroline Tice7826c882010-10-26 03:11:13 +0000232 if (log)
Greg Claytona66ba462010-10-30 04:51:46 +0000233 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
Caroline Tice61ba7ec2010-10-26 23:49:36 +0000234 m_opaque_sp.get(), stop_desc);
Chris Lattner24943d22010-06-08 16:52:24 +0000235 if (dst)
236 return ::snprintf (dst, dst_len, "%s", stop_desc);
237 else
238 {
239 // NULL dst passed in, return the length needed to contain the description
240 return ::strlen (stop_desc) + 1; // Include the NULL byte for size
241 }
242 }
243 else
244 {
Chris Lattner24943d22010-06-08 16:52:24 +0000245 size_t stop_desc_len = 0;
Jim Ingham6297a3a2010-10-20 00:39:53 +0000246 switch (stop_info_sp->GetStopReason())
Chris Lattner24943d22010-06-08 16:52:24 +0000247 {
248 case eStopReasonTrace:
249 case eStopReasonPlanComplete:
250 {
251 static char trace_desc[] = "step";
252 stop_desc = trace_desc;
253 stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
254 }
255 break;
256
257 case eStopReasonBreakpoint:
258 {
259 static char bp_desc[] = "breakpoint hit";
260 stop_desc = bp_desc;
261 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
262 }
263 break;
264
265 case eStopReasonWatchpoint:
266 {
267 static char wp_desc[] = "watchpoint hit";
268 stop_desc = wp_desc;
269 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
270 }
271 break;
272
273 case eStopReasonSignal:
274 {
Jim Ingham6297a3a2010-10-20 00:39:53 +0000275 stop_desc = m_opaque_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
Chris Lattner24943d22010-06-08 16:52:24 +0000276 if (stop_desc == NULL || stop_desc[0] == '\0')
277 {
278 static char signal_desc[] = "signal";
279 stop_desc = signal_desc;
280 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
281 }
282 }
283 break;
284
285 case eStopReasonException:
286 {
287 char exc_desc[] = "exception";
288 stop_desc = exc_desc;
289 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
290 }
Greg Clayton54e7afa2010-07-09 20:39:50 +0000291 break;
292
293 default:
294 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000295 }
296
297 if (stop_desc && stop_desc[0])
298 {
Caroline Tice7826c882010-10-26 03:11:13 +0000299 if (log)
Greg Clayton3f5ee7f2010-10-29 04:59:35 +0000300 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
Caroline Tice61ba7ec2010-10-26 23:49:36 +0000301 m_opaque_sp.get(), stop_desc);
Caroline Tice7826c882010-10-26 03:11:13 +0000302
Chris Lattner24943d22010-06-08 16:52:24 +0000303 if (dst)
304 return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
305
306 if (stop_desc_len == 0)
307 stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
308
309 return stop_desc_len;
310 }
311 }
312 }
313 }
314 if (dst)
315 *dst = 0;
316 return 0;
317}
318
319void
320SBThread::SetThread (const ThreadSP& lldb_object_sp)
321{
Greg Clayton63094e02010-06-23 01:19:29 +0000322 m_opaque_sp = lldb_object_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000323}
324
325
326lldb::tid_t
327SBThread::GetThreadID () const
328{
Greg Claytone005f2c2010-11-06 01:53:30 +0000329 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000330
Greg Claytonbdcda462010-12-20 20:49:23 +0000331 lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
Greg Clayton63094e02010-06-23 01:19:29 +0000332 if (m_opaque_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000333 tid = m_opaque_sp->GetID();
Caroline Tice7826c882010-10-26 03:11:13 +0000334
335 if (log)
Greg Claytonbdcda462010-12-20 20:49:23 +0000336 log->Printf ("SBThread(%p)::GetThreadID () => 0x%4.4x", m_opaque_sp.get(), tid);
Caroline Tice7826c882010-10-26 03:11:13 +0000337
Greg Claytonbdcda462010-12-20 20:49:23 +0000338 return tid;
Chris Lattner24943d22010-06-08 16:52:24 +0000339}
340
341uint32_t
342SBThread::GetIndexID () const
343{
Greg Clayton63094e02010-06-23 01:19:29 +0000344 if (m_opaque_sp)
345 return m_opaque_sp->GetIndexID();
Chris Lattner24943d22010-06-08 16:52:24 +0000346 return LLDB_INVALID_INDEX32;
347}
348const char *
349SBThread::GetName () const
350{
Greg Claytona66ba462010-10-30 04:51:46 +0000351 const char *name = NULL;
Greg Clayton63094e02010-06-23 01:19:29 +0000352 if (m_opaque_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000353 {
354 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Claytona66ba462010-10-30 04:51:46 +0000355 name = m_opaque_sp->GetName();
Greg Claytonbdcda462010-12-20 20:49:23 +0000356 }
Greg Claytona66ba462010-10-30 04:51:46 +0000357
Greg Claytone005f2c2010-11-06 01:53:30 +0000358 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000359 if (log)
Greg Claytona66ba462010-10-30 04:51:46 +0000360 log->Printf ("SBThread(%p)::GetName () => %s", m_opaque_sp.get(), name ? name : "NULL");
Caroline Tice7826c882010-10-26 03:11:13 +0000361
Greg Claytona66ba462010-10-30 04:51:46 +0000362 return name;
Chris Lattner24943d22010-06-08 16:52:24 +0000363}
364
365const char *
366SBThread::GetQueueName () const
367{
Greg Claytona66ba462010-10-30 04:51:46 +0000368 const char *name = NULL;
Greg Clayton63094e02010-06-23 01:19:29 +0000369 if (m_opaque_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000370 {
371 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Claytona66ba462010-10-30 04:51:46 +0000372 name = m_opaque_sp->GetQueueName();
Greg Claytonbdcda462010-12-20 20:49:23 +0000373 }
Greg Claytona66ba462010-10-30 04:51:46 +0000374
Greg Claytone005f2c2010-11-06 01:53:30 +0000375 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000376 if (log)
Greg Claytona66ba462010-10-30 04:51:46 +0000377 log->Printf ("SBThread(%p)::GetQueueName () => %s", m_opaque_sp.get(), name ? name : "NULL");
Caroline Tice7826c882010-10-26 03:11:13 +0000378
Greg Claytona66ba462010-10-30 04:51:46 +0000379 return name;
Chris Lattner24943d22010-06-08 16:52:24 +0000380}
381
382
383void
Chris Lattner24943d22010-06-08 16:52:24 +0000384SBThread::StepOver (lldb::RunMode stop_other_threads)
385{
Greg Claytone005f2c2010-11-06 01:53:30 +0000386 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000387
388 if (log)
Greg Clayton3f5ee7f2010-10-29 04:59:35 +0000389 log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", m_opaque_sp.get(),
Caroline Tice7826c882010-10-26 03:11:13 +0000390 Thread::RunModeAsCString (stop_other_threads));
391
Greg Clayton63094e02010-06-23 01:19:29 +0000392 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000393 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000394 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000395 bool abort_other_plans = true;
Greg Clayton63094e02010-06-23 01:19:29 +0000396 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000397
398 if (frame_sp)
399 {
400 if (frame_sp->HasDebugInformation ())
401 {
402 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000403 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
Greg Clayton1a3083a2010-10-06 03:53:16 +0000404 eStepTypeOver,
405 sc.line_entry.range,
406 sc,
407 stop_other_threads,
408 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000409
410 }
411 else
412 {
Greg Clayton63094e02010-06-23 01:19:29 +0000413 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true,
Greg Clayton1a3083a2010-10-06 03:53:16 +0000414 abort_other_plans,
415 stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000416 }
417 }
418
Greg Clayton63094e02010-06-23 01:19:29 +0000419 Process &process = m_opaque_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000420 // Why do we need to set the current thread by ID here???
Jim Inghamc8332952010-08-26 21:32:51 +0000421 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000422 Error error (process.Resume());
423 if (error.Success())
424 {
425 // If we are doing synchronous mode, then wait for the
426 // process to stop yet again!
427 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
428 process.WaitForProcessToStop (NULL);
429 }
Chris Lattner24943d22010-06-08 16:52:24 +0000430 }
431}
432
433void
434SBThread::StepInto (lldb::RunMode stop_other_threads)
435{
Greg Claytone005f2c2010-11-06 01:53:30 +0000436 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000437
438 if (log)
Greg Clayton3f5ee7f2010-10-29 04:59:35 +0000439 log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", m_opaque_sp.get(),
Caroline Tice7826c882010-10-26 03:11:13 +0000440 Thread::RunModeAsCString (stop_other_threads));
441
Greg Clayton63094e02010-06-23 01:19:29 +0000442 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000443 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000444 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000445 bool abort_other_plans = true;
446
Greg Clayton63094e02010-06-23 01:19:29 +0000447 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000448
449 if (frame_sp && frame_sp->HasDebugInformation ())
450 {
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000451 bool avoid_code_without_debug_info = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000452 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000453 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
Greg Clayton1a3083a2010-10-06 03:53:16 +0000454 eStepTypeInto,
455 sc.line_entry.range,
456 sc,
457 stop_other_threads,
458 avoid_code_without_debug_info);
Chris Lattner24943d22010-06-08 16:52:24 +0000459 }
460 else
461 {
Greg Clayton63094e02010-06-23 01:19:29 +0000462 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false,
Greg Clayton1a3083a2010-10-06 03:53:16 +0000463 abort_other_plans,
464 stop_other_threads);
Chris Lattner24943d22010-06-08 16:52:24 +0000465 }
466
Greg Clayton63094e02010-06-23 01:19:29 +0000467 Process &process = m_opaque_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000468 // Why do we need to set the current thread by ID here???
Jim Inghamc8332952010-08-26 21:32:51 +0000469 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000470 Error error (process.Resume());
471 if (error.Success())
472 {
473 // If we are doing synchronous mode, then wait for the
474 // process to stop yet again!
475 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
476 process.WaitForProcessToStop (NULL);
477 }
Chris Lattner24943d22010-06-08 16:52:24 +0000478 }
479}
480
481void
482SBThread::StepOut ()
483{
Greg Claytone005f2c2010-11-06 01:53:30 +0000484 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000485
486 if (log)
Greg Claytona66ba462010-10-30 04:51:46 +0000487 log->Printf ("SBThread(%p)::StepOut ()", m_opaque_sp.get());
Caroline Tice7826c882010-10-26 03:11:13 +0000488
Greg Clayton63094e02010-06-23 01:19:29 +0000489 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000490 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000491 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000492 bool abort_other_plans = true;
493 bool stop_other_threads = true;
494
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000495 m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans,
496 NULL,
497 false,
498 stop_other_threads,
499 eVoteYes,
500 eVoteNoOpinion,
501 0);
502
503 Process &process = m_opaque_sp->GetProcess();
504 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
505 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 }
513 }
514}
Chris Lattner24943d22010-06-08 16:52:24 +0000515
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000516void
517SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
518{
519 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
520
521 if (log)
522 {
523 SBStream frame_desc_strm;
524 sb_frame.GetDescription (frame_desc_strm);
525 log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
526 }
527
528 if (m_opaque_sp)
529 {
530 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
531 bool abort_other_plans = true;
532 bool stop_other_threads = true;
533
534 m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans,
535 NULL,
536 false,
537 stop_other_threads,
538 eVoteYes,
539 eVoteNoOpinion,
540 sb_frame->GetFrameIndex());
541
Greg Clayton63094e02010-06-23 01:19:29 +0000542 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000543 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000544 Error error (process.Resume());
545 if (error.Success())
546 {
547 // If we are doing synchronous mode, then wait for the
548 // process to stop yet again!
549 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
550 process.WaitForProcessToStop (NULL);
551 }
Chris Lattner24943d22010-06-08 16:52:24 +0000552 }
553}
554
555void
556SBThread::StepInstruction (bool step_over)
557{
Greg Claytone005f2c2010-11-06 01:53:30 +0000558 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000559
560 if (log)
Greg Clayton3f5ee7f2010-10-29 04:59:35 +0000561 log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", m_opaque_sp.get(), step_over);
Caroline Tice7826c882010-10-26 03:11:13 +0000562
Greg Clayton63094e02010-06-23 01:19:29 +0000563 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000564 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000565 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Clayton63094e02010-06-23 01:19:29 +0000566 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
567 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000568 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000569 Error error (process.Resume());
570 if (error.Success())
571 {
572 // If we are doing synchronous mode, then wait for the
573 // process to stop yet again!
574 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
575 process.WaitForProcessToStop (NULL);
576 }
Chris Lattner24943d22010-06-08 16:52:24 +0000577 }
578}
579
580void
581SBThread::RunToAddress (lldb::addr_t addr)
582{
Greg Claytone005f2c2010-11-06 01:53:30 +0000583 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000584
585 if (log)
Greg Clayton3f5ee7f2010-10-29 04:59:35 +0000586 log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", m_opaque_sp.get(), addr);
Caroline Tice7826c882010-10-26 03:11:13 +0000587
Greg Clayton63094e02010-06-23 01:19:29 +0000588 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000589 {
590 bool abort_other_plans = true;
591 bool stop_other_threads = true;
592
593 Address target_addr (NULL, addr);
594
Greg Clayton63094e02010-06-23 01:19:29 +0000595 m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
596 Process &process = m_opaque_sp->GetProcess();
Jim Inghamc8332952010-08-26 21:32:51 +0000597 process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
Greg Clayton1a3083a2010-10-06 03:53:16 +0000598 Error error (process.Resume());
599 if (error.Success())
600 {
601 // If we are doing synchronous mode, then wait for the
602 // process to stop yet again!
603 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
604 process.WaitForProcessToStop (NULL);
605 }
Chris Lattner24943d22010-06-08 16:52:24 +0000606 }
Chris Lattner24943d22010-06-08 16:52:24 +0000607}
608
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000609SBError
610SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
611 lldb::SBFileSpec &sb_file_spec,
612 uint32_t line)
613{
614 SBError sb_error;
615 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
616 char path[PATH_MAX];
617
618 if (log)
619 {
620 SBStream frame_desc_strm;
621 sb_frame.GetDescription (frame_desc_strm);
622 sb_file_spec->GetPath (path, sizeof(path));
623 log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
624 m_opaque_sp.get(),
625 sb_frame.get(),
626 frame_desc_strm.GetData(),
627 path, line);
628 }
629
630 if (m_opaque_sp)
631 {
632 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
633
634 if (line == 0)
635 {
636 sb_error.SetErrorString("invalid line argument");
637 return sb_error;
638 }
639
640 StackFrameSP frame_sp;
641 if (sb_frame.IsValid())
642 frame_sp = sb_frame.get_sp();
643 else
644 {
645 frame_sp = m_opaque_sp->GetSelectedFrame ();
646 if (!frame_sp)
647 frame_sp = m_opaque_sp->GetStackFrameAtIndex (0);
648 }
649
650 SymbolContext frame_sc;
651 if (!frame_sp)
652 {
653 sb_error.SetErrorString("no valid frames in thread to step");
654 return sb_error;
655 }
656
657 // If we have a frame, get its line
658 frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit |
659 eSymbolContextFunction |
660 eSymbolContextLineEntry |
661 eSymbolContextSymbol );
662
663 if (frame_sc.comp_unit == NULL)
664 {
665 sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
666 return sb_error;
667 }
668
669 FileSpec step_file_spec;
670 if (sb_file_spec.IsValid())
671 {
672 // The file spec passed in was valid, so use it
673 step_file_spec = sb_file_spec.ref();
674 }
675 else
676 {
677 if (frame_sc.line_entry.IsValid())
678 step_file_spec = frame_sc.line_entry.file;
679 else
680 {
681 sb_error.SetErrorString("invalid file argument or no file for frame");
682 return sb_error;
683 }
684 }
685
686 std::vector<addr_t> step_over_until_addrs;
687 const bool abort_other_plans = true;
688 const bool stop_other_threads = true;
689 const bool check_inlines = true;
690 const bool exact = false;
691
692 SymbolContextList sc_list;
693 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry, sc_list);
694 if (num_matches > 0)
695 {
696 SymbolContext sc;
697 for (uint32_t i=0; i<num_matches; ++i)
698 {
699 if (sc_list.GetContextAtIndex(i, sc))
700 {
701 addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(&m_opaque_sp->GetProcess().GetTarget());
702 if (step_addr != LLDB_INVALID_ADDRESS)
703 {
704 step_over_until_addrs.push_back(step_addr);
705 }
706 }
707 }
708 }
709
710 if (step_over_until_addrs.empty())
711 {
712 step_file_spec.GetPath (path, sizeof(path));
713 sb_error.SetErrorStringWithFormat("No line entries for %s:u", path, line);
714 }
715 else
716 {
717 m_opaque_sp->QueueThreadPlanForStepUntil (abort_other_plans,
718 &step_over_until_addrs[0],
719 step_over_until_addrs.size(),
720 stop_other_threads,
721 frame_sp->GetFrameIndex());
722
723 m_opaque_sp->GetProcess().GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
724 sb_error.ref() = m_opaque_sp->GetProcess().Resume();
725 if (sb_error->Success())
726 {
727 // If we are doing synchronous mode, then wait for the
728 // process to stop yet again!
729 if (m_opaque_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false)
730 m_opaque_sp->GetProcess().WaitForProcessToStop (NULL);
731 }
732 }
733 }
734 else
735 {
736 sb_error.SetErrorString("this SBThread object is invalid");
737 }
738 return sb_error;
739}
740
741
Greg Clayton123db402011-01-12 02:25:42 +0000742bool
743SBThread::Suspend()
744{
745 if (m_opaque_sp)
746 {
747 m_opaque_sp->SetResumeState (eStateSuspended);
748 return true;
749 }
750 return false;
751}
752
753bool
754SBThread::Resume ()
755{
756 if (m_opaque_sp)
757 {
758 m_opaque_sp->SetResumeState (eStateRunning);
759 return true;
760 }
761 return false;
762}
763
764bool
765SBThread::IsSuspended()
766{
767 if (m_opaque_sp)
Greg Claytonf41d4ca2011-01-18 21:43:22 +0000768 return m_opaque_sp->GetResumeState () == eStateSuspended;
Greg Clayton123db402011-01-12 02:25:42 +0000769 return false;
770}
771
Chris Lattner24943d22010-06-08 16:52:24 +0000772SBProcess
773SBThread::GetProcess ()
774{
Caroline Tice7826c882010-10-26 03:11:13 +0000775
Chris Lattner24943d22010-06-08 16:52:24 +0000776 SBProcess process;
Greg Clayton63094e02010-06-23 01:19:29 +0000777 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000778 {
779 // Have to go up to the target so we can get a shared pointer to our process...
Greg Clayton63094e02010-06-23 01:19:29 +0000780 process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000781 }
Caroline Tice7826c882010-10-26 03:11:13 +0000782
Greg Claytone005f2c2010-11-06 01:53:30 +0000783 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000784 if (log)
785 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000786 SBStream frame_desc_strm;
787 process.GetDescription (frame_desc_strm);
Greg Claytona66ba462010-10-30 04:51:46 +0000788 log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", m_opaque_sp.get(),
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000789 process.get(), frame_desc_strm.GetData());
Caroline Tice7826c882010-10-26 03:11:13 +0000790 }
791
Chris Lattner24943d22010-06-08 16:52:24 +0000792 return process;
793}
794
795uint32_t
796SBThread::GetNumFrames ()
797{
Greg Claytone005f2c2010-11-06 01:53:30 +0000798 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000799
Caroline Tice7826c882010-10-26 03:11:13 +0000800 uint32_t num_frames = 0;
Greg Clayton63094e02010-06-23 01:19:29 +0000801 if (m_opaque_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000802 {
803 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Caroline Tice7826c882010-10-26 03:11:13 +0000804 num_frames = m_opaque_sp->GetStackFrameCount();
Greg Claytonbdcda462010-12-20 20:49:23 +0000805 }
Caroline Tice7826c882010-10-26 03:11:13 +0000806
807 if (log)
Greg Claytona66ba462010-10-30 04:51:46 +0000808 log->Printf ("SBThread(%p)::GetNumFrames () => %u", m_opaque_sp.get(), num_frames);
Caroline Tice7826c882010-10-26 03:11:13 +0000809
810 return num_frames;
Chris Lattner24943d22010-06-08 16:52:24 +0000811}
812
813SBFrame
814SBThread::GetFrameAtIndex (uint32_t idx)
815{
Greg Claytone005f2c2010-11-06 01:53:30 +0000816 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Caroline Tice7826c882010-10-26 03:11:13 +0000817
Chris Lattner24943d22010-06-08 16:52:24 +0000818 SBFrame sb_frame;
Greg Clayton63094e02010-06-23 01:19:29 +0000819 if (m_opaque_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000820 {
821 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Clayton63094e02010-06-23 01:19:29 +0000822 sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx));
Greg Claytonbdcda462010-12-20 20:49:23 +0000823 }
Caroline Tice7826c882010-10-26 03:11:13 +0000824
825 if (log)
826 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000827 SBStream frame_desc_strm;
828 sb_frame.GetDescription (frame_desc_strm);
Greg Claytona66ba462010-10-30 04:51:46 +0000829 log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000830 m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
Caroline Tice7826c882010-10-26 03:11:13 +0000831 }
832
Chris Lattner24943d22010-06-08 16:52:24 +0000833 return sb_frame;
834}
835
Greg Claytonc5157ec2010-12-17 02:26:24 +0000836lldb::SBFrame
837SBThread::GetSelectedFrame ()
838{
839 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
840
841 SBFrame sb_frame;
842 if (m_opaque_sp)
Greg Claytonbdcda462010-12-20 20:49:23 +0000843 {
844 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Claytonc5157ec2010-12-17 02:26:24 +0000845 sb_frame.SetFrame (m_opaque_sp->GetSelectedFrame ());
Greg Claytonbdcda462010-12-20 20:49:23 +0000846 }
Greg Claytonc5157ec2010-12-17 02:26:24 +0000847
848 if (log)
849 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000850 SBStream frame_desc_strm;
851 sb_frame.GetDescription (frame_desc_strm);
Greg Claytonc5157ec2010-12-17 02:26:24 +0000852 log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000853 m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
Greg Claytonc5157ec2010-12-17 02:26:24 +0000854 }
855
856 return sb_frame;
857}
858
859lldb::SBFrame
860SBThread::SetSelectedFrame (uint32_t idx)
861{
862 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
863
864 SBFrame sb_frame;
865 if (m_opaque_sp)
866 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000867 Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
Greg Claytonc5157ec2010-12-17 02:26:24 +0000868 lldb::StackFrameSP frame_sp (m_opaque_sp->GetStackFrameAtIndex (idx));
869 if (frame_sp)
870 {
871 m_opaque_sp->SetSelectedFrame (frame_sp.get());
872 sb_frame.SetFrame (frame_sp);
873 }
874 }
875
876 if (log)
877 {
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000878 SBStream frame_desc_strm;
879 sb_frame.GetDescription (frame_desc_strm);
Greg Claytonc5157ec2010-12-17 02:26:24 +0000880 log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000881 m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
Greg Claytonc5157ec2010-12-17 02:26:24 +0000882 }
883 return sb_frame;
884}
885
886
Chris Lattner24943d22010-06-08 16:52:24 +0000887bool
888SBThread::operator == (const SBThread &rhs) const
889{
Greg Clayton63094e02010-06-23 01:19:29 +0000890 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000891}
892
893bool
894SBThread::operator != (const SBThread &rhs) const
895{
Greg Clayton63094e02010-06-23 01:19:29 +0000896 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000897}
898
899lldb_private::Thread *
Greg Claytona66ba462010-10-30 04:51:46 +0000900SBThread::get ()
Chris Lattner24943d22010-06-08 16:52:24 +0000901{
Greg Clayton63094e02010-06-23 01:19:29 +0000902 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000903}
904
905const lldb_private::Thread *
906SBThread::operator->() const
907{
Greg Clayton63094e02010-06-23 01:19:29 +0000908 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000909}
910
911const lldb_private::Thread &
912SBThread::operator*() const
913{
Greg Clayton63094e02010-06-23 01:19:29 +0000914 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000915}
916
917lldb_private::Thread *
918SBThread::operator->()
919{
Greg Clayton63094e02010-06-23 01:19:29 +0000920 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000921}
922
923lldb_private::Thread &
924SBThread::operator*()
925{
Greg Clayton63094e02010-06-23 01:19:29 +0000926 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000927}
Caroline Tice98f930f2010-09-20 05:20:02 +0000928
929bool
Caroline Tice7826c882010-10-26 03:11:13 +0000930SBThread::GetDescription (SBStream &description) const
931{
932 if (m_opaque_sp)
933 {
934 StreamString strm;
935 description.Printf("SBThread: tid = 0x%4.4x", m_opaque_sp->GetID());
936 }
937 else
938 description.Printf ("No value");
939
940 return true;
941}