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