130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 104c5de699SEli Friedman #include "lldb/API/SBThread.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h" 1330fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h" 14dde9cff3SCaroline Tice #include "lldb/API/SBStream.h" 154e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h" 166611103cSGreg Clayton #include "lldb/Core/Debugger.h" 1730fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 1830fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h" 196611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2030fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2130fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2230fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h" 2330fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h" 24f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 2530fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2630fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 2730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 2830fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 2930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h" 3130fdc8d8SChris Lattner 3230fdc8d8SChris Lattner 334c5de699SEli Friedman #include "lldb/API/SBAddress.h" 344c5de699SEli Friedman #include "lldb/API/SBDebugger.h" 3573ca05a2SJim Ingham #include "lldb/API/SBFrame.h" 364c5de699SEli Friedman #include "lldb/API/SBProcess.h" 3773ca05a2SJim Ingham #include "lldb/API/SBValue.h" 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner using namespace lldb; 4030fdc8d8SChris Lattner using namespace lldb_private; 4130fdc8d8SChris Lattner 42cfd1acedSGreg Clayton //---------------------------------------------------------------------- 43cfd1acedSGreg Clayton // Constructors 44cfd1acedSGreg Clayton //---------------------------------------------------------------------- 4530fdc8d8SChris Lattner SBThread::SBThread () : 4617a6ad05SGreg Clayton m_opaque_wp () 4730fdc8d8SChris Lattner { 4830fdc8d8SChris Lattner } 4930fdc8d8SChris Lattner 5030fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) : 5117a6ad05SGreg Clayton m_opaque_wp (lldb_object_sp) 5230fdc8d8SChris Lattner { 5330fdc8d8SChris Lattner } 5430fdc8d8SChris Lattner 5592ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) : 5617a6ad05SGreg Clayton m_opaque_wp (rhs.m_opaque_wp) 5730fdc8d8SChris Lattner { 5830fdc8d8SChris Lattner } 5930fdc8d8SChris Lattner 6030fdc8d8SChris Lattner //---------------------------------------------------------------------- 61cfd1acedSGreg Clayton // Assignment operator 62cfd1acedSGreg Clayton //---------------------------------------------------------------------- 63cfd1acedSGreg Clayton 64cfd1acedSGreg Clayton const lldb::SBThread & 65cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs) 66cfd1acedSGreg Clayton { 67cfd1acedSGreg Clayton if (this != &rhs) 6817a6ad05SGreg Clayton m_opaque_wp = rhs.m_opaque_wp; 69cfd1acedSGreg Clayton return *this; 70cfd1acedSGreg Clayton } 71cfd1acedSGreg Clayton 72cfd1acedSGreg Clayton //---------------------------------------------------------------------- 7330fdc8d8SChris Lattner // Destructor 7430fdc8d8SChris Lattner //---------------------------------------------------------------------- 7530fdc8d8SChris Lattner SBThread::~SBThread() 7630fdc8d8SChris Lattner { 7730fdc8d8SChris Lattner } 7830fdc8d8SChris Lattner 7930fdc8d8SChris Lattner bool 8030fdc8d8SChris Lattner SBThread::IsValid() const 8130fdc8d8SChris Lattner { 8217a6ad05SGreg Clayton return !m_opaque_wp.expired(); 8330fdc8d8SChris Lattner } 8430fdc8d8SChris Lattner 8548e42549SGreg Clayton void 8648e42549SGreg Clayton SBThread::Clear () 8748e42549SGreg Clayton { 8817a6ad05SGreg Clayton m_opaque_wp.reset(); 8948e42549SGreg Clayton } 9048e42549SGreg Clayton 9148e42549SGreg Clayton 9230fdc8d8SChris Lattner StopReason 9330fdc8d8SChris Lattner SBThread::GetStopReason() 9430fdc8d8SChris Lattner { 952d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 96ceb6b139SCaroline Tice 97ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 9817a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 9917a6ad05SGreg Clayton if (thread_sp) 10030fdc8d8SChris Lattner { 10117a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 10217a6ad05SGreg Clayton StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 103b15bfc75SJim Ingham if (stop_info_sp) 104ceb6b139SCaroline Tice reason = stop_info_sp->GetStopReason(); 10530fdc8d8SChris Lattner } 106ceb6b139SCaroline Tice 107ceb6b139SCaroline Tice if (log) 10817a6ad05SGreg Clayton log->Printf ("SBThread(%p)::GetStopReason () => %s", thread_sp.get(), 109750cd175SCaroline Tice Thread::StopReasonAsCString (reason)); 110ceb6b139SCaroline Tice 111ceb6b139SCaroline Tice return reason; 11230fdc8d8SChris Lattner } 11330fdc8d8SChris Lattner 11430fdc8d8SChris Lattner size_t 1154e78f606SGreg Clayton SBThread::GetStopReasonDataCount () 1164e78f606SGreg Clayton { 11717a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 11817a6ad05SGreg Clayton if (thread_sp) 1194e78f606SGreg Clayton { 12017a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 12117a6ad05SGreg Clayton StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 1224e78f606SGreg Clayton if (stop_info_sp) 1234e78f606SGreg Clayton { 1244e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1254e78f606SGreg Clayton switch (reason) 1264e78f606SGreg Clayton { 1274e78f606SGreg Clayton case eStopReasonInvalid: 1284e78f606SGreg Clayton case eStopReasonNone: 1294e78f606SGreg Clayton case eStopReasonTrace: 1304e78f606SGreg Clayton case eStopReasonPlanComplete: 1314e78f606SGreg Clayton // There is no data for these stop reasons. 1324e78f606SGreg Clayton return 0; 1334e78f606SGreg Clayton 1344e78f606SGreg Clayton case eStopReasonBreakpoint: 1354e78f606SGreg Clayton { 1364e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 13717a6ad05SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id)); 1384e78f606SGreg Clayton if (bp_site_sp) 1394e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners () * 2; 1404e78f606SGreg Clayton else 1414e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 1424e78f606SGreg Clayton } 1434e78f606SGreg Clayton break; 1444e78f606SGreg Clayton 1454e78f606SGreg Clayton case eStopReasonWatchpoint: 146290fa41bSJohnny Chen return 1; 1474e78f606SGreg Clayton 1484e78f606SGreg Clayton case eStopReasonSignal: 1494e78f606SGreg Clayton return 1; 1504e78f606SGreg Clayton 1514e78f606SGreg Clayton case eStopReasonException: 1524e78f606SGreg Clayton return 1; 1534e78f606SGreg Clayton } 1544e78f606SGreg Clayton } 1554e78f606SGreg Clayton } 1564e78f606SGreg Clayton return 0; 1574e78f606SGreg Clayton } 1584e78f606SGreg Clayton 1594e78f606SGreg Clayton uint64_t 1604e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx) 1614e78f606SGreg Clayton { 16217a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 16317a6ad05SGreg Clayton if (thread_sp) 1644e78f606SGreg Clayton { 16517a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 16617a6ad05SGreg Clayton StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 1674e78f606SGreg Clayton if (stop_info_sp) 1684e78f606SGreg Clayton { 1694e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1704e78f606SGreg Clayton switch (reason) 1714e78f606SGreg Clayton { 1724e78f606SGreg Clayton case eStopReasonInvalid: 1734e78f606SGreg Clayton case eStopReasonNone: 1744e78f606SGreg Clayton case eStopReasonTrace: 1754e78f606SGreg Clayton case eStopReasonPlanComplete: 1764e78f606SGreg Clayton // There is no data for these stop reasons. 1774e78f606SGreg Clayton return 0; 1784e78f606SGreg Clayton 1794e78f606SGreg Clayton case eStopReasonBreakpoint: 1804e78f606SGreg Clayton { 1814e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 18217a6ad05SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id)); 1834e78f606SGreg Clayton if (bp_site_sp) 1844e78f606SGreg Clayton { 1854e78f606SGreg Clayton uint32_t bp_index = idx / 2; 1864e78f606SGreg Clayton BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 1874e78f606SGreg Clayton if (bp_loc_sp) 1884e78f606SGreg Clayton { 1894e78f606SGreg Clayton if (bp_index & 1) 1904e78f606SGreg Clayton { 1914e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 1924e78f606SGreg Clayton return bp_loc_sp->GetID(); 1934e78f606SGreg Clayton } 1944e78f606SGreg Clayton else 1954e78f606SGreg Clayton { 1964e78f606SGreg Clayton // Even idx, return the breakpoint ID 1974e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 1984e78f606SGreg Clayton } 1994e78f606SGreg Clayton } 2004e78f606SGreg Clayton } 2014e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 2024e78f606SGreg Clayton } 2034e78f606SGreg Clayton break; 2044e78f606SGreg Clayton 2054e78f606SGreg Clayton case eStopReasonWatchpoint: 206290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2074e78f606SGreg Clayton 2084e78f606SGreg Clayton case eStopReasonSignal: 2094e78f606SGreg Clayton return stop_info_sp->GetValue(); 2104e78f606SGreg Clayton 2114e78f606SGreg Clayton case eStopReasonException: 2124e78f606SGreg Clayton return stop_info_sp->GetValue(); 2134e78f606SGreg Clayton } 2144e78f606SGreg Clayton } 2154e78f606SGreg Clayton } 2164e78f606SGreg Clayton return 0; 2174e78f606SGreg Clayton } 2184e78f606SGreg Clayton 2194e78f606SGreg Clayton size_t 22030fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len) 22130fdc8d8SChris Lattner { 2222d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 223ceb6b139SCaroline Tice 22417a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 22517a6ad05SGreg Clayton if (thread_sp) 22630fdc8d8SChris Lattner { 22717a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 22817a6ad05SGreg Clayton StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 229b15bfc75SJim Ingham if (stop_info_sp) 23030fdc8d8SChris Lattner { 231b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 23230fdc8d8SChris Lattner if (stop_desc) 23330fdc8d8SChris Lattner { 234ceb6b139SCaroline Tice if (log) 2354838131bSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 23617a6ad05SGreg Clayton thread_sp.get(), stop_desc); 23730fdc8d8SChris Lattner if (dst) 23830fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc); 23930fdc8d8SChris Lattner else 24030fdc8d8SChris Lattner { 24130fdc8d8SChris Lattner // NULL dst passed in, return the length needed to contain the description 24230fdc8d8SChris Lattner return ::strlen (stop_desc) + 1; // Include the NULL byte for size 24330fdc8d8SChris Lattner } 24430fdc8d8SChris Lattner } 24530fdc8d8SChris Lattner else 24630fdc8d8SChris Lattner { 24730fdc8d8SChris Lattner size_t stop_desc_len = 0; 248b15bfc75SJim Ingham switch (stop_info_sp->GetStopReason()) 24930fdc8d8SChris Lattner { 25030fdc8d8SChris Lattner case eStopReasonTrace: 25130fdc8d8SChris Lattner case eStopReasonPlanComplete: 25230fdc8d8SChris Lattner { 25330fdc8d8SChris Lattner static char trace_desc[] = "step"; 25430fdc8d8SChris Lattner stop_desc = trace_desc; 25530fdc8d8SChris Lattner stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 25630fdc8d8SChris Lattner } 25730fdc8d8SChris Lattner break; 25830fdc8d8SChris Lattner 25930fdc8d8SChris Lattner case eStopReasonBreakpoint: 26030fdc8d8SChris Lattner { 26130fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 26230fdc8d8SChris Lattner stop_desc = bp_desc; 26330fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 26430fdc8d8SChris Lattner } 26530fdc8d8SChris Lattner break; 26630fdc8d8SChris Lattner 26730fdc8d8SChris Lattner case eStopReasonWatchpoint: 26830fdc8d8SChris Lattner { 26930fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 27030fdc8d8SChris Lattner stop_desc = wp_desc; 27130fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 27230fdc8d8SChris Lattner } 27330fdc8d8SChris Lattner break; 27430fdc8d8SChris Lattner 27530fdc8d8SChris Lattner case eStopReasonSignal: 27630fdc8d8SChris Lattner { 27717a6ad05SGreg Clayton stop_desc = thread_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 27830fdc8d8SChris Lattner if (stop_desc == NULL || stop_desc[0] == '\0') 27930fdc8d8SChris Lattner { 28030fdc8d8SChris Lattner static char signal_desc[] = "signal"; 28130fdc8d8SChris Lattner stop_desc = signal_desc; 28230fdc8d8SChris Lattner stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 28330fdc8d8SChris Lattner } 28430fdc8d8SChris Lattner } 28530fdc8d8SChris Lattner break; 28630fdc8d8SChris Lattner 28730fdc8d8SChris Lattner case eStopReasonException: 28830fdc8d8SChris Lattner { 28930fdc8d8SChris Lattner char exc_desc[] = "exception"; 29030fdc8d8SChris Lattner stop_desc = exc_desc; 29130fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 29230fdc8d8SChris Lattner } 29330fdc8d8SChris Lattner break; 294c982c768SGreg Clayton 295c982c768SGreg Clayton default: 296c982c768SGreg Clayton break; 29730fdc8d8SChris Lattner } 29830fdc8d8SChris Lattner 29930fdc8d8SChris Lattner if (stop_desc && stop_desc[0]) 30030fdc8d8SChris Lattner { 301ceb6b139SCaroline Tice if (log) 30293aa84e8SGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 30317a6ad05SGreg Clayton thread_sp.get(), stop_desc); 304ceb6b139SCaroline Tice 30530fdc8d8SChris Lattner if (dst) 30630fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 30730fdc8d8SChris Lattner 30830fdc8d8SChris Lattner if (stop_desc_len == 0) 30930fdc8d8SChris Lattner stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 31030fdc8d8SChris Lattner 31130fdc8d8SChris Lattner return stop_desc_len; 31230fdc8d8SChris Lattner } 31330fdc8d8SChris Lattner } 31430fdc8d8SChris Lattner } 31530fdc8d8SChris Lattner } 31630fdc8d8SChris Lattner if (dst) 31730fdc8d8SChris Lattner *dst = 0; 31830fdc8d8SChris Lattner return 0; 31930fdc8d8SChris Lattner } 32030fdc8d8SChris Lattner 32173ca05a2SJim Ingham SBValue 32273ca05a2SJim Ingham SBThread::GetStopReturnValue () 32373ca05a2SJim Ingham { 32473ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 32517a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 32617a6ad05SGreg Clayton if (thread_sp) 32773ca05a2SJim Ingham { 32817a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 32917a6ad05SGreg Clayton StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 33073ca05a2SJim Ingham if (stop_info_sp) 33173ca05a2SJim Ingham { 33273ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 33373ca05a2SJim Ingham } 33473ca05a2SJim Ingham } 33573ca05a2SJim Ingham 33673ca05a2SJim Ingham LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 33773ca05a2SJim Ingham if (log) 33817a6ad05SGreg Clayton log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", thread_sp.get(), 33973ca05a2SJim Ingham return_valobj_sp.get() 34073ca05a2SJim Ingham ? return_valobj_sp->GetValueAsCString() 34173ca05a2SJim Ingham : "<no return value>"); 34273ca05a2SJim Ingham 34373ca05a2SJim Ingham return SBValue (return_valobj_sp); 34473ca05a2SJim Ingham } 34573ca05a2SJim Ingham 34630fdc8d8SChris Lattner void 34730fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp) 34830fdc8d8SChris Lattner { 34917a6ad05SGreg Clayton m_opaque_wp = lldb_object_sp; 35030fdc8d8SChris Lattner } 35130fdc8d8SChris Lattner 35230fdc8d8SChris Lattner 35330fdc8d8SChris Lattner lldb::tid_t 35430fdc8d8SChris Lattner SBThread::GetThreadID () const 35530fdc8d8SChris Lattner { 3562d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 357ceb6b139SCaroline Tice 358af67cecdSGreg Clayton lldb::tid_t tid = LLDB_INVALID_THREAD_ID; 35917a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 36017a6ad05SGreg Clayton if (thread_sp) 36117a6ad05SGreg Clayton tid = thread_sp->GetID(); 362ceb6b139SCaroline Tice 363ceb6b139SCaroline Tice if (log) 36417a6ad05SGreg Clayton log->Printf ("SBThread(%p)::GetThreadID () => 0x%4.4llx", thread_sp.get(), tid); 365ceb6b139SCaroline Tice 366af67cecdSGreg Clayton return tid; 36730fdc8d8SChris Lattner } 36830fdc8d8SChris Lattner 36930fdc8d8SChris Lattner uint32_t 37030fdc8d8SChris Lattner SBThread::GetIndexID () const 37130fdc8d8SChris Lattner { 37217a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 37317a6ad05SGreg Clayton if (thread_sp) 37417a6ad05SGreg Clayton return thread_sp->GetIndexID(); 37530fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 37630fdc8d8SChris Lattner } 37730fdc8d8SChris Lattner const char * 37830fdc8d8SChris Lattner SBThread::GetName () const 37930fdc8d8SChris Lattner { 3804838131bSGreg Clayton const char *name = NULL; 38117a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 38217a6ad05SGreg Clayton if (thread_sp) 383af67cecdSGreg Clayton { 38417a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 38517a6ad05SGreg Clayton name = thread_sp->GetName(); 386af67cecdSGreg Clayton } 387ceb6b139SCaroline Tice 3882d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 389ceb6b139SCaroline Tice if (log) 39017a6ad05SGreg Clayton log->Printf ("SBThread(%p)::GetName () => %s", thread_sp.get(), name ? name : "NULL"); 391ceb6b139SCaroline Tice 3924838131bSGreg Clayton return name; 39330fdc8d8SChris Lattner } 39430fdc8d8SChris Lattner 39530fdc8d8SChris Lattner const char * 39630fdc8d8SChris Lattner SBThread::GetQueueName () const 39730fdc8d8SChris Lattner { 3984838131bSGreg Clayton const char *name = NULL; 39917a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 40017a6ad05SGreg Clayton if (thread_sp) 401af67cecdSGreg Clayton { 40217a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 40317a6ad05SGreg Clayton name = thread_sp->GetQueueName(); 404af67cecdSGreg Clayton } 405ceb6b139SCaroline Tice 4062d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 407ceb6b139SCaroline Tice if (log) 40817a6ad05SGreg Clayton log->Printf ("SBThread(%p)::GetQueueName () => %s", thread_sp.get(), name ? name : "NULL"); 409ceb6b139SCaroline Tice 4104838131bSGreg Clayton return name; 41130fdc8d8SChris Lattner } 41230fdc8d8SChris Lattner 41330fdc8d8SChris Lattner 41430fdc8d8SChris Lattner void 41530fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads) 41630fdc8d8SChris Lattner { 4172d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 418ceb6b139SCaroline Tice 41917a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 42017a6ad05SGreg Clayton 421ceb6b139SCaroline Tice if (log) 42217a6ad05SGreg Clayton log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", thread_sp.get(), 423ceb6b139SCaroline Tice Thread::RunModeAsCString (stop_other_threads)); 424ceb6b139SCaroline Tice 42517a6ad05SGreg Clayton if (thread_sp) 42630fdc8d8SChris Lattner { 42717a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 42830fdc8d8SChris Lattner bool abort_other_plans = true; 42917a6ad05SGreg Clayton StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0)); 43030fdc8d8SChris Lattner 43130fdc8d8SChris Lattner if (frame_sp) 43230fdc8d8SChris Lattner { 43330fdc8d8SChris Lattner if (frame_sp->HasDebugInformation ()) 43430fdc8d8SChris Lattner { 43530fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 43617a6ad05SGreg Clayton thread_sp->QueueThreadPlanForStepRange (abort_other_plans, 43730fdc8d8SChris Lattner eStepTypeOver, 43830fdc8d8SChris Lattner sc.line_entry.range, 43930fdc8d8SChris Lattner sc, 440474966a4SGreg Clayton stop_other_threads, 441474966a4SGreg Clayton false); 44230fdc8d8SChris Lattner 44330fdc8d8SChris Lattner } 44430fdc8d8SChris Lattner else 44530fdc8d8SChris Lattner { 44617a6ad05SGreg Clayton thread_sp->QueueThreadPlanForStepSingleInstruction (true, 44730fdc8d8SChris Lattner abort_other_plans, 44830fdc8d8SChris Lattner stop_other_threads); 44930fdc8d8SChris Lattner } 45030fdc8d8SChris Lattner } 45130fdc8d8SChris Lattner 45217a6ad05SGreg Clayton Process &process = thread_sp->GetProcess(); 45330fdc8d8SChris Lattner // Why do we need to set the current thread by ID here??? 45417a6ad05SGreg Clayton process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 4555d5028b5SGreg Clayton Error error (process.Resume()); 4565d5028b5SGreg Clayton if (error.Success()) 4575d5028b5SGreg Clayton { 4585d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 4595d5028b5SGreg Clayton // process to stop yet again! 4605d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 4615d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 4625d5028b5SGreg Clayton } 46330fdc8d8SChris Lattner } 46430fdc8d8SChris Lattner } 46530fdc8d8SChris Lattner 46630fdc8d8SChris Lattner void 46730fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads) 46830fdc8d8SChris Lattner { 4692d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 470ceb6b139SCaroline Tice 471ceb6b139SCaroline Tice 47217a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 47317a6ad05SGreg Clayton 47417a6ad05SGreg Clayton if (log) 47517a6ad05SGreg Clayton log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", thread_sp.get(), 47617a6ad05SGreg Clayton Thread::RunModeAsCString (stop_other_threads)); 47717a6ad05SGreg Clayton if (thread_sp) 47830fdc8d8SChris Lattner { 47917a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 48030fdc8d8SChris Lattner bool abort_other_plans = true; 48130fdc8d8SChris Lattner 48217a6ad05SGreg Clayton StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0)); 48330fdc8d8SChris Lattner 48430fdc8d8SChris Lattner if (frame_sp && frame_sp->HasDebugInformation ()) 48530fdc8d8SChris Lattner { 486474966a4SGreg Clayton bool avoid_code_without_debug_info = true; 48730fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 48817a6ad05SGreg Clayton thread_sp->QueueThreadPlanForStepRange (abort_other_plans, 48930fdc8d8SChris Lattner eStepTypeInto, 49030fdc8d8SChris Lattner sc.line_entry.range, 49130fdc8d8SChris Lattner sc, 492474966a4SGreg Clayton stop_other_threads, 493474966a4SGreg Clayton avoid_code_without_debug_info); 49430fdc8d8SChris Lattner } 49530fdc8d8SChris Lattner else 49630fdc8d8SChris Lattner { 49717a6ad05SGreg Clayton thread_sp->QueueThreadPlanForStepSingleInstruction (false, 49830fdc8d8SChris Lattner abort_other_plans, 49930fdc8d8SChris Lattner stop_other_threads); 50030fdc8d8SChris Lattner } 50130fdc8d8SChris Lattner 50217a6ad05SGreg Clayton Process &process = thread_sp->GetProcess(); 50330fdc8d8SChris Lattner // Why do we need to set the current thread by ID here??? 50417a6ad05SGreg Clayton process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 5055d5028b5SGreg Clayton Error error (process.Resume()); 5065d5028b5SGreg Clayton if (error.Success()) 5075d5028b5SGreg Clayton { 5085d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 5095d5028b5SGreg Clayton // process to stop yet again! 5105d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 5115d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 5125d5028b5SGreg Clayton } 51330fdc8d8SChris Lattner } 51430fdc8d8SChris Lattner } 51530fdc8d8SChris Lattner 51630fdc8d8SChris Lattner void 51730fdc8d8SChris Lattner SBThread::StepOut () 51830fdc8d8SChris Lattner { 5192d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 520ceb6b139SCaroline Tice 52117a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 522ceb6b139SCaroline Tice 52317a6ad05SGreg Clayton if (log) 52417a6ad05SGreg Clayton log->Printf ("SBThread(%p)::StepOut ()", thread_sp.get()); 52517a6ad05SGreg Clayton 52617a6ad05SGreg Clayton if (thread_sp) 52730fdc8d8SChris Lattner { 52817a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 52930fdc8d8SChris Lattner bool abort_other_plans = true; 53030fdc8d8SChris Lattner bool stop_other_threads = true; 53130fdc8d8SChris Lattner 53217a6ad05SGreg Clayton thread_sp->QueueThreadPlanForStepOut (abort_other_plans, 533481cef25SGreg Clayton NULL, 534481cef25SGreg Clayton false, 535481cef25SGreg Clayton stop_other_threads, 536481cef25SGreg Clayton eVoteYes, 537481cef25SGreg Clayton eVoteNoOpinion, 538481cef25SGreg Clayton 0); 539481cef25SGreg Clayton 54017a6ad05SGreg Clayton Process &process = thread_sp->GetProcess(); 54117a6ad05SGreg Clayton process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 542481cef25SGreg Clayton Error error (process.Resume()); 543481cef25SGreg Clayton if (error.Success()) 544481cef25SGreg Clayton { 545481cef25SGreg Clayton // If we are doing synchronous mode, then wait for the 546481cef25SGreg Clayton // process to stop yet again! 547481cef25SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 548481cef25SGreg Clayton process.WaitForProcessToStop (NULL); 549481cef25SGreg Clayton } 550481cef25SGreg Clayton } 551481cef25SGreg Clayton } 552481cef25SGreg Clayton 553481cef25SGreg Clayton void 554481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 555481cef25SGreg Clayton { 556481cef25SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 557481cef25SGreg Clayton 55817a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 55917a6ad05SGreg Clayton 560*b9556accSGreg Clayton StackFrameSP frame_sp (sb_frame.GetFrameSP()); 561481cef25SGreg Clayton if (log) 562481cef25SGreg Clayton { 563481cef25SGreg Clayton SBStream frame_desc_strm; 564481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 565*b9556accSGreg Clayton log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", thread_sp.get(), frame_sp.get(), frame_desc_strm.GetData()); 566481cef25SGreg Clayton } 567481cef25SGreg Clayton 56817a6ad05SGreg Clayton if (thread_sp) 569481cef25SGreg Clayton { 57017a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 571481cef25SGreg Clayton bool abort_other_plans = true; 572481cef25SGreg Clayton bool stop_other_threads = true; 573481cef25SGreg Clayton 57417a6ad05SGreg Clayton thread_sp->QueueThreadPlanForStepOut (abort_other_plans, 575481cef25SGreg Clayton NULL, 576481cef25SGreg Clayton false, 577481cef25SGreg Clayton stop_other_threads, 578481cef25SGreg Clayton eVoteYes, 579481cef25SGreg Clayton eVoteNoOpinion, 580*b9556accSGreg Clayton frame_sp->GetFrameIndex()); 58130fdc8d8SChris Lattner 58217a6ad05SGreg Clayton Process &process = thread_sp->GetProcess(); 58317a6ad05SGreg Clayton process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 5845d5028b5SGreg Clayton Error error (process.Resume()); 5855d5028b5SGreg Clayton if (error.Success()) 5865d5028b5SGreg Clayton { 5875d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 5885d5028b5SGreg Clayton // process to stop yet again! 5895d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 5905d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 5915d5028b5SGreg Clayton } 59230fdc8d8SChris Lattner } 59330fdc8d8SChris Lattner } 59430fdc8d8SChris Lattner 59530fdc8d8SChris Lattner void 59630fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over) 59730fdc8d8SChris Lattner { 5982d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 599ceb6b139SCaroline Tice 60017a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 601ceb6b139SCaroline Tice 60217a6ad05SGreg Clayton if (log) 60317a6ad05SGreg Clayton log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", thread_sp.get(), step_over); 60417a6ad05SGreg Clayton 60517a6ad05SGreg Clayton if (thread_sp) 60630fdc8d8SChris Lattner { 60717a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 60817a6ad05SGreg Clayton thread_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true); 60917a6ad05SGreg Clayton Process &process = thread_sp->GetProcess(); 61017a6ad05SGreg Clayton process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 6115d5028b5SGreg Clayton Error error (process.Resume()); 6125d5028b5SGreg Clayton if (error.Success()) 6135d5028b5SGreg Clayton { 6145d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 6155d5028b5SGreg Clayton // process to stop yet again! 6165d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 6175d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 6185d5028b5SGreg Clayton } 61930fdc8d8SChris Lattner } 62030fdc8d8SChris Lattner } 62130fdc8d8SChris Lattner 62230fdc8d8SChris Lattner void 62330fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr) 62430fdc8d8SChris Lattner { 6252d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 626ceb6b139SCaroline Tice 62717a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 628ceb6b139SCaroline Tice 62917a6ad05SGreg Clayton if (log) 63017a6ad05SGreg Clayton log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", thread_sp.get(), addr); 63117a6ad05SGreg Clayton 63217a6ad05SGreg Clayton if (thread_sp) 63330fdc8d8SChris Lattner { 63430fdc8d8SChris Lattner bool abort_other_plans = true; 63530fdc8d8SChris Lattner bool stop_other_threads = true; 63630fdc8d8SChris Lattner 63730fdc8d8SChris Lattner Address target_addr (NULL, addr); 63830fdc8d8SChris Lattner 63917a6ad05SGreg Clayton thread_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads); 64017a6ad05SGreg Clayton Process &process = thread_sp->GetProcess(); 64117a6ad05SGreg Clayton process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 6425d5028b5SGreg Clayton Error error (process.Resume()); 6435d5028b5SGreg Clayton if (error.Success()) 6445d5028b5SGreg Clayton { 6455d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 6465d5028b5SGreg Clayton // process to stop yet again! 6475d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 6485d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 6495d5028b5SGreg Clayton } 65030fdc8d8SChris Lattner } 65130fdc8d8SChris Lattner } 65230fdc8d8SChris Lattner 653481cef25SGreg Clayton SBError 654481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 655481cef25SGreg Clayton lldb::SBFileSpec &sb_file_spec, 656481cef25SGreg Clayton uint32_t line) 657481cef25SGreg Clayton { 658481cef25SGreg Clayton SBError sb_error; 659481cef25SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 660481cef25SGreg Clayton char path[PATH_MAX]; 661481cef25SGreg Clayton 66217a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 663*b9556accSGreg Clayton StackFrameSP frame_sp (sb_frame.GetFrameSP()); 66417a6ad05SGreg Clayton 665481cef25SGreg Clayton if (log) 666481cef25SGreg Clayton { 667481cef25SGreg Clayton SBStream frame_desc_strm; 668481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 669481cef25SGreg Clayton sb_file_spec->GetPath (path, sizeof(path)); 670481cef25SGreg Clayton log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 67117a6ad05SGreg Clayton thread_sp.get(), 672*b9556accSGreg Clayton frame_sp.get(), 673481cef25SGreg Clayton frame_desc_strm.GetData(), 674481cef25SGreg Clayton path, line); 675481cef25SGreg Clayton } 676481cef25SGreg Clayton 67717a6ad05SGreg Clayton if (thread_sp) 678481cef25SGreg Clayton { 67917a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 680481cef25SGreg Clayton 681481cef25SGreg Clayton if (line == 0) 682481cef25SGreg Clayton { 683481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 684481cef25SGreg Clayton return sb_error; 685481cef25SGreg Clayton } 686481cef25SGreg Clayton 687481cef25SGreg Clayton StackFrameSP frame_sp; 688*b9556accSGreg Clayton if (!frame_sp) 689481cef25SGreg Clayton { 69017a6ad05SGreg Clayton frame_sp = thread_sp->GetSelectedFrame (); 691481cef25SGreg Clayton if (!frame_sp) 69217a6ad05SGreg Clayton frame_sp = thread_sp->GetStackFrameAtIndex (0); 693481cef25SGreg Clayton } 694481cef25SGreg Clayton 695481cef25SGreg Clayton SymbolContext frame_sc; 696481cef25SGreg Clayton if (!frame_sp) 697481cef25SGreg Clayton { 698481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 699481cef25SGreg Clayton return sb_error; 700481cef25SGreg Clayton } 701481cef25SGreg Clayton 702481cef25SGreg Clayton // If we have a frame, get its line 703481cef25SGreg Clayton frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 704481cef25SGreg Clayton eSymbolContextFunction | 705481cef25SGreg Clayton eSymbolContextLineEntry | 706481cef25SGreg Clayton eSymbolContextSymbol ); 707481cef25SGreg Clayton 708481cef25SGreg Clayton if (frame_sc.comp_unit == NULL) 709481cef25SGreg Clayton { 710481cef25SGreg Clayton sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 711481cef25SGreg Clayton return sb_error; 712481cef25SGreg Clayton } 713481cef25SGreg Clayton 714481cef25SGreg Clayton FileSpec step_file_spec; 715481cef25SGreg Clayton if (sb_file_spec.IsValid()) 716481cef25SGreg Clayton { 717481cef25SGreg Clayton // The file spec passed in was valid, so use it 718481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 719481cef25SGreg Clayton } 720481cef25SGreg Clayton else 721481cef25SGreg Clayton { 722481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 723481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 724481cef25SGreg Clayton else 725481cef25SGreg Clayton { 726481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 727481cef25SGreg Clayton return sb_error; 728481cef25SGreg Clayton } 729481cef25SGreg Clayton } 730481cef25SGreg Clayton 7319b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 7329b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 7339b70ddb3SJim Ingham // function, and then if there are no addresses remaining, give an appropriate 7349b70ddb3SJim Ingham // error message. 7359b70ddb3SJim Ingham 7369b70ddb3SJim Ingham bool all_in_function = true; 7379b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 7389b70ddb3SJim Ingham 739481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 740481cef25SGreg Clayton const bool abort_other_plans = true; 741481cef25SGreg Clayton const bool stop_other_threads = true; 742481cef25SGreg Clayton const bool check_inlines = true; 743481cef25SGreg Clayton const bool exact = false; 74417a6ad05SGreg Clayton Target *target = &thread_sp->GetProcess().GetTarget(); 745481cef25SGreg Clayton 746481cef25SGreg Clayton SymbolContextList sc_list; 7479b70ddb3SJim Ingham const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 7489b70ddb3SJim Ingham line, 7499b70ddb3SJim Ingham check_inlines, 7509b70ddb3SJim Ingham exact, 7519b70ddb3SJim Ingham eSymbolContextLineEntry, 7529b70ddb3SJim Ingham sc_list); 753481cef25SGreg Clayton if (num_matches > 0) 754481cef25SGreg Clayton { 755481cef25SGreg Clayton SymbolContext sc; 756481cef25SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 757481cef25SGreg Clayton { 758481cef25SGreg Clayton if (sc_list.GetContextAtIndex(i, sc)) 759481cef25SGreg Clayton { 7609b70ddb3SJim Ingham addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 761481cef25SGreg Clayton if (step_addr != LLDB_INVALID_ADDRESS) 762481cef25SGreg Clayton { 7639b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 764481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 7659b70ddb3SJim Ingham else 7669b70ddb3SJim Ingham all_in_function = false; 767481cef25SGreg Clayton } 768481cef25SGreg Clayton } 769481cef25SGreg Clayton } 770481cef25SGreg Clayton } 771481cef25SGreg Clayton 772481cef25SGreg Clayton if (step_over_until_addrs.empty()) 773481cef25SGreg Clayton { 7749b70ddb3SJim Ingham if (all_in_function) 7759b70ddb3SJim Ingham { 776481cef25SGreg Clayton step_file_spec.GetPath (path, sizeof(path)); 777fd54b368SJason Molenda sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 778481cef25SGreg Clayton } 779481cef25SGreg Clayton else 78086edbf41SGreg Clayton sb_error.SetErrorString ("step until target not in current function"); 7819b70ddb3SJim Ingham } 7829b70ddb3SJim Ingham else 783481cef25SGreg Clayton { 78417a6ad05SGreg Clayton thread_sp->QueueThreadPlanForStepUntil (abort_other_plans, 785481cef25SGreg Clayton &step_over_until_addrs[0], 786481cef25SGreg Clayton step_over_until_addrs.size(), 787481cef25SGreg Clayton stop_other_threads, 788481cef25SGreg Clayton frame_sp->GetFrameIndex()); 789481cef25SGreg Clayton 79017a6ad05SGreg Clayton thread_sp->GetProcess().GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 79117a6ad05SGreg Clayton sb_error.ref() = thread_sp->GetProcess().Resume(); 792481cef25SGreg Clayton if (sb_error->Success()) 793481cef25SGreg Clayton { 794481cef25SGreg Clayton // If we are doing synchronous mode, then wait for the 795481cef25SGreg Clayton // process to stop yet again! 79617a6ad05SGreg Clayton if (thread_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false) 79717a6ad05SGreg Clayton thread_sp->GetProcess().WaitForProcessToStop (NULL); 798481cef25SGreg Clayton } 799481cef25SGreg Clayton } 800481cef25SGreg Clayton } 801481cef25SGreg Clayton else 802481cef25SGreg Clayton { 803481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 804481cef25SGreg Clayton } 805481cef25SGreg Clayton return sb_error; 806481cef25SGreg Clayton } 807481cef25SGreg Clayton 808481cef25SGreg Clayton 809722a0cdcSGreg Clayton bool 810722a0cdcSGreg Clayton SBThread::Suspend() 811722a0cdcSGreg Clayton { 81217a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 81317a6ad05SGreg Clayton if (thread_sp) 814722a0cdcSGreg Clayton { 81517a6ad05SGreg Clayton thread_sp->SetResumeState (eStateSuspended); 816722a0cdcSGreg Clayton return true; 817722a0cdcSGreg Clayton } 818722a0cdcSGreg Clayton return false; 819722a0cdcSGreg Clayton } 820722a0cdcSGreg Clayton 821722a0cdcSGreg Clayton bool 822722a0cdcSGreg Clayton SBThread::Resume () 823722a0cdcSGreg Clayton { 82417a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 82517a6ad05SGreg Clayton if (thread_sp) 826722a0cdcSGreg Clayton { 82717a6ad05SGreg Clayton thread_sp->SetResumeState (eStateRunning); 828722a0cdcSGreg Clayton return true; 829722a0cdcSGreg Clayton } 830722a0cdcSGreg Clayton return false; 831722a0cdcSGreg Clayton } 832722a0cdcSGreg Clayton 833722a0cdcSGreg Clayton bool 834722a0cdcSGreg Clayton SBThread::IsSuspended() 835722a0cdcSGreg Clayton { 83617a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 83717a6ad05SGreg Clayton if (thread_sp) 83817a6ad05SGreg Clayton return thread_sp->GetResumeState () == eStateSuspended; 839722a0cdcSGreg Clayton return false; 840722a0cdcSGreg Clayton } 841722a0cdcSGreg Clayton 84230fdc8d8SChris Lattner SBProcess 84330fdc8d8SChris Lattner SBThread::GetProcess () 84430fdc8d8SChris Lattner { 845ceb6b139SCaroline Tice 846*b9556accSGreg Clayton SBProcess sb_process; 847*b9556accSGreg Clayton ProcessSP process_sp; 84817a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 84917a6ad05SGreg Clayton if (thread_sp) 85030fdc8d8SChris Lattner { 85130fdc8d8SChris Lattner // Have to go up to the target so we can get a shared pointer to our process... 852*b9556accSGreg Clayton process_sp = thread_sp->GetProcess().GetTarget().GetProcessSP(); 853*b9556accSGreg Clayton sb_process.SetSP (process_sp); 85430fdc8d8SChris Lattner } 855ceb6b139SCaroline Tice 8562d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 857ceb6b139SCaroline Tice if (log) 858ceb6b139SCaroline Tice { 859481cef25SGreg Clayton SBStream frame_desc_strm; 860*b9556accSGreg Clayton sb_process.GetDescription (frame_desc_strm); 86117a6ad05SGreg Clayton log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", thread_sp.get(), 862*b9556accSGreg Clayton process_sp.get(), frame_desc_strm.GetData()); 863ceb6b139SCaroline Tice } 864ceb6b139SCaroline Tice 865*b9556accSGreg Clayton return sb_process; 86630fdc8d8SChris Lattner } 86730fdc8d8SChris Lattner 86830fdc8d8SChris Lattner uint32_t 86930fdc8d8SChris Lattner SBThread::GetNumFrames () 87030fdc8d8SChris Lattner { 8712d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 872ceb6b139SCaroline Tice 873ceb6b139SCaroline Tice uint32_t num_frames = 0; 87417a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 87517a6ad05SGreg Clayton if (thread_sp) 876af67cecdSGreg Clayton { 87717a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 87817a6ad05SGreg Clayton num_frames = thread_sp->GetStackFrameCount(); 879af67cecdSGreg Clayton } 880ceb6b139SCaroline Tice 881ceb6b139SCaroline Tice if (log) 88217a6ad05SGreg Clayton log->Printf ("SBThread(%p)::GetNumFrames () => %u", thread_sp.get(), num_frames); 883ceb6b139SCaroline Tice 884ceb6b139SCaroline Tice return num_frames; 88530fdc8d8SChris Lattner } 88630fdc8d8SChris Lattner 88730fdc8d8SChris Lattner SBFrame 88830fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx) 88930fdc8d8SChris Lattner { 8902d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 891ceb6b139SCaroline Tice 89230fdc8d8SChris Lattner SBFrame sb_frame; 893*b9556accSGreg Clayton StackFrameSP frame_sp; 89417a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 89517a6ad05SGreg Clayton if (thread_sp) 896af67cecdSGreg Clayton { 89717a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 898*b9556accSGreg Clayton frame_sp = thread_sp->GetStackFrameAtIndex (idx); 899*b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 900af67cecdSGreg Clayton } 901ceb6b139SCaroline Tice 902ceb6b139SCaroline Tice if (log) 903ceb6b139SCaroline Tice { 904481cef25SGreg Clayton SBStream frame_desc_strm; 905481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 9064838131bSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 907*b9556accSGreg Clayton thread_sp.get(), idx, frame_sp.get(), frame_desc_strm.GetData()); 908ceb6b139SCaroline Tice } 909ceb6b139SCaroline Tice 91030fdc8d8SChris Lattner return sb_frame; 91130fdc8d8SChris Lattner } 91230fdc8d8SChris Lattner 913f028a1fbSGreg Clayton lldb::SBFrame 914f028a1fbSGreg Clayton SBThread::GetSelectedFrame () 915f028a1fbSGreg Clayton { 916f028a1fbSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 917f028a1fbSGreg Clayton 918f028a1fbSGreg Clayton SBFrame sb_frame; 919*b9556accSGreg Clayton StackFrameSP frame_sp; 92017a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 92117a6ad05SGreg Clayton if (thread_sp) 922af67cecdSGreg Clayton { 92317a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 924*b9556accSGreg Clayton frame_sp = thread_sp->GetSelectedFrame (); 925*b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 926af67cecdSGreg Clayton } 927f028a1fbSGreg Clayton 928f028a1fbSGreg Clayton if (log) 929f028a1fbSGreg Clayton { 930481cef25SGreg Clayton SBStream frame_desc_strm; 931481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 932f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 933*b9556accSGreg Clayton thread_sp.get(), frame_sp.get(), frame_desc_strm.GetData()); 934f028a1fbSGreg Clayton } 935f028a1fbSGreg Clayton 936f028a1fbSGreg Clayton return sb_frame; 937f028a1fbSGreg Clayton } 938f028a1fbSGreg Clayton 939f028a1fbSGreg Clayton lldb::SBFrame 940f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx) 941f028a1fbSGreg Clayton { 942f028a1fbSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 943f028a1fbSGreg Clayton 944f028a1fbSGreg Clayton SBFrame sb_frame; 945*b9556accSGreg Clayton StackFrameSP frame_sp; 94617a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 94717a6ad05SGreg Clayton if (thread_sp) 948f028a1fbSGreg Clayton { 94917a6ad05SGreg Clayton Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 950*b9556accSGreg Clayton frame_sp = thread_sp->GetStackFrameAtIndex (idx); 951f028a1fbSGreg Clayton if (frame_sp) 952f028a1fbSGreg Clayton { 95317a6ad05SGreg Clayton thread_sp->SetSelectedFrame (frame_sp.get()); 954*b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 955f028a1fbSGreg Clayton } 956f028a1fbSGreg Clayton } 957f028a1fbSGreg Clayton 958f028a1fbSGreg Clayton if (log) 959f028a1fbSGreg Clayton { 960481cef25SGreg Clayton SBStream frame_desc_strm; 961481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 962f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 963*b9556accSGreg Clayton thread_sp.get(), idx, frame_sp.get(), frame_desc_strm.GetData()); 964f028a1fbSGreg Clayton } 965f028a1fbSGreg Clayton return sb_frame; 966f028a1fbSGreg Clayton } 967f028a1fbSGreg Clayton 968f028a1fbSGreg Clayton 96930fdc8d8SChris Lattner bool 97030fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const 97130fdc8d8SChris Lattner { 97217a6ad05SGreg Clayton return m_opaque_wp.lock().get() == rhs.m_opaque_wp.lock().get(); 97330fdc8d8SChris Lattner } 97430fdc8d8SChris Lattner 97530fdc8d8SChris Lattner bool 97630fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const 97730fdc8d8SChris Lattner { 97817a6ad05SGreg Clayton return m_opaque_wp.lock().get() != rhs.m_opaque_wp.lock().get(); 97930fdc8d8SChris Lattner } 980dde9cff3SCaroline Tice 981dde9cff3SCaroline Tice bool 982ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const 983ceb6b139SCaroline Tice { 984da7bc7d0SGreg Clayton Stream &strm = description.ref(); 985da7bc7d0SGreg Clayton 98617a6ad05SGreg Clayton ThreadSP thread_sp(m_opaque_wp.lock()); 98717a6ad05SGreg Clayton if (thread_sp) 988ceb6b139SCaroline Tice { 98917a6ad05SGreg Clayton strm.Printf("SBThread: tid = 0x%4.4llx", thread_sp->GetID()); 990ceb6b139SCaroline Tice } 991ceb6b139SCaroline Tice else 992da7bc7d0SGreg Clayton strm.PutCString ("No value"); 993ceb6b139SCaroline Tice 994ceb6b139SCaroline Tice return true; 995ceb6b139SCaroline Tice } 996