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/SBDebugger.h"
35 #include "lldb/API/SBFrame.h"
36 #include "lldb/API/SBProcess.h"
37 #include "lldb/API/SBValue.h"
38 
39 using namespace lldb;
40 using namespace lldb_private;
41 
42 //----------------------------------------------------------------------
43 // Constructors
44 //----------------------------------------------------------------------
45 SBThread::SBThread () :
46     m_opaque_sp (new ExecutionContextRef())
47 {
48 }
49 
50 SBThread::SBThread (const ThreadSP& lldb_object_sp) :
51     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
52 {
53 }
54 
55 SBThread::SBThread (const SBThread &rhs) :
56     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
57 {
58 
59 }
60 
61 //----------------------------------------------------------------------
62 // Assignment operator
63 //----------------------------------------------------------------------
64 
65 const lldb::SBThread &
66 SBThread::operator = (const SBThread &rhs)
67 {
68     if (this != &rhs)
69         *m_opaque_sp = *rhs.m_opaque_sp;
70     return *this;
71 }
72 
73 //----------------------------------------------------------------------
74 // Destructor
75 //----------------------------------------------------------------------
76 SBThread::~SBThread()
77 {
78 }
79 
80 bool
81 SBThread::IsValid() const
82 {
83     return m_opaque_sp->GetThreadSP().get() != NULL;
84 }
85 
86 void
87 SBThread::Clear ()
88 {
89     m_opaque_sp->Clear();
90 }
91 
92 
93 StopReason
94 SBThread::GetStopReason()
95 {
96     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
97 
98     StopReason reason = eStopReasonInvalid;
99     ExecutionContext exe_ctx (m_opaque_sp.get());
100     if (exe_ctx.HasThreadScope())
101     {
102         Process::StopLocker stop_locker;
103         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
104         {
105             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
106             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
107             if (stop_info_sp)
108                 reason =  stop_info_sp->GetStopReason();
109         }
110         else
111         {
112             if (log)
113                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
114         }
115     }
116 
117     if (log)
118         log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
119                      Thread::StopReasonAsCString (reason));
120 
121     return reason;
122 }
123 
124 size_t
125 SBThread::GetStopReasonDataCount ()
126 {
127     ExecutionContext exe_ctx (m_opaque_sp.get());
128     if (exe_ctx.HasThreadScope())
129     {
130         Process::StopLocker stop_locker;
131         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
132         {
133             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
134             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
135             if (stop_info_sp)
136             {
137                 StopReason reason = stop_info_sp->GetStopReason();
138                 switch (reason)
139                 {
140                 case eStopReasonInvalid:
141                 case eStopReasonNone:
142                 case eStopReasonTrace:
143                 case eStopReasonPlanComplete:
144                     // There is no data for these stop reasons.
145                     return 0;
146 
147                 case eStopReasonBreakpoint:
148                     {
149                         break_id_t site_id = stop_info_sp->GetValue();
150                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
151                         if (bp_site_sp)
152                             return bp_site_sp->GetNumberOfOwners () * 2;
153                         else
154                             return 0; // Breakpoint must have cleared itself...
155                     }
156                     break;
157 
158                 case eStopReasonWatchpoint:
159                     return 1;
160 
161                 case eStopReasonSignal:
162                     return 1;
163 
164                 case eStopReasonException:
165                     return 1;
166                 }
167             }
168         }
169         else
170         {
171             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
172             if (log)
173                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
174         }
175     }
176     return 0;
177 }
178 
179 uint64_t
180 SBThread::GetStopReasonDataAtIndex (uint32_t idx)
181 {
182     ExecutionContext exe_ctx (m_opaque_sp.get());
183     if (exe_ctx.HasThreadScope())
184     {
185         Process::StopLocker stop_locker;
186         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
187         {
188 
189             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
190             Thread *thread = exe_ctx.GetThreadPtr();
191             StopInfoSP stop_info_sp = thread->GetStopInfo ();
192             if (stop_info_sp)
193             {
194                 StopReason reason = stop_info_sp->GetStopReason();
195                 switch (reason)
196                 {
197                 case eStopReasonInvalid:
198                 case eStopReasonNone:
199                 case eStopReasonTrace:
200                 case eStopReasonPlanComplete:
201                     // There is no data for these stop reasons.
202                     return 0;
203 
204                 case eStopReasonBreakpoint:
205                     {
206                         break_id_t site_id = stop_info_sp->GetValue();
207                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
208                         if (bp_site_sp)
209                         {
210                             uint32_t bp_index = idx / 2;
211                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
212                             if (bp_loc_sp)
213                             {
214                                 if (bp_index & 1)
215                                 {
216                                     // Odd idx, return the breakpoint location ID
217                                     return bp_loc_sp->GetID();
218                                 }
219                                 else
220                                 {
221                                     // Even idx, return the breakpoint ID
222                                     return bp_loc_sp->GetBreakpoint().GetID();
223                                 }
224                             }
225                         }
226                         return LLDB_INVALID_BREAK_ID;
227                     }
228                     break;
229 
230                 case eStopReasonWatchpoint:
231                     return stop_info_sp->GetValue();
232 
233                 case eStopReasonSignal:
234                     return stop_info_sp->GetValue();
235 
236                 case eStopReasonException:
237                     return stop_info_sp->GetValue();
238                 }
239             }
240         }
241         else
242         {
243             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
244             if (log)
245                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
246         }
247     }
248     return 0;
249 }
250 
251 size_t
252 SBThread::GetStopDescription (char *dst, size_t dst_len)
253 {
254     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
255 
256     ExecutionContext exe_ctx (m_opaque_sp.get());
257     if (exe_ctx.HasThreadScope())
258     {
259         Process::StopLocker stop_locker;
260         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
261         {
262 
263             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
264             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
265             if (stop_info_sp)
266             {
267                 const char *stop_desc = stop_info_sp->GetDescription();
268                 if (stop_desc)
269                 {
270                     if (log)
271                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
272                                      exe_ctx.GetThreadPtr(), stop_desc);
273                     if (dst)
274                         return ::snprintf (dst, dst_len, "%s", stop_desc);
275                     else
276                     {
277                         // NULL dst passed in, return the length needed to contain the description
278                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
279                     }
280                 }
281                 else
282                 {
283                     size_t stop_desc_len = 0;
284                     switch (stop_info_sp->GetStopReason())
285                     {
286                     case eStopReasonTrace:
287                     case eStopReasonPlanComplete:
288                         {
289                             static char trace_desc[] = "step";
290                             stop_desc = trace_desc;
291                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
292                         }
293                         break;
294 
295                     case eStopReasonBreakpoint:
296                         {
297                             static char bp_desc[] = "breakpoint hit";
298                             stop_desc = bp_desc;
299                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
300                         }
301                         break;
302 
303                     case eStopReasonWatchpoint:
304                         {
305                             static char wp_desc[] = "watchpoint hit";
306                             stop_desc = wp_desc;
307                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
308                         }
309                         break;
310 
311                     case eStopReasonSignal:
312                         {
313                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
314                             if (stop_desc == NULL || stop_desc[0] == '\0')
315                             {
316                                 static char signal_desc[] = "signal";
317                                 stop_desc = signal_desc;
318                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
319                             }
320                         }
321                         break;
322 
323                     case eStopReasonException:
324                         {
325                             char exc_desc[] = "exception";
326                             stop_desc = exc_desc;
327                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
328                         }
329                         break;
330 
331                     default:
332                         break;
333                     }
334 
335                     if (stop_desc && stop_desc[0])
336                     {
337                         if (log)
338                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
339                                          exe_ctx.GetThreadPtr(), stop_desc);
340 
341                         if (dst)
342                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
343 
344                         if (stop_desc_len == 0)
345                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
346 
347                         return stop_desc_len;
348                     }
349                 }
350             }
351         }
352         else
353         {
354             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
355             if (log)
356                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
357         }
358     }
359     if (dst)
360         *dst = 0;
361     return 0;
362 }
363 
364 SBValue
365 SBThread::GetStopReturnValue ()
366 {
367     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
368     ValueObjectSP return_valobj_sp;
369     ExecutionContext exe_ctx (m_opaque_sp.get());
370     if (exe_ctx.HasThreadScope())
371     {
372         Process::StopLocker stop_locker;
373         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
374         {
375             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
376             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
377             if (stop_info_sp)
378             {
379                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
380             }
381         }
382         else
383         {
384             if (log)
385                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
386         }
387     }
388 
389     if (log)
390         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
391                                                                   return_valobj_sp.get()
392                                                                       ? return_valobj_sp->GetValueAsCString()
393                                                                         : "<no return value>");
394 
395     return SBValue (return_valobj_sp);
396 }
397 
398 void
399 SBThread::SetThread (const ThreadSP& lldb_object_sp)
400 {
401     m_opaque_sp->SetThreadSP (lldb_object_sp);
402 }
403 
404 
405 lldb::tid_t
406 SBThread::GetThreadID () const
407 {
408     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
409     if (thread_sp)
410         return thread_sp->GetID();
411     return LLDB_INVALID_THREAD_ID;
412 }
413 
414 uint32_t
415 SBThread::GetIndexID () const
416 {
417     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
418     if (thread_sp)
419         return thread_sp->GetIndexID();
420     return LLDB_INVALID_INDEX32;
421 }
422 
423 const char *
424 SBThread::GetName () const
425 {
426     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
427     const char *name = NULL;
428     ExecutionContext exe_ctx (m_opaque_sp.get());
429     if (exe_ctx.HasThreadScope())
430     {
431         Process::StopLocker stop_locker;
432         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
433         {
434             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
435             name = exe_ctx.GetThreadPtr()->GetName();
436         }
437         else
438         {
439             if (log)
440                 log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
441         }
442     }
443 
444     if (log)
445         log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
446 
447     return name;
448 }
449 
450 const char *
451 SBThread::GetQueueName () const
452 {
453     const char *name = NULL;
454     ExecutionContext exe_ctx (m_opaque_sp.get());
455     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
456     if (exe_ctx.HasThreadScope())
457     {
458         Process::StopLocker stop_locker;
459         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
460         {
461             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
462             name = exe_ctx.GetThreadPtr()->GetQueueName();
463         }
464         else
465         {
466             if (log)
467                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
468         }
469     }
470 
471     if (log)
472         log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
473 
474     return name;
475 }
476 
477 
478 void
479 SBThread::StepOver (lldb::RunMode stop_other_threads)
480 {
481     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
482 
483     ExecutionContext exe_ctx (m_opaque_sp.get());
484 
485     if (log)
486         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
487                      Thread::RunModeAsCString (stop_other_threads));
488 
489     if (exe_ctx.HasThreadScope())
490     {
491         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
492         Thread *thread = exe_ctx.GetThreadPtr();
493         bool abort_other_plans = true;
494         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
495 
496         if (frame_sp)
497         {
498             if (frame_sp->HasDebugInformation ())
499             {
500                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
501                 thread->QueueThreadPlanForStepRange (abort_other_plans,
502                                                      eStepTypeOver,
503                                                      sc.line_entry.range,
504                                                      sc,
505                                                      stop_other_threads,
506                                                      false);
507 
508             }
509             else
510             {
511                 thread->QueueThreadPlanForStepSingleInstruction (true,
512                                                                  abort_other_plans,
513                                                                  stop_other_threads);
514             }
515         }
516 
517         Process *process = exe_ctx.GetProcessPtr();
518         // Why do we need to set the current thread by ID here???
519         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
520         Error error (process->Resume());
521         if (error.Success())
522         {
523             // If we are doing synchronous mode, then wait for the
524             // process to stop yet again!
525             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
526                 process->WaitForProcessToStop (NULL);
527         }
528     }
529 }
530 
531 void
532 SBThread::StepInto (lldb::RunMode stop_other_threads)
533 {
534     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
535 
536     ExecutionContext exe_ctx (m_opaque_sp.get());
537 
538     if (log)
539         log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
540                      Thread::RunModeAsCString (stop_other_threads));
541     if (exe_ctx.HasThreadScope())
542     {
543         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
544         bool abort_other_plans = true;
545 
546         Thread *thread = exe_ctx.GetThreadPtr();
547         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
548 
549         if (frame_sp && frame_sp->HasDebugInformation ())
550         {
551             bool avoid_code_without_debug_info = true;
552             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
553             thread->QueueThreadPlanForStepRange (abort_other_plans,
554                                                  eStepTypeInto,
555                                                  sc.line_entry.range,
556                                                  sc,
557                                                  stop_other_threads,
558                                                  avoid_code_without_debug_info);
559         }
560         else
561         {
562             thread->QueueThreadPlanForStepSingleInstruction (false,
563                                                              abort_other_plans,
564                                                              stop_other_threads);
565         }
566 
567         Process *process = exe_ctx.GetProcessPtr();
568         // Why do we need to set the current thread by ID here???
569         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
570         Error error (process->Resume());
571         if (error.Success())
572         {
573             // If we are doing synchronous mode, then wait for the
574             // process to stop yet again!
575             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
576                 process->WaitForProcessToStop (NULL);
577         }
578     }
579 }
580 
581 void
582 SBThread::StepOut ()
583 {
584     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
585 
586     ExecutionContext exe_ctx (m_opaque_sp.get());
587 
588     if (log)
589         log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
590 
591     if (exe_ctx.HasThreadScope())
592     {
593         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
594         bool abort_other_plans = true;
595         bool stop_other_threads = true;
596 
597         Thread *thread = exe_ctx.GetThreadPtr();
598 
599         thread->QueueThreadPlanForStepOut (abort_other_plans,
600                                               NULL,
601                                               false,
602                                               stop_other_threads,
603                                               eVoteYes,
604                                               eVoteNoOpinion,
605                                               0);
606 
607         Process *process = exe_ctx.GetProcessPtr();
608         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
609         Error error (process->Resume());
610         if (error.Success())
611         {
612             // If we are doing synchronous mode, then wait for the
613             // process to stop yet again!
614             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
615                 process->WaitForProcessToStop (NULL);
616         }
617     }
618 }
619 
620 void
621 SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
622 {
623     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
624 
625     ExecutionContext exe_ctx (m_opaque_sp.get());
626     StackFrameSP frame_sp (sb_frame.GetFrameSP());
627     if (log)
628     {
629         SBStream frame_desc_strm;
630         sb_frame.GetDescription (frame_desc_strm);
631         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
632     }
633 
634     if (exe_ctx.HasThreadScope())
635     {
636         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
637         bool abort_other_plans = true;
638         bool stop_other_threads = true;
639         Thread *thread = exe_ctx.GetThreadPtr();
640 
641         thread->QueueThreadPlanForStepOut (abort_other_plans,
642                                               NULL,
643                                               false,
644                                               stop_other_threads,
645                                               eVoteYes,
646                                               eVoteNoOpinion,
647                                               frame_sp->GetFrameIndex());
648 
649         Process *process = exe_ctx.GetProcessPtr();
650         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
651         Error error (process->Resume());
652         if (error.Success())
653         {
654             // If we are doing synchronous mode, then wait for the
655             // process to stop yet again!
656             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
657                 process->WaitForProcessToStop (NULL);
658         }
659     }
660 }
661 
662 void
663 SBThread::StepInstruction (bool step_over)
664 {
665     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
666 
667     ExecutionContext exe_ctx (m_opaque_sp.get());
668 
669 
670     if (log)
671         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
672 
673     if (exe_ctx.HasThreadScope())
674     {
675         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
676         Thread *thread = exe_ctx.GetThreadPtr();
677         Process *process = exe_ctx.GetProcessPtr();
678         thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
679         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
680         Error error (process->Resume());
681         if (error.Success())
682         {
683             // If we are doing synchronous mode, then wait for the
684             // process to stop yet again!
685             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
686                 process->WaitForProcessToStop (NULL);
687         }
688     }
689 }
690 
691 void
692 SBThread::RunToAddress (lldb::addr_t addr)
693 {
694     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
695 
696     ExecutionContext exe_ctx (m_opaque_sp.get());
697 
698     if (log)
699         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr);
700 
701     if (exe_ctx.HasThreadScope())
702     {
703         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
704         bool abort_other_plans = true;
705         bool stop_other_threads = true;
706 
707         Address target_addr (addr);
708 
709         Thread *thread = exe_ctx.GetThreadPtr();
710         Process *process = exe_ctx.GetProcessPtr();
711 
712         thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
713         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
714         Error error (process->Resume());
715         if (error.Success())
716         {
717             // If we are doing synchronous mode, then wait for the
718             // process to stop yet again!
719             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
720                 process->WaitForProcessToStop (NULL);
721         }
722     }
723 }
724 
725 SBError
726 SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
727                          lldb::SBFileSpec &sb_file_spec,
728                          uint32_t line)
729 {
730     SBError sb_error;
731     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
732     char path[PATH_MAX];
733 
734     ExecutionContext exe_ctx (m_opaque_sp.get());
735     StackFrameSP frame_sp (sb_frame.GetFrameSP());
736 
737     if (log)
738     {
739         SBStream frame_desc_strm;
740         sb_frame.GetDescription (frame_desc_strm);
741         sb_file_spec->GetPath (path, sizeof(path));
742         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
743                      exe_ctx.GetThreadPtr(),
744                      frame_sp.get(),
745                      frame_desc_strm.GetData(),
746                      path, line);
747     }
748 
749     if (exe_ctx.HasThreadScope())
750     {
751         Target *target = exe_ctx.GetTargetPtr();
752         Mutex::Locker api_locker (target->GetAPIMutex());
753         Thread *thread = exe_ctx.GetThreadPtr();
754 
755         if (line == 0)
756         {
757             sb_error.SetErrorString("invalid line argument");
758             return sb_error;
759         }
760 
761         StackFrameSP frame_sp;
762         if (!frame_sp)
763         {
764             frame_sp = thread->GetSelectedFrame ();
765             if (!frame_sp)
766                 frame_sp = thread->GetStackFrameAtIndex (0);
767         }
768 
769         SymbolContext frame_sc;
770         if (!frame_sp)
771         {
772             sb_error.SetErrorString("no valid frames in thread to step");
773             return sb_error;
774         }
775 
776         // If we have a frame, get its line
777         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
778                                                eSymbolContextFunction  |
779                                                eSymbolContextLineEntry |
780                                                eSymbolContextSymbol    );
781 
782         if (frame_sc.comp_unit == NULL)
783         {
784             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
785             return sb_error;
786         }
787 
788         FileSpec step_file_spec;
789         if (sb_file_spec.IsValid())
790         {
791             // The file spec passed in was valid, so use it
792             step_file_spec = sb_file_spec.ref();
793         }
794         else
795         {
796             if (frame_sc.line_entry.IsValid())
797                 step_file_spec = frame_sc.line_entry.file;
798             else
799             {
800                 sb_error.SetErrorString("invalid file argument or no file for frame");
801                 return sb_error;
802             }
803         }
804 
805         // Grab the current function, then we will make sure the "until" address is
806         // within the function.  We discard addresses that are out of the current
807         // function, and then if there are no addresses remaining, give an appropriate
808         // error message.
809 
810         bool all_in_function = true;
811         AddressRange fun_range = frame_sc.function->GetAddressRange();
812 
813         std::vector<addr_t> step_over_until_addrs;
814         const bool abort_other_plans = true;
815         const bool stop_other_threads = true;
816         const bool check_inlines = true;
817         const bool exact = false;
818 
819         SymbolContextList sc_list;
820         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
821                                                                                line,
822                                                                                check_inlines,
823                                                                                exact,
824                                                                                eSymbolContextLineEntry,
825                                                                                sc_list);
826         if (num_matches > 0)
827         {
828             SymbolContext sc;
829             for (uint32_t i=0; i<num_matches; ++i)
830             {
831                 if (sc_list.GetContextAtIndex(i, sc))
832                 {
833                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
834                     if (step_addr != LLDB_INVALID_ADDRESS)
835                     {
836                         if (fun_range.ContainsLoadAddress(step_addr, target))
837                             step_over_until_addrs.push_back(step_addr);
838                         else
839                             all_in_function = false;
840                     }
841                 }
842             }
843         }
844 
845         if (step_over_until_addrs.empty())
846         {
847             if (all_in_function)
848             {
849                 step_file_spec.GetPath (path, sizeof(path));
850                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
851             }
852             else
853                 sb_error.SetErrorString ("step until target not in current function");
854         }
855         else
856         {
857             thread->QueueThreadPlanForStepUntil (abort_other_plans,
858                                                  &step_over_until_addrs[0],
859                                                  step_over_until_addrs.size(),
860                                                  stop_other_threads,
861                                                  frame_sp->GetFrameIndex());
862 
863             Process *process = exe_ctx.GetProcessPtr();
864 
865             process->GetThreadList().SetSelectedThreadByID (thread->GetID());
866             sb_error.ref() = process->Resume();
867             if (sb_error->Success())
868             {
869                 // If we are doing synchronous mode, then wait for the
870                 // process to stop yet again!
871                 if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
872                     process->WaitForProcessToStop (NULL);
873             }
874         }
875     }
876     else
877     {
878         sb_error.SetErrorString("this SBThread object is invalid");
879     }
880     return sb_error;
881 }
882 
883 
884 bool
885 SBThread::Suspend()
886 {
887     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
888     ExecutionContext exe_ctx (m_opaque_sp.get());
889     bool result = false;
890     if (exe_ctx.HasThreadScope())
891     {
892         Process::StopLocker stop_locker;
893         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
894         {
895             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
896             result = true;
897         }
898         else
899         {
900             if (log)
901                 log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
902         }
903     }
904     if (log)
905         log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
906     return result;
907 }
908 
909 bool
910 SBThread::Resume ()
911 {
912     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
913     ExecutionContext exe_ctx (m_opaque_sp.get());
914     bool result = false;
915     if (exe_ctx.HasThreadScope())
916     {
917         Process::StopLocker stop_locker;
918         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
919         {
920             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
921             result = true;
922         }
923         else
924         {
925             if (log)
926                 log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
927         }
928     }
929     if (log)
930         log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
931     return result;
932 }
933 
934 bool
935 SBThread::IsSuspended()
936 {
937     ExecutionContext exe_ctx (m_opaque_sp.get());
938     if (exe_ctx.HasThreadScope())
939         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
940     return false;
941 }
942 
943 SBProcess
944 SBThread::GetProcess ()
945 {
946 
947     SBProcess sb_process;
948     ProcessSP process_sp;
949     ExecutionContext exe_ctx (m_opaque_sp.get());
950     if (exe_ctx.HasThreadScope())
951     {
952         // Have to go up to the target so we can get a shared pointer to our process...
953         sb_process.SetSP (exe_ctx.GetProcessSP());
954     }
955 
956     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
957     if (log)
958     {
959         SBStream frame_desc_strm;
960         sb_process.GetDescription (frame_desc_strm);
961         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
962                      process_sp.get(), frame_desc_strm.GetData());
963     }
964 
965     return sb_process;
966 }
967 
968 uint32_t
969 SBThread::GetNumFrames ()
970 {
971     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
972 
973     uint32_t num_frames = 0;
974     ExecutionContext exe_ctx (m_opaque_sp.get());
975     if (exe_ctx.HasThreadScope())
976     {
977         Process::StopLocker stop_locker;
978         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
979         {
980             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
981             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
982         }
983         else
984         {
985             if (log)
986                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
987         }
988     }
989 
990     if (log)
991         log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
992 
993     return num_frames;
994 }
995 
996 SBFrame
997 SBThread::GetFrameAtIndex (uint32_t idx)
998 {
999     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1000 
1001     SBFrame sb_frame;
1002     StackFrameSP frame_sp;
1003     ExecutionContext exe_ctx (m_opaque_sp.get());
1004     if (exe_ctx.HasThreadScope())
1005     {
1006         Process::StopLocker stop_locker;
1007         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1008         {
1009             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
1010             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1011             sb_frame.SetFrameSP (frame_sp);
1012         }
1013         else
1014         {
1015             if (log)
1016                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1017         }
1018     }
1019 
1020     if (log)
1021     {
1022         SBStream frame_desc_strm;
1023         sb_frame.GetDescription (frame_desc_strm);
1024         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1025                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1026     }
1027 
1028     return sb_frame;
1029 }
1030 
1031 lldb::SBFrame
1032 SBThread::GetSelectedFrame ()
1033 {
1034     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1035 
1036     SBFrame sb_frame;
1037     StackFrameSP frame_sp;
1038     ExecutionContext exe_ctx (m_opaque_sp.get());
1039     if (exe_ctx.HasThreadScope())
1040     {
1041         Process::StopLocker stop_locker;
1042         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1043         {
1044             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
1045             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1046             sb_frame.SetFrameSP (frame_sp);
1047         }
1048         else
1049         {
1050             if (log)
1051                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1052         }
1053     }
1054 
1055     if (log)
1056     {
1057         SBStream frame_desc_strm;
1058         sb_frame.GetDescription (frame_desc_strm);
1059         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1060                      exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1061     }
1062 
1063     return sb_frame;
1064 }
1065 
1066 lldb::SBFrame
1067 SBThread::SetSelectedFrame (uint32_t idx)
1068 {
1069     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1070 
1071     SBFrame sb_frame;
1072     StackFrameSP frame_sp;
1073     ExecutionContext exe_ctx (m_opaque_sp.get());
1074     if (exe_ctx.HasThreadScope())
1075     {
1076         Process::StopLocker stop_locker;
1077         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1078         {
1079             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
1080             Thread *thread = exe_ctx.GetThreadPtr();
1081             frame_sp = thread->GetStackFrameAtIndex (idx);
1082             if (frame_sp)
1083             {
1084                 thread->SetSelectedFrame (frame_sp.get());
1085                 sb_frame.SetFrameSP (frame_sp);
1086             }
1087         }
1088         else
1089         {
1090             if (log)
1091                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1092         }
1093     }
1094 
1095     if (log)
1096     {
1097         SBStream frame_desc_strm;
1098         sb_frame.GetDescription (frame_desc_strm);
1099         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1100                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1101     }
1102     return sb_frame;
1103 }
1104 
1105 
1106 bool
1107 SBThread::operator == (const SBThread &rhs) const
1108 {
1109     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
1110 }
1111 
1112 bool
1113 SBThread::operator != (const SBThread &rhs) const
1114 {
1115     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
1116 }
1117 
1118 bool
1119 SBThread::GetDescription (SBStream &description) const
1120 {
1121     Stream &strm = description.ref();
1122 
1123     ExecutionContext exe_ctx (m_opaque_sp.get());
1124     if (exe_ctx.HasThreadScope())
1125     {
1126         strm.Printf("SBThread: tid = 0x%4.4llx", exe_ctx.GetThreadPtr()->GetID());
1127     }
1128     else
1129         strm.PutCString ("No value");
1130 
1131     return true;
1132 }
1133