Home | History | Annotate | Download | only in API
      1 //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/lldb-python.h"
     11 
     12 #include "lldb/API/SBThread.h"
     13 
     14 #include "lldb/API/SBSymbolContext.h"
     15 #include "lldb/API/SBFileSpec.h"
     16 #include "lldb/API/SBStream.h"
     17 #include "lldb/Breakpoint/BreakpointLocation.h"
     18 #include "lldb/Core/Debugger.h"
     19 #include "lldb/Core/State.h"
     20 #include "lldb/Core/Stream.h"
     21 #include "lldb/Core/StreamFile.h"
     22 #include "lldb/Interpreter/CommandInterpreter.h"
     23 #include "lldb/Target/Thread.h"
     24 #include "lldb/Target/Process.h"
     25 #include "lldb/Symbol/SymbolContext.h"
     26 #include "lldb/Symbol/CompileUnit.h"
     27 #include "lldb/Target/StopInfo.h"
     28 #include "lldb/Target/Target.h"
     29 #include "lldb/Target/ThreadPlan.h"
     30 #include "lldb/Target/ThreadPlanStepInstruction.h"
     31 #include "lldb/Target/ThreadPlanStepOut.h"
     32 #include "lldb/Target/ThreadPlanStepRange.h"
     33 #include "lldb/Target/ThreadPlanStepInRange.h"
     34 
     35 
     36 #include "lldb/API/SBAddress.h"
     37 #include "lldb/API/SBDebugger.h"
     38 #include "lldb/API/SBEvent.h"
     39 #include "lldb/API/SBFrame.h"
     40 #include "lldb/API/SBProcess.h"
     41 #include "lldb/API/SBValue.h"
     42 
     43 using namespace lldb;
     44 using namespace lldb_private;
     45 
     46 const char *
     47 SBThread::GetBroadcasterClassName ()
     48 {
     49     return Thread::GetStaticBroadcasterClass().AsCString();
     50 }
     51 
     52 //----------------------------------------------------------------------
     53 // Constructors
     54 //----------------------------------------------------------------------
     55 SBThread::SBThread () :
     56     m_opaque_sp (new ExecutionContextRef())
     57 {
     58 }
     59 
     60 SBThread::SBThread (const ThreadSP& lldb_object_sp) :
     61     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
     62 {
     63 }
     64 
     65 SBThread::SBThread (const SBThread &rhs) :
     66     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
     67 {
     68 
     69 }
     70 
     71 //----------------------------------------------------------------------
     72 // Assignment operator
     73 //----------------------------------------------------------------------
     74 
     75 const lldb::SBThread &
     76 SBThread::operator = (const SBThread &rhs)
     77 {
     78     if (this != &rhs)
     79         *m_opaque_sp = *rhs.m_opaque_sp;
     80     return *this;
     81 }
     82 
     83 //----------------------------------------------------------------------
     84 // Destructor
     85 //----------------------------------------------------------------------
     86 SBThread::~SBThread()
     87 {
     88 }
     89 
     90 bool
     91 SBThread::IsValid() const
     92 {
     93     return m_opaque_sp->GetThreadSP().get() != NULL;
     94 }
     95 
     96 void
     97 SBThread::Clear ()
     98 {
     99     m_opaque_sp->Clear();
    100 }
    101 
    102 
    103 StopReason
    104 SBThread::GetStopReason()
    105 {
    106     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    107 
    108     StopReason reason = eStopReasonInvalid;
    109     Mutex::Locker api_locker;
    110     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
    111 
    112     if (exe_ctx.HasThreadScope())
    113     {
    114         Process::StopLocker stop_locker;
    115         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
    116         {
    117             return exe_ctx.GetThreadPtr()->GetStopReason();
    118         }
    119         else
    120         {
    121             if (log)
    122                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
    123         }
    124     }
    125 
    126     if (log)
    127         log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
    128                      Thread::StopReasonAsCString (reason));
    129 
    130     return reason;
    131 }
    132 
    133 size_t
    134 SBThread::GetStopReasonDataCount ()
    135 {
    136     Mutex::Locker api_locker;
    137     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
    138 
    139     if (exe_ctx.HasThreadScope())
    140     {
    141         Process::StopLocker stop_locker;
    142         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
    143         {
    144             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
    145             if (stop_info_sp)
    146             {
    147                 StopReason reason = stop_info_sp->GetStopReason();
    148                 switch (reason)
    149                 {
    150                 case eStopReasonInvalid:
    151                 case eStopReasonNone:
    152                 case eStopReasonTrace:
    153                 case eStopReasonExec:
    154                 case eStopReasonPlanComplete:
    155                 case eStopReasonThreadExiting:
    156                     // There is no data for these stop reasons.
    157                     return 0;
    158 
    159                 case eStopReasonBreakpoint:
    160                     {
    161                         break_id_t site_id = stop_info_sp->GetValue();
    162                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
    163                         if (bp_site_sp)
    164                             return bp_site_sp->GetNumberOfOwners () * 2;
    165                         else
    166                             return 0; // Breakpoint must have cleared itself...
    167                     }
    168                     break;
    169 
    170                 case eStopReasonWatchpoint:
    171                     return 1;
    172 
    173                 case eStopReasonSignal:
    174                     return 1;
    175 
    176                 case eStopReasonException:
    177                     return 1;
    178                 }
    179             }
    180         }
    181         else
    182         {
    183             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    184             if (log)
    185                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
    186         }
    187     }
    188     return 0;
    189 }
    190 
    191 uint64_t
    192 SBThread::GetStopReasonDataAtIndex (uint32_t idx)
    193 {
    194     Mutex::Locker api_locker;
    195     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
    196 
    197     if (exe_ctx.HasThreadScope())
    198     {
    199         Process::StopLocker stop_locker;
    200         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
    201         {
    202             Thread *thread = exe_ctx.GetThreadPtr();
    203             StopInfoSP stop_info_sp = thread->GetStopInfo ();
    204             if (stop_info_sp)
    205             {
    206                 StopReason reason = stop_info_sp->GetStopReason();
    207                 switch (reason)
    208                 {
    209                 case eStopReasonInvalid:
    210                 case eStopReasonNone:
    211                 case eStopReasonTrace:
    212                 case eStopReasonExec:
    213                 case eStopReasonPlanComplete:
    214                 case eStopReasonThreadExiting:
    215                     // There is no data for these stop reasons.
    216                     return 0;
    217 
    218                 case eStopReasonBreakpoint:
    219                     {
    220                         break_id_t site_id = stop_info_sp->GetValue();
    221                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
    222                         if (bp_site_sp)
    223                         {
    224                             uint32_t bp_index = idx / 2;
    225                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
    226                             if (bp_loc_sp)
    227                             {
    228                                 if (bp_index & 1)
    229                                 {
    230                                     // Odd idx, return the breakpoint location ID
    231                                     return bp_loc_sp->GetID();
    232                                 }
    233                                 else
    234                                 {
    235                                     // Even idx, return the breakpoint ID
    236                                     return bp_loc_sp->GetBreakpoint().GetID();
    237                                 }
    238                             }
    239                         }
    240                         return LLDB_INVALID_BREAK_ID;
    241                     }
    242                     break;
    243 
    244                 case eStopReasonWatchpoint:
    245                     return stop_info_sp->GetValue();
    246 
    247                 case eStopReasonSignal:
    248                     return stop_info_sp->GetValue();
    249 
    250                 case eStopReasonException:
    251                     return stop_info_sp->GetValue();
    252                 }
    253             }
    254         }
    255         else
    256         {
    257             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    258             if (log)
    259                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
    260         }
    261     }
    262     return 0;
    263 }
    264 
    265 size_t
    266 SBThread::GetStopDescription (char *dst, size_t dst_len)
    267 {
    268     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    269 
    270     Mutex::Locker api_locker;
    271     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
    272 
    273     if (exe_ctx.HasThreadScope())
    274     {
    275         Process::StopLocker stop_locker;
    276         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
    277         {
    278 
    279             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
    280             if (stop_info_sp)
    281             {
    282                 const char *stop_desc = stop_info_sp->GetDescription();
    283                 if (stop_desc)
    284                 {
    285                     if (log)
    286                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
    287                                      exe_ctx.GetThreadPtr(), stop_desc);
    288                     if (dst)
    289                         return ::snprintf (dst, dst_len, "%s", stop_desc);
    290                     else
    291                     {
    292                         // NULL dst passed in, return the length needed to contain the description
    293                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
    294                     }
    295                 }
    296                 else
    297                 {
    298                     size_t stop_desc_len = 0;
    299                     switch (stop_info_sp->GetStopReason())
    300                     {
    301                     case eStopReasonTrace:
    302                     case eStopReasonPlanComplete:
    303                         {
    304                             static char trace_desc[] = "step";
    305                             stop_desc = trace_desc;
    306                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
    307                         }
    308                         break;
    309 
    310                     case eStopReasonBreakpoint:
    311                         {
    312                             static char bp_desc[] = "breakpoint hit";
    313                             stop_desc = bp_desc;
    314                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
    315                         }
    316                         break;
    317 
    318                     case eStopReasonWatchpoint:
    319                         {
    320                             static char wp_desc[] = "watchpoint hit";
    321                             stop_desc = wp_desc;
    322                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
    323                         }
    324                         break;
    325 
    326                     case eStopReasonSignal:
    327                         {
    328                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
    329                             if (stop_desc == NULL || stop_desc[0] == '\0')
    330                             {
    331                                 static char signal_desc[] = "signal";
    332                                 stop_desc = signal_desc;
    333                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
    334                             }
    335                         }
    336                         break;
    337 
    338                     case eStopReasonException:
    339                         {
    340                             char exc_desc[] = "exception";
    341                             stop_desc = exc_desc;
    342                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
    343                         }
    344                         break;
    345 
    346                     case eStopReasonExec:
    347                         {
    348                             char exc_desc[] = "exec";
    349                             stop_desc = exc_desc;
    350                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
    351                         }
    352                         break;
    353 
    354                     case eStopReasonThreadExiting:
    355                         {
    356                             char limbo_desc[] = "thread exiting";
    357                             stop_desc = limbo_desc;
    358                             stop_desc_len = sizeof(limbo_desc);
    359                         }
    360                         break;
    361                     default:
    362                         break;
    363                     }
    364 
    365                     if (stop_desc && stop_desc[0])
    366                     {
    367                         if (log)
    368                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
    369                                          exe_ctx.GetThreadPtr(), stop_desc);
    370 
    371                         if (dst)
    372                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
    373 
    374                         if (stop_desc_len == 0)
    375                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
    376 
    377                         return stop_desc_len;
    378                     }
    379                 }
    380             }
    381         }
    382         else
    383         {
    384             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    385             if (log)
    386                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
    387         }
    388     }
    389     if (dst)
    390         *dst = 0;
    391     return 0;
    392 }
    393 
    394 SBValue
    395 SBThread::GetStopReturnValue ()
    396 {
    397     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    398     ValueObjectSP return_valobj_sp;
    399     Mutex::Locker api_locker;
    400     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
    401 
    402     if (exe_ctx.HasThreadScope())
    403     {
    404         Process::StopLocker stop_locker;
    405         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
    406         {
    407             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
    408             if (stop_info_sp)
    409             {
    410                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
    411             }
    412         }
    413         else
    414         {
    415             if (log)
    416                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
    417         }
    418     }
    419 
    420     if (log)
    421         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
    422                                                                   return_valobj_sp.get()
    423                                                                       ? return_valobj_sp->GetValueAsCString()
    424                                                                         : "<no return value>");
    425 
    426     return SBValue (return_valobj_sp);
    427 }
    428 
    429 void
    430 SBThread::SetThread (const ThreadSP& lldb_object_sp)
    431 {
    432     m_opaque_sp->SetThreadSP (lldb_object_sp);
    433 }
    434 
    435 
    436 lldb::tid_t
    437 SBThread::GetThreadID () const
    438 {
    439     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
    440     if (thread_sp)
    441         return thread_sp->GetID();
    442     return LLDB_INVALID_THREAD_ID;
    443 }
    444 
    445 uint32_t
    446 SBThread::GetIndexID () const
    447 {
    448     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
    449     if (thread_sp)
    450         return thread_sp->GetIndexID();
    451     return LLDB_INVALID_INDEX32;
    452 }
    453 
    454 const char *
    455 SBThread::GetName () const
    456 {
    457     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    458     const char *name = NULL;
    459     Mutex::Locker api_locker;
    460     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
    461 
    462     if (exe_ctx.HasThreadScope())
    463     {
    464         Process::StopLocker stop_locker;
    465         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
    466         {
    467             name = exe_ctx.GetThreadPtr()->GetName();
    468         }
    469         else
    470         {
    471             if (log)
    472                 log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
    473         }
    474     }
    475 
    476     if (log)
    477         log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
    478 
    479     return name;
    480 }
    481 
    482 const char *
    483 SBThread::GetQueueName () const
    484 {
    485     const char *name = NULL;
    486     Mutex::Locker api_locker;
    487     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
    488 
    489     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    490     if (exe_ctx.HasThreadScope())
    491     {
    492         Process::StopLocker stop_locker;
    493         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
    494         {
    495             name = exe_ctx.GetThreadPtr()->GetQueueName();
    496         }
    497         else
    498         {
    499             if (log)
    500                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
    501         }
    502     }
    503 
    504     if (log)
    505         log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
    506 
    507     return name;
    508 }
    509 
    510 SBError
    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
    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
    596 SBThread::StepInto (lldb::RunMode stop_other_threads)
    597 {
    598     StepInto (NULL, stop_other_threads);
    599 }
    600 
    601 void
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   1169 SBThread::EventIsThreadEvent (const SBEvent &event)
   1170 {
   1171     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
   1172 }
   1173 
   1174 SBFrame
   1175 SBThread::GetStackFrameFromEvent (const SBEvent &event)
   1176 {
   1177     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
   1178 
   1179 }
   1180 
   1181 SBThread
   1182 SBThread::GetThreadFromEvent (const SBEvent &event)
   1183 {
   1184     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
   1185 }
   1186 
   1187 bool
   1188 SBThread::operator == (const SBThread &rhs) const
   1189 {
   1190     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
   1191 }
   1192 
   1193 bool
   1194 SBThread::operator != (const SBThread &rhs) const
   1195 {
   1196     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
   1197 }
   1198 
   1199 bool
   1200 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
   1216 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