blob: 8f4b3b9d99ef1f6d74223b2d8e07565bfaa11d90 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedman7a62c8b2010-06-09 07:44:37 +000010#include "lldb/API/SBThread.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12#include "lldb/API/SBSymbolContext.h"
13#include "lldb/API/SBFileSpec.h"
Greg Clayton63094e02010-06-23 01:19:29 +000014#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000015#include "lldb/Core/Stream.h"
16#include "lldb/Core/StreamFile.h"
Greg Clayton63094e02010-06-23 01:19:29 +000017#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Target/Thread.h"
19#include "lldb/Target/Process.h"
20#include "lldb/Symbol/SymbolContext.h"
21#include "lldb/Symbol/CompileUnit.h"
22#include "lldb/Target/Target.h"
23#include "lldb/Target/ThreadPlan.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Target/ThreadPlanStepInstruction.h"
25#include "lldb/Target/ThreadPlanStepOut.h"
26#include "lldb/Target/ThreadPlanStepRange.h"
27#include "lldb/Target/ThreadPlanStepInRange.h"
28
29
Eli Friedman7a62c8b2010-06-09 07:44:37 +000030#include "lldb/API/SBAddress.h"
31#include "lldb/API/SBFrame.h"
32#include "lldb/API/SBSourceManager.h"
33#include "lldb/API/SBDebugger.h"
34#include "lldb/API/SBProcess.h"
Chris Lattner24943d22010-06-08 16:52:24 +000035
36using namespace lldb;
37using namespace lldb_private;
38
39SBThread::SBThread () :
Greg Clayton63094e02010-06-23 01:19:29 +000040 m_opaque_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +000041{
42}
43
44//----------------------------------------------------------------------
45// Thread constructor
46//----------------------------------------------------------------------
47SBThread::SBThread (const ThreadSP& lldb_object_sp) :
Greg Clayton63094e02010-06-23 01:19:29 +000048 m_opaque_sp (lldb_object_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000049{
50}
51
52SBThread::SBThread (const SBThread &rhs)
53{
Greg Clayton63094e02010-06-23 01:19:29 +000054 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000055}
56
57//----------------------------------------------------------------------
58// Destructor
59//----------------------------------------------------------------------
60SBThread::~SBThread()
61{
62}
63
64bool
65SBThread::IsValid() const
66{
Greg Clayton63094e02010-06-23 01:19:29 +000067 return m_opaque_sp != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +000068}
69
70StopReason
71SBThread::GetStopReason()
72{
Greg Clayton63094e02010-06-23 01:19:29 +000073 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000074 {
75 lldb_private::Thread::StopInfo thread_stop_info;
Greg Clayton63094e02010-06-23 01:19:29 +000076 if (m_opaque_sp->GetStopInfo(&thread_stop_info))
Chris Lattner24943d22010-06-08 16:52:24 +000077 return thread_stop_info.GetStopReason();
78 }
79 return eStopReasonInvalid;
80}
81
82size_t
83SBThread::GetStopDescription (char *dst, size_t dst_len)
84{
Greg Clayton63094e02010-06-23 01:19:29 +000085 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000086 {
87 lldb_private::Thread::StopInfo thread_stop_info;
Greg Clayton63094e02010-06-23 01:19:29 +000088 if (m_opaque_sp->GetStopInfo(&thread_stop_info))
Chris Lattner24943d22010-06-08 16:52:24 +000089 {
90 const char *stop_desc = thread_stop_info.GetStopDescription();
91 if (stop_desc)
92 {
93 if (dst)
94 return ::snprintf (dst, dst_len, "%s", stop_desc);
95 else
96 {
97 // NULL dst passed in, return the length needed to contain the description
98 return ::strlen (stop_desc) + 1; // Include the NULL byte for size
99 }
100 }
101 else
102 {
103 const char *stop_desc = NULL;
104 size_t stop_desc_len = 0;
105 switch (thread_stop_info.GetStopReason())
106 {
107 case eStopReasonTrace:
108 case eStopReasonPlanComplete:
109 {
110 static char trace_desc[] = "step";
111 stop_desc = trace_desc;
112 stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
113 }
114 break;
115
116 case eStopReasonBreakpoint:
117 {
118 static char bp_desc[] = "breakpoint hit";
119 stop_desc = bp_desc;
120 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
121 }
122 break;
123
124 case eStopReasonWatchpoint:
125 {
126 static char wp_desc[] = "watchpoint hit";
127 stop_desc = wp_desc;
128 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
129 }
130 break;
131
132 case eStopReasonSignal:
133 {
Greg Clayton63094e02010-06-23 01:19:29 +0000134 stop_desc = m_opaque_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (thread_stop_info.GetSignal());
Chris Lattner24943d22010-06-08 16:52:24 +0000135 if (stop_desc == NULL || stop_desc[0] == '\0')
136 {
137 static char signal_desc[] = "signal";
138 stop_desc = signal_desc;
139 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
140 }
141 }
142 break;
143
144 case eStopReasonException:
145 {
146 char exc_desc[] = "exception";
147 stop_desc = exc_desc;
148 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
149 }
Greg Clayton54e7afa2010-07-09 20:39:50 +0000150 break;
151
152 default:
153 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000154 }
155
156 if (stop_desc && stop_desc[0])
157 {
158 if (dst)
159 return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
160
161 if (stop_desc_len == 0)
162 stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
163
164 return stop_desc_len;
165 }
166 }
167 }
168 }
169 if (dst)
170 *dst = 0;
171 return 0;
172}
173
174void
175SBThread::SetThread (const ThreadSP& lldb_object_sp)
176{
Greg Clayton63094e02010-06-23 01:19:29 +0000177 m_opaque_sp = lldb_object_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000178}
179
180
181lldb::tid_t
182SBThread::GetThreadID () const
183{
Greg Clayton63094e02010-06-23 01:19:29 +0000184 if (m_opaque_sp)
185 return m_opaque_sp->GetID();
Chris Lattner24943d22010-06-08 16:52:24 +0000186 else
187 return LLDB_INVALID_THREAD_ID;
188}
189
190uint32_t
191SBThread::GetIndexID () const
192{
Greg Clayton63094e02010-06-23 01:19:29 +0000193 if (m_opaque_sp)
194 return m_opaque_sp->GetIndexID();
Chris Lattner24943d22010-06-08 16:52:24 +0000195 return LLDB_INVALID_INDEX32;
196}
197const char *
198SBThread::GetName () const
199{
Greg Clayton63094e02010-06-23 01:19:29 +0000200 if (m_opaque_sp)
201 return m_opaque_sp->GetName();
Chris Lattner24943d22010-06-08 16:52:24 +0000202 return NULL;
203}
204
205const char *
206SBThread::GetQueueName () const
207{
Greg Clayton63094e02010-06-23 01:19:29 +0000208 if (m_opaque_sp)
209 return m_opaque_sp->GetQueueName();
Chris Lattner24943d22010-06-08 16:52:24 +0000210 return NULL;
211}
212
213
214void
215SBThread::DisplayFramesForCurrentContext (FILE *out,
216 FILE *err,
217 uint32_t first_frame,
218 uint32_t num_frames,
219 bool show_frame_info,
220 uint32_t num_frames_with_source,
221 uint32_t source_lines_before,
222 uint32_t source_lines_after)
223{
224 if ((out == NULL) || (err == NULL))
225 return;
226
Greg Clayton63094e02010-06-23 01:19:29 +0000227 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000228 {
Greg Clayton63094e02010-06-23 01:19:29 +0000229 uint32_t num_stack_frames = m_opaque_sp->GetStackFrameCount ();
Chris Lattner24943d22010-06-08 16:52:24 +0000230 StackFrameSP frame_sp;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000231 uint32_t frame_idx = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000232
233 for (frame_idx = first_frame; frame_idx < first_frame + num_frames; ++frame_idx)
234 {
235 if (frame_idx >= num_stack_frames)
236 break;
237
Greg Clayton63094e02010-06-23 01:19:29 +0000238 frame_sp = m_opaque_sp->GetStackFrameAtIndex (frame_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000239 if (!frame_sp)
240 break;
241
242 SBFrame sb_frame (frame_sp);
243 if (DisplaySingleFrameForCurrentContext (out,
244 err,
245 sb_frame,
246 show_frame_info,
247 num_frames_with_source > first_frame - frame_idx,
248 source_lines_before,
249 source_lines_after) == false)
250 break;
251 }
252 }
253}
254
255bool
256SBThread::DisplaySingleFrameForCurrentContext (FILE *out,
257 FILE *err,
258 SBFrame &frame,
259 bool show_frame_info,
260 bool show_source,
261 uint32_t source_lines_after,
262 uint32_t source_lines_before)
263{
264 bool success = false;
Greg Clayton63094e02010-06-23 01:19:29 +0000265
266 if ((out == NULL) || (err == NULL))
Chris Lattner24943d22010-06-08 16:52:24 +0000267 return false;
Greg Clayton63094e02010-06-23 01:19:29 +0000268
269 if (m_opaque_sp && frame.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000270 {
Chris Lattner24943d22010-06-08 16:52:24 +0000271 StreamFile str (out);
Greg Clayton63094e02010-06-23 01:19:29 +0000272
Chris Lattner24943d22010-06-08 16:52:24 +0000273 SBSymbolContext sc(frame.GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000274
Chris Lattner24943d22010-06-08 16:52:24 +0000275 if (show_frame_info && sc.IsValid())
276 {
277 user_id_t frame_idx = (user_id_t) frame.GetFrameID();
278 lldb::addr_t pc = frame.GetPC();
279 ::fprintf (out,
280 " frame #%u: tid = 0x%4.4x, pc = 0x%llx ",
281 frame_idx,
282 GetThreadID(),
Eli Friedman0a164a12010-07-09 22:53:18 +0000283 (long long)pc);
Greg Clayton63094e02010-06-23 01:19:29 +0000284 sc->DumpStopContext (&str, &m_opaque_sp->GetProcess(), *frame.GetPCAddress());
Chris Lattner24943d22010-06-08 16:52:24 +0000285 fprintf (out, "\n");
286 success = true;
287 }
Greg Clayton63094e02010-06-23 01:19:29 +0000288
Chris Lattner24943d22010-06-08 16:52:24 +0000289 SBCompileUnit comp_unit(sc.GetCompileUnit());
290 if (show_source && comp_unit.IsValid())
291 {
Greg Clayton63094e02010-06-23 01:19:29 +0000292 success = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000293 SBLineEntry line_entry;
294 if (line_entry.IsValid())
295 {
Greg Clayton63094e02010-06-23 01:19:29 +0000296 SourceManager& source_manager = m_opaque_sp->GetProcess().GetTarget().GetDebugger().GetSourceManager();
297 SBFileSpec line_entry_file_spec (line_entry.GetFileSpec());
298
Chris Lattner24943d22010-06-08 16:52:24 +0000299 if (line_entry_file_spec.IsValid())
300 {
Greg Clayton63094e02010-06-23 01:19:29 +0000301 source_manager.DisplaySourceLinesWithLineNumbers (line_entry_file_spec.ref(),
Chris Lattner24943d22010-06-08 16:52:24 +0000302 line_entry.GetLine(),
303 source_lines_after,
304 source_lines_before, "->",
Greg Clayton63094e02010-06-23 01:19:29 +0000305 &str);
Chris Lattner24943d22010-06-08 16:52:24 +0000306 success = true;
307 }
308 }
309 }
310 }
311 return success;
312}
313
314void
315SBThread::StepOver (lldb::RunMode stop_other_threads)
316{
Greg Clayton63094e02010-06-23 01:19:29 +0000317 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000318 {
319 bool abort_other_plans = true;
Greg Clayton63094e02010-06-23 01:19:29 +0000320 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000321
322 if (frame_sp)
323 {
324 if (frame_sp->HasDebugInformation ())
325 {
326 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000327 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
Chris Lattner24943d22010-06-08 16:52:24 +0000328 eStepTypeOver,
329 sc.line_entry.range,
330 sc,
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000331 stop_other_threads,
332 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000333
334 }
335 else
336 {
Greg Clayton63094e02010-06-23 01:19:29 +0000337 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true,
Chris Lattner24943d22010-06-08 16:52:24 +0000338 abort_other_plans,
339 stop_other_threads);
340 }
341 }
342
Greg Clayton63094e02010-06-23 01:19:29 +0000343 Process &process = m_opaque_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000344 // Why do we need to set the current thread by ID here???
Greg Clayton63094e02010-06-23 01:19:29 +0000345 process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000346 process.Resume();
347 }
348}
349
350void
351SBThread::StepInto (lldb::RunMode stop_other_threads)
352{
Greg Clayton63094e02010-06-23 01:19:29 +0000353 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000354 {
355 bool abort_other_plans = true;
356
Greg Clayton63094e02010-06-23 01:19:29 +0000357 StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
Chris Lattner24943d22010-06-08 16:52:24 +0000358
359 if (frame_sp && frame_sp->HasDebugInformation ())
360 {
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000361 bool avoid_code_without_debug_info = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000362 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
Greg Clayton63094e02010-06-23 01:19:29 +0000363 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000364 eStepTypeInto,
365 sc.line_entry.range,
366 sc,
367 stop_other_threads,
368 avoid_code_without_debug_info);
Chris Lattner24943d22010-06-08 16:52:24 +0000369 }
370 else
371 {
Greg Clayton63094e02010-06-23 01:19:29 +0000372 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false,
Chris Lattner24943d22010-06-08 16:52:24 +0000373 abort_other_plans,
374 stop_other_threads);
375 }
376
Greg Clayton63094e02010-06-23 01:19:29 +0000377 Process &process = m_opaque_sp->GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +0000378 // Why do we need to set the current thread by ID here???
Greg Clayton63094e02010-06-23 01:19:29 +0000379 process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000380 process.Resume();
381
382 }
383}
384
385void
386SBThread::StepOut ()
387{
Greg Clayton63094e02010-06-23 01:19:29 +0000388 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000389 {
390 bool abort_other_plans = true;
391 bool stop_other_threads = true;
392
Greg Clayton63094e02010-06-23 01:19:29 +0000393 m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion);
Chris Lattner24943d22010-06-08 16:52:24 +0000394
Greg Clayton63094e02010-06-23 01:19:29 +0000395 Process &process = m_opaque_sp->GetProcess();
396 process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000397 process.Resume();
398 }
399}
400
401void
402SBThread::StepInstruction (bool step_over)
403{
Greg Clayton63094e02010-06-23 01:19:29 +0000404 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000405 {
Greg Clayton63094e02010-06-23 01:19:29 +0000406 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
407 Process &process = m_opaque_sp->GetProcess();
408 process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000409 process.Resume();
410 }
411}
412
413void
414SBThread::RunToAddress (lldb::addr_t addr)
415{
Greg Clayton63094e02010-06-23 01:19:29 +0000416 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000417 {
418 bool abort_other_plans = true;
419 bool stop_other_threads = true;
420
421 Address target_addr (NULL, addr);
422
Greg Clayton63094e02010-06-23 01:19:29 +0000423 m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
424 Process &process = m_opaque_sp->GetProcess();
425 process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000426 process.Resume();
427 }
428
429}
430
Chris Lattner24943d22010-06-08 16:52:24 +0000431SBProcess
432SBThread::GetProcess ()
433{
434 SBProcess process;
Greg Clayton63094e02010-06-23 01:19:29 +0000435 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000436 {
437 // Have to go up to the target so we can get a shared pointer to our process...
Greg Clayton63094e02010-06-23 01:19:29 +0000438 process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000439 }
440 return process;
441}
442
443uint32_t
444SBThread::GetNumFrames ()
445{
Greg Clayton63094e02010-06-23 01:19:29 +0000446 if (m_opaque_sp)
447 return m_opaque_sp->GetStackFrameCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000448 return 0;
449}
450
451SBFrame
452SBThread::GetFrameAtIndex (uint32_t idx)
453{
454 SBFrame sb_frame;
Greg Clayton63094e02010-06-23 01:19:29 +0000455 if (m_opaque_sp)
456 sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000457 return sb_frame;
458}
459
460const lldb::SBThread &
461SBThread::operator = (const lldb::SBThread &rhs)
462{
Greg Clayton63094e02010-06-23 01:19:29 +0000463 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000464 return *this;
465}
466
467bool
468SBThread::operator == (const SBThread &rhs) const
469{
Greg Clayton63094e02010-06-23 01:19:29 +0000470 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000471}
472
473bool
474SBThread::operator != (const SBThread &rhs) const
475{
Greg Clayton63094e02010-06-23 01:19:29 +0000476 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000477}
478
479lldb_private::Thread *
480SBThread::GetLLDBObjectPtr ()
481{
Greg Clayton63094e02010-06-23 01:19:29 +0000482 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000483}
484
485const lldb_private::Thread *
486SBThread::operator->() const
487{
Greg Clayton63094e02010-06-23 01:19:29 +0000488 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000489}
490
491const lldb_private::Thread &
492SBThread::operator*() const
493{
Greg Clayton63094e02010-06-23 01:19:29 +0000494 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000495}
496
497lldb_private::Thread *
498SBThread::operator->()
499{
Greg Clayton63094e02010-06-23 01:19:29 +0000500 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000501}
502
503lldb_private::Thread &
504SBThread::operator*()
505{
Greg Clayton63094e02010-06-23 01:19:29 +0000506 return *m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000507}