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 // DONT THINK THIS IS NECESSARY: #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;
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         // Grab the current function, then we will make sure the "until" address is
687         // within the function.  We discard addresses that are out of the current
688         // function, and then if there are no addresses remaining, give an appropriate
689         // error message.
690 
691         bool all_in_function = true;
692         AddressRange fun_range = frame_sc.function->GetAddressRange();
693 
694         std::vector<addr_t> step_over_until_addrs;
695         const bool abort_other_plans = true;
696         const bool stop_other_threads = true;
697         const bool check_inlines = true;
698         const bool exact = false;
699         Target *target = &m_opaque_sp->GetProcess().GetTarget();
700 
701         SymbolContextList sc_list;
702         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
703                                                                                line,
704                                                                                check_inlines,
705                                                                                exact,
706                                                                                eSymbolContextLineEntry,
707                                                                                sc_list);
708         if (num_matches > 0)
709         {
710             SymbolContext sc;
711             for (uint32_t i=0; i<num_matches; ++i)
712             {
713                 if (sc_list.GetContextAtIndex(i, sc))
714                 {
715                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
716                     if (step_addr != LLDB_INVALID_ADDRESS)
717                     {
718                         if (fun_range.ContainsLoadAddress(step_addr, target))
719                             step_over_until_addrs.push_back(step_addr);
720                         else
721                             all_in_function = false;
722                     }
723                 }
724             }
725         }
726 
727         if (step_over_until_addrs.empty())
728         {
729             if (all_in_function)
730             {
731                 step_file_spec.GetPath (path, sizeof(path));
732                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
733             }
734             else
735                 sb_error.SetErrorString ("Step until target not in current function.\n");
736         }
737         else
738         {
739             m_opaque_sp->QueueThreadPlanForStepUntil (abort_other_plans,
740                                                       &step_over_until_addrs[0],
741                                                       step_over_until_addrs.size(),
742                                                       stop_other_threads,
743                                                       frame_sp->GetFrameIndex());
744 
745             m_opaque_sp->GetProcess().GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
746             sb_error.ref() = m_opaque_sp->GetProcess().Resume();
747             if (sb_error->Success())
748             {
749                 // If we are doing synchronous mode, then wait for the
750                 // process to stop yet again!
751                 if (m_opaque_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false)
752                     m_opaque_sp->GetProcess().WaitForProcessToStop (NULL);
753             }
754         }
755     }
756     else
757     {
758         sb_error.SetErrorString("this SBThread object is invalid");
759     }
760     return sb_error;
761 }
762 
763 
764 bool
765 SBThread::Suspend()
766 {
767     if (m_opaque_sp)
768     {
769         m_opaque_sp->SetResumeState (eStateSuspended);
770         return true;
771     }
772     return false;
773 }
774 
775 bool
776 SBThread::Resume ()
777 {
778     if (m_opaque_sp)
779     {
780         m_opaque_sp->SetResumeState (eStateRunning);
781         return true;
782     }
783     return false;
784 }
785 
786 bool
787 SBThread::IsSuspended()
788 {
789     if (m_opaque_sp)
790         return m_opaque_sp->GetResumeState () == eStateSuspended;
791     return false;
792 }
793 
794 SBProcess
795 SBThread::GetProcess ()
796 {
797 
798     SBProcess process;
799     if (m_opaque_sp)
800     {
801         // Have to go up to the target so we can get a shared pointer to our process...
802         process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP());
803     }
804 
805     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
806     if (log)
807     {
808         SBStream frame_desc_strm;
809         process.GetDescription (frame_desc_strm);
810         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", m_opaque_sp.get(),
811                      process.get(), frame_desc_strm.GetData());
812     }
813 
814     return process;
815 }
816 
817 uint32_t
818 SBThread::GetNumFrames ()
819 {
820     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
821 
822     uint32_t num_frames = 0;
823     if (m_opaque_sp)
824     {
825         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
826         num_frames = m_opaque_sp->GetStackFrameCount();
827     }
828 
829     if (log)
830         log->Printf ("SBThread(%p)::GetNumFrames () => %u", m_opaque_sp.get(), num_frames);
831 
832     return num_frames;
833 }
834 
835 SBFrame
836 SBThread::GetFrameAtIndex (uint32_t idx)
837 {
838     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
839 
840     SBFrame sb_frame;
841     if (m_opaque_sp)
842     {
843         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
844         sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx));
845     }
846 
847     if (log)
848     {
849         SBStream frame_desc_strm;
850         sb_frame.GetDescription (frame_desc_strm);
851         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
852                      m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
853     }
854 
855     return sb_frame;
856 }
857 
858 lldb::SBFrame
859 SBThread::GetSelectedFrame ()
860 {
861     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
862 
863     SBFrame sb_frame;
864     if (m_opaque_sp)
865     {
866         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
867         sb_frame.SetFrame (m_opaque_sp->GetSelectedFrame ());
868     }
869 
870     if (log)
871     {
872         SBStream frame_desc_strm;
873         sb_frame.GetDescription (frame_desc_strm);
874         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
875                      m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
876     }
877 
878     return sb_frame;
879 }
880 
881 lldb::SBFrame
882 SBThread::SetSelectedFrame (uint32_t idx)
883 {
884     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
885 
886     SBFrame sb_frame;
887     if (m_opaque_sp)
888     {
889         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
890         lldb::StackFrameSP frame_sp (m_opaque_sp->GetStackFrameAtIndex (idx));
891         if (frame_sp)
892         {
893             m_opaque_sp->SetSelectedFrame (frame_sp.get());
894             sb_frame.SetFrame (frame_sp);
895         }
896     }
897 
898     if (log)
899     {
900         SBStream frame_desc_strm;
901         sb_frame.GetDescription (frame_desc_strm);
902         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
903                      m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
904     }
905     return sb_frame;
906 }
907 
908 
909 bool
910 SBThread::operator == (const SBThread &rhs) const
911 {
912     return m_opaque_sp.get() == rhs.m_opaque_sp.get();
913 }
914 
915 bool
916 SBThread::operator != (const SBThread &rhs) const
917 {
918     return m_opaque_sp.get() != rhs.m_opaque_sp.get();
919 }
920 
921 lldb_private::Thread *
922 SBThread::get ()
923 {
924     return m_opaque_sp.get();
925 }
926 
927 const lldb_private::Thread *
928 SBThread::operator->() const
929 {
930     return m_opaque_sp.get();
931 }
932 
933 const lldb_private::Thread &
934 SBThread::operator*() const
935 {
936     return *m_opaque_sp;
937 }
938 
939 lldb_private::Thread *
940 SBThread::operator->()
941 {
942     return m_opaque_sp.get();
943 }
944 
945 lldb_private::Thread &
946 SBThread::operator*()
947 {
948     return *m_opaque_sp;
949 }
950 
951 bool
952 SBThread::GetDescription (SBStream &description) const
953 {
954     if (m_opaque_sp)
955     {
956         StreamString strm;
957         description.Printf("SBThread: tid = 0x%4.4x", m_opaque_sp->GetID());
958     }
959     else
960         description.Printf ("No value");
961 
962     return true;
963 }
964