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