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