1 //===-- 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 
10 #include "lldb/API/SBThread.h"
11 
12 #include "lldb/API/SBSymbolContext.h"
13 #include "lldb/API/SBFileSpec.h"
14 #include "lldb/API/SBStream.h"
15 #include "lldb/Breakpoint/BreakpointLocation.h"
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/Stream.h"
18 #include "lldb/Core/StreamFile.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Target/Thread.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Symbol/SymbolContext.h"
23 #include "lldb/Symbol/CompileUnit.h"
24 #include "lldb/Target/StopInfo.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/ThreadPlan.h"
27 #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 
33 #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"
38 
39 using namespace lldb;
40 using namespace lldb_private;
41 
42 //----------------------------------------------------------------------
43 // Constructors
44 //----------------------------------------------------------------------
45 SBThread::SBThread () :
46     m_opaque_sp ()
47 {
48 }
49 
50 SBThread::SBThread (const ThreadSP& lldb_object_sp) :
51     m_opaque_sp (lldb_object_sp)
52 {
53 }
54 
55 SBThread::SBThread (const SBThread &rhs) :
56     m_opaque_sp (rhs.m_opaque_sp)
57 {
58 }
59 
60 //----------------------------------------------------------------------
61 // Assignment operator
62 //----------------------------------------------------------------------
63 
64 const lldb::SBThread &
65 SBThread::operator = (const SBThread &rhs)
66 {
67     if (this != &rhs)
68         m_opaque_sp = rhs.m_opaque_sp;
69     return *this;
70 }
71 
72 //----------------------------------------------------------------------
73 // Destructor
74 //----------------------------------------------------------------------
75 SBThread::~SBThread()
76 {
77 }
78 
79 bool
80 SBThread::IsValid() const
81 {
82     return m_opaque_sp != NULL;
83 }
84 
85 void
86 SBThread::Clear ()
87 {
88     m_opaque_sp.reset();
89 }
90 
91 
92 StopReason
93 SBThread::GetStopReason()
94 {
95     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
96 
97     StopReason reason = eStopReasonInvalid;
98     if (m_opaque_sp)
99     {
100         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
101         StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
102         if (stop_info_sp)
103             reason =  stop_info_sp->GetStopReason();
104     }
105 
106     if (log)
107         log->Printf ("SBThread(%p)::GetStopReason () => %s", m_opaque_sp.get(),
108                      Thread::StopReasonAsCString (reason));
109 
110     return reason;
111 }
112 
113 size_t
114 SBThread::GetStopReasonDataCount ()
115 {
116     if (m_opaque_sp)
117     {
118         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
119         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 
158 uint64_t
159 SBThread::GetStopReasonDataAtIndex (uint32_t idx)
160 {
161     if (m_opaque_sp)
162     {
163         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
164         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 
218 size_t
219 SBThread::GetStopDescription (char *dst, size_t dst_len)
220 {
221     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
222 
223     if (m_opaque_sp)
224     {
225         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
226         StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
227         if (stop_info_sp)
228         {
229             const char *stop_desc = stop_info_sp->GetDescription();
230             if (stop_desc)
231             {
232                 if (log)
233                     log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
234                                  m_opaque_sp.get(), stop_desc);
235                 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             {
245                 size_t stop_desc_len = 0;
246                 switch (stop_info_sp->GetStopReason())
247                 {
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                     {
275                         stop_desc = m_opaque_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
276                         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                     }
291                     break;
292 
293                 default:
294                     break;
295                 }
296 
297                 if (stop_desc && stop_desc[0])
298                 {
299                     if (log)
300                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
301                                      m_opaque_sp.get(), stop_desc);
302 
303                     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 
319 void
320 SBThread::SetThread (const ThreadSP& lldb_object_sp)
321 {
322     m_opaque_sp = lldb_object_sp;
323 }
324 
325 
326 lldb::tid_t
327 SBThread::GetThreadID () const
328 {
329     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
330 
331     lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
332     if (m_opaque_sp)
333         tid = m_opaque_sp->GetID();
334 
335     if (log)
336         log->Printf ("SBThread(%p)::GetThreadID () => 0x%4.4x", m_opaque_sp.get(), tid);
337 
338     return tid;
339 }
340 
341 uint32_t
342 SBThread::GetIndexID () const
343 {
344     if (m_opaque_sp)
345         return m_opaque_sp->GetIndexID();
346     return LLDB_INVALID_INDEX32;
347 }
348 const char *
349 SBThread::GetName () const
350 {
351     const char *name = NULL;
352     if (m_opaque_sp)
353     {
354         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
355         name = m_opaque_sp->GetName();
356     }
357 
358     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
359     if (log)
360         log->Printf ("SBThread(%p)::GetName () => %s", m_opaque_sp.get(), name ? name : "NULL");
361 
362     return name;
363 }
364 
365 const char *
366 SBThread::GetQueueName () const
367 {
368     const char *name = NULL;
369     if (m_opaque_sp)
370     {
371         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
372         name = m_opaque_sp->GetQueueName();
373     }
374 
375     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
376     if (log)
377         log->Printf ("SBThread(%p)::GetQueueName () => %s", m_opaque_sp.get(), name ? name : "NULL");
378 
379     return name;
380 }
381 
382 
383 void
384 SBThread::StepOver (lldb::RunMode stop_other_threads)
385 {
386     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
387 
388     if (log)
389         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", m_opaque_sp.get(),
390                      Thread::RunModeAsCString (stop_other_threads));
391 
392     if (m_opaque_sp)
393     {
394         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
395         bool abort_other_plans = true;
396         StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
397 
398         if (frame_sp)
399         {
400             if (frame_sp->HasDebugInformation ())
401             {
402                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
403                 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
404                                                           eStepTypeOver,
405                                                           sc.line_entry.range,
406                                                           sc,
407                                                           stop_other_threads,
408                                                           false);
409 
410             }
411             else
412             {
413                 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true,
414                                                                       abort_other_plans,
415                                                                       stop_other_threads);
416             }
417         }
418 
419         Process &process = m_opaque_sp->GetProcess();
420         // Why do we need to set the current thread by ID here???
421         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
422         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         }
430     }
431 }
432 
433 void
434 SBThread::StepInto (lldb::RunMode stop_other_threads)
435 {
436     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
437 
438     if (log)
439         log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", m_opaque_sp.get(),
440                      Thread::RunModeAsCString (stop_other_threads));
441 
442     if (m_opaque_sp)
443     {
444         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
445         bool abort_other_plans = true;
446 
447         StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
448 
449         if (frame_sp && frame_sp->HasDebugInformation ())
450         {
451             bool avoid_code_without_debug_info = true;
452             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
453             m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
454                                                       eStepTypeInto,
455                                                       sc.line_entry.range,
456                                                       sc,
457                                                       stop_other_threads,
458                                                       avoid_code_without_debug_info);
459         }
460         else
461         {
462             m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false,
463                                                                   abort_other_plans,
464                                                                   stop_other_threads);
465         }
466 
467         Process &process = m_opaque_sp->GetProcess();
468         // Why do we need to set the current thread by ID here???
469         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
470         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         }
478     }
479 }
480 
481 void
482 SBThread::StepOut ()
483 {
484     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
485 
486     if (log)
487         log->Printf ("SBThread(%p)::StepOut ()", m_opaque_sp.get());
488 
489     if (m_opaque_sp)
490     {
491         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
492         bool abort_other_plans = true;
493         bool stop_other_threads = true;
494 
495         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 }
515 
516 void
517 SBThread::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 
542         Process &process = m_opaque_sp->GetProcess();
543         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
544         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         }
552     }
553 }
554 
555 void
556 SBThread::StepInstruction (bool step_over)
557 {
558     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
559 
560     if (log)
561         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", m_opaque_sp.get(), step_over);
562 
563     if (m_opaque_sp)
564     {
565         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
566         m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
567         Process &process = m_opaque_sp->GetProcess();
568         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
569         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         }
577     }
578 }
579 
580 void
581 SBThread::RunToAddress (lldb::addr_t addr)
582 {
583     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
584 
585     if (log)
586         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", m_opaque_sp.get(), addr);
587 
588     if (m_opaque_sp)
589     {
590         bool abort_other_plans = true;
591         bool stop_other_threads = true;
592 
593         Address target_addr (NULL, addr);
594 
595         m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
596         Process &process = m_opaque_sp->GetProcess();
597         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
598         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         }
606     }
607 }
608 
609 SBError
610 SBThread::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 
742 bool
743 SBThread::Suspend()
744 {
745     if (m_opaque_sp)
746     {
747         m_opaque_sp->SetResumeState (eStateSuspended);
748         return true;
749     }
750     return false;
751 }
752 
753 bool
754 SBThread::Resume ()
755 {
756     if (m_opaque_sp)
757     {
758         m_opaque_sp->SetResumeState (eStateRunning);
759         return true;
760     }
761     return false;
762 }
763 
764 bool
765 SBThread::IsSuspended()
766 {
767     if (m_opaque_sp)
768         return m_opaque_sp->GetResumeState () == eStateSuspended;
769     return false;
770 }
771 
772 SBProcess
773 SBThread::GetProcess ()
774 {
775 
776     SBProcess process;
777     if (m_opaque_sp)
778     {
779         // Have to go up to the target so we can get a shared pointer to our process...
780         process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP());
781     }
782 
783     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
784     if (log)
785     {
786         SBStream frame_desc_strm;
787         process.GetDescription (frame_desc_strm);
788         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", m_opaque_sp.get(),
789                      process.get(), frame_desc_strm.GetData());
790     }
791 
792     return process;
793 }
794 
795 uint32_t
796 SBThread::GetNumFrames ()
797 {
798     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
799 
800     uint32_t num_frames = 0;
801     if (m_opaque_sp)
802     {
803         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
804         num_frames = m_opaque_sp->GetStackFrameCount();
805     }
806 
807     if (log)
808         log->Printf ("SBThread(%p)::GetNumFrames () => %u", m_opaque_sp.get(), num_frames);
809 
810     return num_frames;
811 }
812 
813 SBFrame
814 SBThread::GetFrameAtIndex (uint32_t idx)
815 {
816     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
817 
818     SBFrame sb_frame;
819     if (m_opaque_sp)
820     {
821         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
822         sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx));
823     }
824 
825     if (log)
826     {
827         SBStream frame_desc_strm;
828         sb_frame.GetDescription (frame_desc_strm);
829         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
830                      m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
831     }
832 
833     return sb_frame;
834 }
835 
836 lldb::SBFrame
837 SBThread::GetSelectedFrame ()
838 {
839     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
840 
841     SBFrame sb_frame;
842     if (m_opaque_sp)
843     {
844         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
845         sb_frame.SetFrame (m_opaque_sp->GetSelectedFrame ());
846     }
847 
848     if (log)
849     {
850         SBStream frame_desc_strm;
851         sb_frame.GetDescription (frame_desc_strm);
852         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
853                      m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
854     }
855 
856     return sb_frame;
857 }
858 
859 lldb::SBFrame
860 SBThread::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     {
867         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
868         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     {
878         SBStream frame_desc_strm;
879         sb_frame.GetDescription (frame_desc_strm);
880         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
881                      m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
882     }
883     return sb_frame;
884 }
885 
886 
887 bool
888 SBThread::operator == (const SBThread &rhs) const
889 {
890     return m_opaque_sp.get() == rhs.m_opaque_sp.get();
891 }
892 
893 bool
894 SBThread::operator != (const SBThread &rhs) const
895 {
896     return m_opaque_sp.get() != rhs.m_opaque_sp.get();
897 }
898 
899 lldb_private::Thread *
900 SBThread::get ()
901 {
902     return m_opaque_sp.get();
903 }
904 
905 const lldb_private::Thread *
906 SBThread::operator->() const
907 {
908     return m_opaque_sp.get();
909 }
910 
911 const lldb_private::Thread &
912 SBThread::operator*() const
913 {
914     return *m_opaque_sp;
915 }
916 
917 lldb_private::Thread *
918 SBThread::operator->()
919 {
920     return m_opaque_sp.get();
921 }
922 
923 lldb_private::Thread &
924 SBThread::operator*()
925 {
926     return *m_opaque_sp;
927 }
928 
929 bool
930 SBThread::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 }
942