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