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