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