130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 94c5de699SEli Friedman #include "lldb/API/SBThread.h" 1030fdc8d8SChris Lattner 1130fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h" 12dde9cff3SCaroline Tice #include "lldb/API/SBStream.h" 13b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h" 144e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h" 156611103cSGreg Clayton #include "lldb/Core/Debugger.h" 1630fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h" 17a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h" 186611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 1993749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h" 20b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h" 2130fdc8d8SChris Lattner #include "lldb/Target/Process.h" 22b9ffa98cSJason Molenda #include "lldb/Target/Queue.h" 23f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 24b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h" 2530fdc8d8SChris Lattner #include "lldb/Target/Target.h" 26b9c1b51eSKate Stone #include "lldb/Target/Thread.h" 2730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 28b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h" 2930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 32b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h" 33d821c997SPavel Labath #include "lldb/Utility/State.h" 34bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 35f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h" 3630fdc8d8SChris Lattner 374c5de699SEli Friedman #include "lldb/API/SBAddress.h" 384c5de699SEli Friedman #include "lldb/API/SBDebugger.h" 394f465cffSJim Ingham #include "lldb/API/SBEvent.h" 4073ca05a2SJim Ingham #include "lldb/API/SBFrame.h" 414c5de699SEli Friedman #include "lldb/API/SBProcess.h" 426a831436SKuba Brecka #include "lldb/API/SBThreadCollection.h" 432bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h" 4473ca05a2SJim Ingham #include "lldb/API/SBValue.h" 455bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h" 4630fdc8d8SChris Lattner 4730fdc8d8SChris Lattner using namespace lldb; 4830fdc8d8SChris Lattner using namespace lldb_private; 4930fdc8d8SChris Lattner 50b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() { 514f465cffSJim Ingham return Thread::GetStaticBroadcasterClass().AsCString(); 524f465cffSJim Ingham } 534f465cffSJim Ingham 54cfd1acedSGreg Clayton //---------------------------------------------------------------------- 55cfd1acedSGreg Clayton // Constructors 56cfd1acedSGreg Clayton //---------------------------------------------------------------------- 57b9c1b51eSKate Stone SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {} 5830fdc8d8SChris Lattner 59b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp) 60b9c1b51eSKate Stone : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {} 6130fdc8d8SChris Lattner 62b9c1b51eSKate Stone SBThread::SBThread(const SBThread &rhs) 63b9c1b51eSKate Stone : m_opaque_sp(new ExecutionContextRef(*rhs.m_opaque_sp)) {} 6430fdc8d8SChris Lattner 6530fdc8d8SChris Lattner //---------------------------------------------------------------------- 66cfd1acedSGreg Clayton // Assignment operator 67cfd1acedSGreg Clayton //---------------------------------------------------------------------- 68cfd1acedSGreg Clayton 69b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) { 70cfd1acedSGreg Clayton if (this != &rhs) 717fdf9ef1SGreg Clayton *m_opaque_sp = *rhs.m_opaque_sp; 72cfd1acedSGreg Clayton return *this; 73cfd1acedSGreg Clayton } 74cfd1acedSGreg Clayton 75cfd1acedSGreg Clayton //---------------------------------------------------------------------- 7630fdc8d8SChris Lattner // Destructor 7730fdc8d8SChris Lattner //---------------------------------------------------------------------- 78b9c1b51eSKate Stone SBThread::~SBThread() {} 7930fdc8d8SChris Lattner 80b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const { 81b9ffa98cSJason Molenda SBQueue sb_queue; 82b9ffa98cSJason Molenda QueueSP queue_sp; 83bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 84bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 85b9ffa98cSJason Molenda 86b9ffa98cSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 87b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 88b9ffa98cSJason Molenda Process::StopLocker stop_locker; 89b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 90b9ffa98cSJason Molenda queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); 91b9c1b51eSKate Stone if (queue_sp) { 92b9ffa98cSJason Molenda sb_queue.SetQueue(queue_sp); 93b9ffa98cSJason Molenda } 94b9c1b51eSKate Stone } else { 95b9ffa98cSJason Molenda if (log) 96358cf1eaSGreg Clayton log->Printf("SBThread(%p)::GetQueue() => error: process is running", 97b9ffa98cSJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr())); 98b9ffa98cSJason Molenda } 99b9ffa98cSJason Molenda } 100b9ffa98cSJason Molenda 101b9ffa98cSJason Molenda if (log) 102358cf1eaSGreg Clayton log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)", 103b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), 104b9c1b51eSKate Stone static_cast<void *>(queue_sp.get())); 105b9ffa98cSJason Molenda 106b9ffa98cSJason Molenda return sb_queue; 107b9ffa98cSJason Molenda } 108b9ffa98cSJason Molenda 109b9c1b51eSKate Stone bool SBThread::IsValid() const { 110bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 111bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1127fa7dc36SJim Ingham 1137fa7dc36SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 1147fa7dc36SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 115b9c1b51eSKate Stone if (target && process) { 1167fa7dc36SJim Ingham Process::StopLocker stop_locker; 1177fa7dc36SJim Ingham if (stop_locker.TryLock(&process->GetRunLock())) 1187fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != NULL; 11930fdc8d8SChris Lattner } 1207fa7dc36SJim Ingham // Without a valid target & process, this thread can't be valid. 1217fa7dc36SJim Ingham return false; 1227fa7dc36SJim Ingham } 12330fdc8d8SChris Lattner 124b9c1b51eSKate Stone void SBThread::Clear() { m_opaque_sp->Clear(); } 12548e42549SGreg Clayton 126b9c1b51eSKate Stone StopReason SBThread::GetStopReason() { 1275160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 128ceb6b139SCaroline Tice 129ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 130bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 131bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1324fc6cb9cSJim Ingham 133b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1347fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 135b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13697d5cf05SGreg Clayton return exe_ctx.GetThreadPtr()->GetStopReason(); 137b9c1b51eSKate Stone } else { 138c9858e4dSGreg Clayton if (log) 139b9c1b51eSKate Stone log->Printf( 140b9c1b51eSKate Stone "SBThread(%p)::GetStopReason() => error: process is running", 141324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 142c9858e4dSGreg Clayton } 1437fdf9ef1SGreg Clayton } 144ceb6b139SCaroline Tice 145ceb6b139SCaroline Tice if (log) 146324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetStopReason () => %s", 147324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 148750cd175SCaroline Tice Thread::StopReasonAsCString(reason)); 149ceb6b139SCaroline Tice 150ceb6b139SCaroline Tice return reason; 15130fdc8d8SChris Lattner } 15230fdc8d8SChris Lattner 153b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() { 154bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 155bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1564fc6cb9cSJim Ingham 157b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1587fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 159b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1601ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 161b9c1b51eSKate Stone if (stop_info_sp) { 1624e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 163b9c1b51eSKate Stone switch (reason) { 1644e78f606SGreg Clayton case eStopReasonInvalid: 1654e78f606SGreg Clayton case eStopReasonNone: 1664e78f606SGreg Clayton case eStopReasonTrace: 16790ba8115SGreg Clayton case eStopReasonExec: 1684e78f606SGreg Clayton case eStopReasonPlanComplete: 169f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 170afdf842bSKuba Brecka case eStopReasonInstrumentation: 1714e78f606SGreg Clayton // There is no data for these stop reasons. 1724e78f606SGreg Clayton return 0; 1734e78f606SGreg Clayton 174b9c1b51eSKate Stone case eStopReasonBreakpoint: { 1754e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 176b9c1b51eSKate Stone lldb::BreakpointSiteSP bp_site_sp( 177b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 178b9c1b51eSKate Stone site_id)); 1794e78f606SGreg Clayton if (bp_site_sp) 1804e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners() * 2; 1814e78f606SGreg Clayton else 1824e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 183b9c1b51eSKate Stone } break; 1844e78f606SGreg Clayton 1854e78f606SGreg Clayton case eStopReasonWatchpoint: 186290fa41bSJohnny Chen return 1; 1874e78f606SGreg Clayton 1884e78f606SGreg Clayton case eStopReasonSignal: 1894e78f606SGreg Clayton return 1; 1904e78f606SGreg Clayton 1914e78f606SGreg Clayton case eStopReasonException: 1924e78f606SGreg Clayton return 1; 1934e78f606SGreg Clayton } 1944e78f606SGreg Clayton } 195b9c1b51eSKate Stone } else { 1965160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 197c9858e4dSGreg Clayton if (log) 198b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process " 199b9c1b51eSKate Stone "is running", 200324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 201c9858e4dSGreg Clayton } 2027fdf9ef1SGreg Clayton } 2034e78f606SGreg Clayton return 0; 2044e78f606SGreg Clayton } 2054e78f606SGreg Clayton 206b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) { 207bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 208bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 2094fc6cb9cSJim Ingham 210b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 2117fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 212b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 2131ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 2141ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo(); 215b9c1b51eSKate Stone if (stop_info_sp) { 2164e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 217b9c1b51eSKate Stone switch (reason) { 2184e78f606SGreg Clayton case eStopReasonInvalid: 2194e78f606SGreg Clayton case eStopReasonNone: 2204e78f606SGreg Clayton case eStopReasonTrace: 22190ba8115SGreg Clayton case eStopReasonExec: 2224e78f606SGreg Clayton case eStopReasonPlanComplete: 223f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 224afdf842bSKuba Brecka case eStopReasonInstrumentation: 2254e78f606SGreg Clayton // There is no data for these stop reasons. 2264e78f606SGreg Clayton return 0; 2274e78f606SGreg Clayton 228b9c1b51eSKate Stone case eStopReasonBreakpoint: { 2294e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 230b9c1b51eSKate Stone lldb::BreakpointSiteSP bp_site_sp( 231b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 232b9c1b51eSKate Stone site_id)); 233b9c1b51eSKate Stone if (bp_site_sp) { 2344e78f606SGreg Clayton uint32_t bp_index = idx / 2; 235b9c1b51eSKate Stone BreakpointLocationSP bp_loc_sp( 236b9c1b51eSKate Stone bp_site_sp->GetOwnerAtIndex(bp_index)); 237b9c1b51eSKate Stone if (bp_loc_sp) { 238b9c1b51eSKate Stone if (idx & 1) { 2394e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2404e78f606SGreg Clayton return bp_loc_sp->GetID(); 241b9c1b51eSKate Stone } else { 2424e78f606SGreg Clayton // Even idx, return the breakpoint ID 2434e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2444e78f606SGreg Clayton } 2454e78f606SGreg Clayton } 2464e78f606SGreg Clayton } 2474e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 248b9c1b51eSKate Stone } break; 2494e78f606SGreg Clayton 2504e78f606SGreg Clayton case eStopReasonWatchpoint: 251290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2524e78f606SGreg Clayton 2534e78f606SGreg Clayton case eStopReasonSignal: 2544e78f606SGreg Clayton return stop_info_sp->GetValue(); 2554e78f606SGreg Clayton 2564e78f606SGreg Clayton case eStopReasonException: 2574e78f606SGreg Clayton return stop_info_sp->GetValue(); 2584e78f606SGreg Clayton } 2594e78f606SGreg Clayton } 260b9c1b51eSKate Stone } else { 2615160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 262c9858e4dSGreg Clayton if (log) 263b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: " 264b9c1b51eSKate Stone "process is running", 265324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 266c9858e4dSGreg Clayton } 2677fdf9ef1SGreg Clayton } 2684e78f606SGreg Clayton return 0; 2694e78f606SGreg Clayton } 2704e78f606SGreg Clayton 271b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) { 272afdf842bSKuba Brecka Stream &strm = stream.ref(); 273afdf842bSKuba Brecka 274b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 275b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 276b2e7d28eSJim Ingham 277afdf842bSKuba Brecka if (!exe_ctx.HasThreadScope()) 278afdf842bSKuba Brecka return false; 279afdf842bSKuba Brecka 280afdf842bSKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 281afdf842bSKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 282afdf842bSKuba Brecka if (!info) 283afdf842bSKuba Brecka return false; 284afdf842bSKuba Brecka 285afdf842bSKuba Brecka info->Dump(strm); 286afdf842bSKuba Brecka 287afdf842bSKuba Brecka return true; 288afdf842bSKuba Brecka } 289afdf842bSKuba Brecka 2906a831436SKuba Brecka SBThreadCollection 291b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) { 2926a831436SKuba Brecka ThreadCollectionSP threads; 2936a831436SKuba Brecka threads.reset(new ThreadCollection()); 2946a831436SKuba Brecka 295b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 296b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 297b2e7d28eSJim Ingham 2986a831436SKuba Brecka if (!exe_ctx.HasThreadScope()) 2991aad8fb7SKuba Brecka return threads; 3006a831436SKuba Brecka 3016a831436SKuba Brecka ProcessSP process_sp = exe_ctx.GetProcessSP(); 3026a831436SKuba Brecka 3036a831436SKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 3046a831436SKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 3056a831436SKuba Brecka if (!info) 3066a831436SKuba Brecka return threads; 3076a831436SKuba Brecka 308b9c1b51eSKate Stone return process_sp->GetInstrumentationRuntime(type) 309b9c1b51eSKate Stone ->GetBacktracesFromExtendedStopInfo(info); 3106a831436SKuba Brecka } 3116a831436SKuba Brecka 312b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) { 3135160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 314ceb6b139SCaroline Tice 315bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 316bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 3174fc6cb9cSJim Ingham 318b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 3197fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 320b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 3217fdf9ef1SGreg Clayton 3221ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 323b9c1b51eSKate Stone if (stop_info_sp) { 324b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 325b9c1b51eSKate Stone if (stop_desc) { 326ceb6b139SCaroline Tice if (log) 327b9c1b51eSKate Stone log->Printf( 328b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 329b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc); 33030fdc8d8SChris Lattner if (dst) 33130fdc8d8SChris Lattner return ::snprintf(dst, dst_len, "%s", stop_desc); 332b9c1b51eSKate Stone else { 333b9c1b51eSKate Stone // NULL dst passed in, return the length needed to contain the 334b9c1b51eSKate Stone // description 33530fdc8d8SChris Lattner return ::strlen(stop_desc) + 1; // Include the NULL byte for size 33630fdc8d8SChris Lattner } 337b9c1b51eSKate Stone } else { 33830fdc8d8SChris Lattner size_t stop_desc_len = 0; 339b9c1b51eSKate Stone switch (stop_info_sp->GetStopReason()) { 34030fdc8d8SChris Lattner case eStopReasonTrace: 341b9c1b51eSKate Stone case eStopReasonPlanComplete: { 34230fdc8d8SChris Lattner static char trace_desc[] = "step"; 34330fdc8d8SChris Lattner stop_desc = trace_desc; 344b9c1b51eSKate Stone stop_desc_len = 345b9c1b51eSKate Stone sizeof(trace_desc); // Include the NULL byte for size 346b9c1b51eSKate Stone } break; 34730fdc8d8SChris Lattner 348b9c1b51eSKate Stone case eStopReasonBreakpoint: { 34930fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 35030fdc8d8SChris Lattner stop_desc = bp_desc; 35130fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 352b9c1b51eSKate Stone } break; 35330fdc8d8SChris Lattner 354b9c1b51eSKate Stone case eStopReasonWatchpoint: { 35530fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 35630fdc8d8SChris Lattner stop_desc = wp_desc; 35730fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 358b9c1b51eSKate Stone } break; 35930fdc8d8SChris Lattner 360b9c1b51eSKate Stone case eStopReasonSignal: { 361b9c1b51eSKate Stone stop_desc = 362b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString( 363b9c1b51eSKate Stone stop_info_sp->GetValue()); 364b9c1b51eSKate Stone if (stop_desc == NULL || stop_desc[0] == '\0') { 36530fdc8d8SChris Lattner static char signal_desc[] = "signal"; 36630fdc8d8SChris Lattner stop_desc = signal_desc; 367b9c1b51eSKate Stone stop_desc_len = 368b9c1b51eSKate Stone sizeof(signal_desc); // Include the NULL byte for size 36930fdc8d8SChris Lattner } 370b9c1b51eSKate Stone } break; 37130fdc8d8SChris Lattner 372b9c1b51eSKate Stone case eStopReasonException: { 37330fdc8d8SChris Lattner char exc_desc[] = "exception"; 37430fdc8d8SChris Lattner stop_desc = exc_desc; 37530fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 376b9c1b51eSKate Stone } break; 377c982c768SGreg Clayton 378b9c1b51eSKate Stone case eStopReasonExec: { 37990ba8115SGreg Clayton char exc_desc[] = "exec"; 38090ba8115SGreg Clayton stop_desc = exc_desc; 38190ba8115SGreg Clayton stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 382b9c1b51eSKate Stone } break; 38390ba8115SGreg Clayton 384b9c1b51eSKate Stone case eStopReasonThreadExiting: { 385f85defaeSAndrew Kaylor char limbo_desc[] = "thread exiting"; 386f85defaeSAndrew Kaylor stop_desc = limbo_desc; 387f85defaeSAndrew Kaylor stop_desc_len = sizeof(limbo_desc); 388b9c1b51eSKate Stone } break; 389c982c768SGreg Clayton default: 390c982c768SGreg Clayton break; 39130fdc8d8SChris Lattner } 39230fdc8d8SChris Lattner 393b9c1b51eSKate Stone if (stop_desc && stop_desc[0]) { 394ceb6b139SCaroline Tice if (log) 395b9c1b51eSKate Stone log->Printf( 396b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 397b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc); 398ceb6b139SCaroline Tice 39930fdc8d8SChris Lattner if (dst) 400b9c1b51eSKate Stone return ::snprintf(dst, dst_len, "%s", stop_desc) + 401b9c1b51eSKate Stone 1; // Include the NULL byte 40230fdc8d8SChris Lattner 40330fdc8d8SChris Lattner if (stop_desc_len == 0) 40430fdc8d8SChris Lattner stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte 40530fdc8d8SChris Lattner 40630fdc8d8SChris Lattner return stop_desc_len; 40730fdc8d8SChris Lattner } 40830fdc8d8SChris Lattner } 40930fdc8d8SChris Lattner } 410b9c1b51eSKate Stone } else { 4115160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 412c9858e4dSGreg Clayton if (log) 413b9c1b51eSKate Stone log->Printf( 414b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription() => error: process is running", 415324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 416c9858e4dSGreg Clayton } 4177fdf9ef1SGreg Clayton } 41830fdc8d8SChris Lattner if (dst) 41930fdc8d8SChris Lattner *dst = 0; 42030fdc8d8SChris Lattner return 0; 42130fdc8d8SChris Lattner } 42230fdc8d8SChris Lattner 423b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() { 4245160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 42573ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 426bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 427bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4284fc6cb9cSJim Ingham 429b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 4307fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 431b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4321ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 433b9c1b51eSKate Stone if (stop_info_sp) { 43473ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp); 43573ca05a2SJim Ingham } 436b9c1b51eSKate Stone } else { 437c9858e4dSGreg Clayton if (log) 438b9c1b51eSKate Stone log->Printf( 439b9c1b51eSKate Stone "SBThread(%p)::GetStopReturnValue() => error: process is running", 440324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 441c9858e4dSGreg Clayton } 4427fdf9ef1SGreg Clayton } 44373ca05a2SJim Ingham 44473ca05a2SJim Ingham if (log) 445324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetStopReturnValue () => %s", 446324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 447b9c1b51eSKate Stone return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString() 44873ca05a2SJim Ingham : "<no return value>"); 44973ca05a2SJim Ingham 45073ca05a2SJim Ingham return SBValue(return_valobj_sp); 45173ca05a2SJim Ingham } 45273ca05a2SJim Ingham 453b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) { 4547fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP(lldb_object_sp); 45530fdc8d8SChris Lattner } 45630fdc8d8SChris Lattner 457b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const { 4587fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 45917a6ad05SGreg Clayton if (thread_sp) 4601ac04c30SGreg Clayton return thread_sp->GetID(); 4611ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 46230fdc8d8SChris Lattner } 46330fdc8d8SChris Lattner 464b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const { 4657fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 46617a6ad05SGreg Clayton if (thread_sp) 46717a6ad05SGreg Clayton return thread_sp->GetIndexID(); 46830fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 46930fdc8d8SChris Lattner } 4701ac04c30SGreg Clayton 471b9c1b51eSKate Stone const char *SBThread::GetName() const { 4725160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 4734838131bSGreg Clayton const char *name = NULL; 474bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 475bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4764fc6cb9cSJim Ingham 477b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 4787fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 479b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4801ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 481b9c1b51eSKate Stone } else { 482c9858e4dSGreg Clayton if (log) 483324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetName() => error: process is running", 484324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 485c9858e4dSGreg Clayton } 4867fdf9ef1SGreg Clayton } 487ceb6b139SCaroline Tice 488ceb6b139SCaroline Tice if (log) 489324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetName () => %s", 490324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 491324a1036SSaleem Abdulrasool name ? name : "NULL"); 492ceb6b139SCaroline Tice 4934838131bSGreg Clayton return name; 49430fdc8d8SChris Lattner } 49530fdc8d8SChris Lattner 496b9c1b51eSKate Stone const char *SBThread::GetQueueName() const { 4974838131bSGreg Clayton const char *name = NULL; 498bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 499bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5004fc6cb9cSJim Ingham 5015160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 502b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 5037fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 504b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 5051ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 506b9c1b51eSKate Stone } else { 507c9858e4dSGreg Clayton if (log) 508324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueName() => error: process is running", 509324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 510c9858e4dSGreg Clayton } 5117fdf9ef1SGreg Clayton } 512ceb6b139SCaroline Tice 513ceb6b139SCaroline Tice if (log) 514324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueName () => %s", 515324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 516324a1036SSaleem Abdulrasool name ? name : "NULL"); 517ceb6b139SCaroline Tice 5184838131bSGreg Clayton return name; 51930fdc8d8SChris Lattner } 52030fdc8d8SChris Lattner 521b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const { 5224fdb5863SJason Molenda queue_id_t id = LLDB_INVALID_QUEUE_ID; 523bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 524bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5254fdb5863SJason Molenda 5264fdb5863SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 527b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 5284fdb5863SJason Molenda Process::StopLocker stop_locker; 529b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 5304fdb5863SJason Molenda id = exe_ctx.GetThreadPtr()->GetQueueID(); 531b9c1b51eSKate Stone } else { 5324fdb5863SJason Molenda if (log) 533324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueID() => error: process is running", 534324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 5354fdb5863SJason Molenda } 5364fdb5863SJason Molenda } 5374fdb5863SJason Molenda 5384fdb5863SJason Molenda if (log) 539324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64, 540324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), id); 5414fdb5863SJason Molenda 5424fdb5863SJason Molenda return id; 5434fdb5863SJason Molenda } 5444fdb5863SJason Molenda 545b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { 546705b1809SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 547705b1809SJason Molenda bool success = false; 548bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 549bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 550705b1809SJason Molenda 551b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 552705b1809SJason Molenda Process::StopLocker stop_locker; 553b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 554705b1809SJason Molenda Thread *thread = exe_ctx.GetThreadPtr(); 555705b1809SJason Molenda StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); 556b9c1b51eSKate Stone if (info_root_sp) { 557b9c1b51eSKate Stone StructuredData::ObjectSP node = 558b9c1b51eSKate Stone info_root_sp->GetObjectForDotSeparatedPath(path); 559b9c1b51eSKate Stone if (node) { 5605bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeString) { 5612833321fSZachary Turner strm.Printf("%s", node->GetAsString()->GetValue().str().c_str()); 562705b1809SJason Molenda success = true; 563705b1809SJason Molenda } 5645bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeInteger) { 565705b1809SJason Molenda strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue()); 566705b1809SJason Molenda success = true; 567705b1809SJason Molenda } 5685bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeFloat) { 569705b1809SJason Molenda strm.Printf("0x%f", node->GetAsFloat()->GetValue()); 570705b1809SJason Molenda success = true; 571705b1809SJason Molenda } 5725bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeBoolean) { 573a6682a41SJonas Devlieghere if (node->GetAsBoolean()->GetValue()) 574705b1809SJason Molenda strm.Printf("true"); 575705b1809SJason Molenda else 576705b1809SJason Molenda strm.Printf("false"); 577705b1809SJason Molenda success = true; 578705b1809SJason Molenda } 5795bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeNull) { 580705b1809SJason Molenda strm.Printf("null"); 581705b1809SJason Molenda success = true; 582705b1809SJason Molenda } 583705b1809SJason Molenda } 584705b1809SJason Molenda } 585b9c1b51eSKate Stone } else { 586705b1809SJason Molenda if (log) 587b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: " 588b9c1b51eSKate Stone "process is running", 589705b1809SJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr())); 590705b1809SJason Molenda } 591705b1809SJason Molenda } 592705b1809SJason Molenda 593705b1809SJason Molenda if (log) 594753e13c0SJason Molenda log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"", 595753e13c0SJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData()); 596705b1809SJason Molenda 597705b1809SJason Molenda return success; 598705b1809SJason Molenda } 599705b1809SJason Molenda 600b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx, 601b9c1b51eSKate Stone ThreadPlan *new_plan) { 60264e7ead1SJim Ingham SBError sb_error; 60364e7ead1SJim Ingham 60464e7ead1SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 605b9c1b51eSKate Stone if (!process) { 60664e7ead1SJim Ingham sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 60764e7ead1SJim Ingham return sb_error; 60864e7ead1SJim Ingham } 60964e7ead1SJim Ingham 61064e7ead1SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 611b9c1b51eSKate Stone if (!thread) { 61264e7ead1SJim Ingham sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 61364e7ead1SJim Ingham return sb_error; 61464e7ead1SJim Ingham } 61564e7ead1SJim Ingham 616b9c1b51eSKate Stone // User level plans should be Master Plans so they can be interrupted, other 61705097246SAdrian Prantl // plans executed, and then a "continue" will resume the plan. 618b9c1b51eSKate Stone if (new_plan != NULL) { 61964e7ead1SJim Ingham new_plan->SetIsMasterPlan(true); 62064e7ead1SJim Ingham new_plan->SetOkayToDiscard(false); 62164e7ead1SJim Ingham } 62264e7ead1SJim Ingham 62364e7ead1SJim Ingham // Why do we need to set the current thread by ID here??? 62464e7ead1SJim Ingham process->GetThreadList().SetSelectedThreadByID(thread->GetID()); 62564e7ead1SJim Ingham 626dc6224e0SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution()) 627dc6224e0SGreg Clayton sb_error.ref() = process->Resume(); 628dc6224e0SGreg Clayton else 629dc6224e0SGreg Clayton sb_error.ref() = process->ResumeSynchronous(NULL); 63064e7ead1SJim Ingham 63164e7ead1SJim Ingham return sb_error; 63264e7ead1SJim Ingham } 63330fdc8d8SChris Lattner 634b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) { 635859f54b3SAlexander Polyakov SBError error; // Ignored 636859f54b3SAlexander Polyakov StepOver(stop_other_threads, error); 637859f54b3SAlexander Polyakov } 638859f54b3SAlexander Polyakov 639859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { 6405160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 641ceb6b139SCaroline Tice 642bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 643bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 64417a6ad05SGreg Clayton 645ceb6b139SCaroline Tice if (log) 646324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')", 647324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 648ceb6b139SCaroline Tice Thread::RunModeAsCString(stop_other_threads)); 649ceb6b139SCaroline Tice 650859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 651859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 652859f54b3SAlexander Polyakov return; 653859f54b3SAlexander Polyakov } 654859f54b3SAlexander Polyakov 6551ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 6567ba6e991SJim Ingham bool abort_other_plans = false; 657b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 65830fdc8d8SChris Lattner 659e103ae92SJonas Devlieghere Status new_plan_status; 6604d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 661b9c1b51eSKate Stone if (frame_sp) { 662b9c1b51eSKate Stone if (frame_sp->HasDebugInformation()) { 6634b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 66430fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 665b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepOverRange( 666b9c1b51eSKate Stone abort_other_plans, sc.line_entry, sc, stop_other_threads, 667e103ae92SJonas Devlieghere new_plan_status, avoid_no_debug); 668b9c1b51eSKate Stone } else { 669b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 670e103ae92SJonas Devlieghere true, abort_other_plans, stop_other_threads, new_plan_status); 67130fdc8d8SChris Lattner } 67230fdc8d8SChris Lattner } 673859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 67430fdc8d8SChris Lattner } 67530fdc8d8SChris Lattner 676b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) { 677c627682eSJim Ingham StepInto(NULL, stop_other_threads); 678c627682eSJim Ingham } 679c627682eSJim Ingham 680b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, 681b9c1b51eSKate Stone lldb::RunMode stop_other_threads) { 682859f54b3SAlexander Polyakov SBError error; // Ignored 683cbf6f9b2SJim Ingham StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads); 684cbf6f9b2SJim Ingham } 685cbf6f9b2SJim Ingham 686b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line, 687b9c1b51eSKate Stone SBError &error, lldb::RunMode stop_other_threads) { 6885160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 689ceb6b139SCaroline Tice 690bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 691bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 69217a6ad05SGreg Clayton 69317a6ad05SGreg Clayton if (log) 694b9c1b51eSKate Stone log->Printf( 695b9c1b51eSKate Stone "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 696324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 697c627682eSJim Ingham target_name ? target_name : "<NULL>", 69817a6ad05SGreg Clayton Thread::RunModeAsCString(stop_other_threads)); 699c627682eSJim Ingham 700859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 701859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 702859f54b3SAlexander Polyakov return; 703859f54b3SAlexander Polyakov } 704859f54b3SAlexander Polyakov 7057ba6e991SJim Ingham bool abort_other_plans = false; 70630fdc8d8SChris Lattner 7071ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 708b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 7094d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 710e103ae92SJonas Devlieghere Status new_plan_status; 71130fdc8d8SChris Lattner 712b9c1b51eSKate Stone if (frame_sp && frame_sp->HasDebugInformation()) { 713cbf6f9b2SJim Ingham SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 714cbf6f9b2SJim Ingham AddressRange range; 715cbf6f9b2SJim Ingham if (end_line == LLDB_INVALID_LINE_NUMBER) 716cbf6f9b2SJim Ingham range = sc.line_entry.range; 717b9c1b51eSKate Stone else { 718cbf6f9b2SJim Ingham if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref())) 719cbf6f9b2SJim Ingham return; 720cbf6f9b2SJim Ingham } 721cbf6f9b2SJim Ingham 722b9c1b51eSKate Stone const LazyBool step_out_avoids_code_without_debug_info = 723b9c1b51eSKate Stone eLazyBoolCalculate; 724b9c1b51eSKate Stone const LazyBool step_in_avoids_code_without_debug_info = 725b9c1b51eSKate Stone eLazyBoolCalculate; 726b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepInRange( 727b9c1b51eSKate Stone abort_other_plans, range, sc, target_name, stop_other_threads, 728e103ae92SJonas Devlieghere new_plan_status, step_in_avoids_code_without_debug_info, 7294b4b2478SJim Ingham step_out_avoids_code_without_debug_info); 730b9c1b51eSKate Stone } else { 731b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 732e103ae92SJonas Devlieghere false, abort_other_plans, stop_other_threads, new_plan_status); 73330fdc8d8SChris Lattner } 734e103ae92SJonas Devlieghere 735e103ae92SJonas Devlieghere if (new_plan_status.Success()) 736cbf6f9b2SJim Ingham error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 737e103ae92SJonas Devlieghere else 738e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 73930fdc8d8SChris Lattner } 74030fdc8d8SChris Lattner 741b9c1b51eSKate Stone void SBThread::StepOut() { 742859f54b3SAlexander Polyakov SBError error; // Ignored 743859f54b3SAlexander Polyakov StepOut(error); 744859f54b3SAlexander Polyakov } 745859f54b3SAlexander Polyakov 746859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) { 7475160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 748ceb6b139SCaroline Tice 749bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 750bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7514fc6cb9cSJim Ingham 75217a6ad05SGreg Clayton if (log) 753324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOut ()", 754324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 75517a6ad05SGreg Clayton 756859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 757859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 758859f54b3SAlexander Polyakov return; 759859f54b3SAlexander Polyakov } 760859f54b3SAlexander Polyakov 7617ba6e991SJim Ingham bool abort_other_plans = false; 76294b09246SJim Ingham bool stop_other_threads = false; 76330fdc8d8SChris Lattner 7641ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7651ac04c30SGreg Clayton 7664b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 767e103ae92SJonas Devlieghere Status new_plan_status; 768b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 769b9c1b51eSKate Stone abort_other_plans, NULL, false, stop_other_threads, eVoteYes, 770e103ae92SJonas Devlieghere eVoteNoOpinion, 0, new_plan_status, avoid_no_debug)); 771481cef25SGreg Clayton 772e103ae92SJonas Devlieghere if (new_plan_status.Success()) 773859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 774e103ae92SJonas Devlieghere else 775e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 776481cef25SGreg Clayton } 777481cef25SGreg Clayton 778859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) { 779859f54b3SAlexander Polyakov SBError error; // Ignored 780859f54b3SAlexander Polyakov StepOutOfFrame(sb_frame, error); 781859f54b3SAlexander Polyakov } 782859f54b3SAlexander Polyakov 783859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) { 7845160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 785481cef25SGreg Clayton 786bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 787bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7884fc6cb9cSJim Ingham 789b9c1b51eSKate Stone if (!sb_frame.IsValid()) { 790989a7558SJim Ingham if (log) 791b9c1b51eSKate Stone log->Printf( 792b9c1b51eSKate Stone "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.", 793989a7558SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr())); 794859f54b3SAlexander Polyakov error.SetErrorString("passed invalid SBFrame object"); 795989a7558SJim Ingham return; 796989a7558SJim Ingham } 797989a7558SJim Ingham 798b57e4a1bSJason Molenda StackFrameSP frame_sp(sb_frame.GetFrameSP()); 799b9c1b51eSKate Stone if (log) { 800481cef25SGreg Clayton SBStream frame_desc_strm; 801481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 802324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", 803324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 804b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 805481cef25SGreg Clayton } 806481cef25SGreg Clayton 807859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 808859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 809859f54b3SAlexander Polyakov return; 810859f54b3SAlexander Polyakov } 811859f54b3SAlexander Polyakov 8127ba6e991SJim Ingham bool abort_other_plans = false; 81394b09246SJim Ingham bool stop_other_threads = false; 8141ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 815b9c1b51eSKate Stone if (sb_frame.GetThread().GetThreadID() != thread->GetID()) { 816b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another " 817b9c1b51eSKate Stone "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.", 818989a7558SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr()), 819b9c1b51eSKate Stone sb_frame.GetThread().GetThreadID(), thread->GetID()); 820859f54b3SAlexander Polyakov error.SetErrorString("passed a frame from another thread"); 821859f54b3SAlexander Polyakov return; 822989a7558SJim Ingham } 823481cef25SGreg Clayton 824e103ae92SJonas Devlieghere Status new_plan_status; 825b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 826b9c1b51eSKate Stone abort_other_plans, NULL, false, stop_other_threads, eVoteYes, 827e103ae92SJonas Devlieghere eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status)); 82830fdc8d8SChris Lattner 829e103ae92SJonas Devlieghere if (new_plan_status.Success()) 830859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 831e103ae92SJonas Devlieghere else 832e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 83330fdc8d8SChris Lattner } 83430fdc8d8SChris Lattner 835b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) { 836859f54b3SAlexander Polyakov SBError error; // Ignored 837859f54b3SAlexander Polyakov StepInstruction(step_over, error); 838859f54b3SAlexander Polyakov } 839859f54b3SAlexander Polyakov 840859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) { 8415160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 842ceb6b139SCaroline Tice 843bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 844bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 845ceb6b139SCaroline Tice 84617a6ad05SGreg Clayton if (log) 847324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepInstruction (step_over=%i)", 848324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), step_over); 84917a6ad05SGreg Clayton 850859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 851859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 852859f54b3SAlexander Polyakov return; 853859f54b3SAlexander Polyakov } 854859f54b3SAlexander Polyakov 8551ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 856e103ae92SJonas Devlieghere Status new_plan_status; 857e103ae92SJonas Devlieghere ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction( 858e103ae92SJonas Devlieghere step_over, true, true, new_plan_status)); 85964e7ead1SJim Ingham 860e103ae92SJonas Devlieghere if (new_plan_status.Success()) 861859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 862e103ae92SJonas Devlieghere else 863e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 86430fdc8d8SChris Lattner } 86530fdc8d8SChris Lattner 866b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) { 867859f54b3SAlexander Polyakov SBError error; // Ignored 868859f54b3SAlexander Polyakov RunToAddress(addr, error); 869859f54b3SAlexander Polyakov } 870859f54b3SAlexander Polyakov 871859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) { 8725160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 873ceb6b139SCaroline Tice 874bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 875bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 876ceb6b139SCaroline Tice 87717a6ad05SGreg Clayton if (log) 878324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", 879324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), addr); 88017a6ad05SGreg Clayton 881859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 882859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 883859f54b3SAlexander Polyakov return; 884859f54b3SAlexander Polyakov } 885859f54b3SAlexander Polyakov 8867ba6e991SJim Ingham bool abort_other_plans = false; 88730fdc8d8SChris Lattner bool stop_other_threads = true; 88830fdc8d8SChris Lattner 889e72dfb32SGreg Clayton Address target_addr(addr); 89030fdc8d8SChris Lattner 8911ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 8921ac04c30SGreg Clayton 893e103ae92SJonas Devlieghere Status new_plan_status; 894b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress( 895e103ae92SJonas Devlieghere abort_other_plans, target_addr, stop_other_threads, new_plan_status)); 89664e7ead1SJim Ingham 897e103ae92SJonas Devlieghere if (new_plan_status.Success()) 898859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 899e103ae92SJonas Devlieghere else 900e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 90130fdc8d8SChris Lattner } 90230fdc8d8SChris Lattner 903b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, 904b9c1b51eSKate Stone lldb::SBFileSpec &sb_file_spec, uint32_t line) { 905481cef25SGreg Clayton SBError sb_error; 9065160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 907481cef25SGreg Clayton char path[PATH_MAX]; 908481cef25SGreg Clayton 909bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 910bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 9114fc6cb9cSJim Ingham 912b57e4a1bSJason Molenda StackFrameSP frame_sp(sb_frame.GetFrameSP()); 91317a6ad05SGreg Clayton 914b9c1b51eSKate Stone if (log) { 915481cef25SGreg Clayton SBStream frame_desc_strm; 916481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 917481cef25SGreg Clayton sb_file_spec->GetPath(path, sizeof(path)); 918b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, " 919b9c1b51eSKate Stone "file+line = %s:%u)", 920324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 921b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(), 922b9c1b51eSKate Stone path, line); 923481cef25SGreg Clayton } 924481cef25SGreg Clayton 925b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 9261ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 9271ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 928481cef25SGreg Clayton 929b9c1b51eSKate Stone if (line == 0) { 930481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 931481cef25SGreg Clayton return sb_error; 932481cef25SGreg Clayton } 933481cef25SGreg Clayton 934b9c1b51eSKate Stone if (!frame_sp) { 9351ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame(); 936481cef25SGreg Clayton if (!frame_sp) 9371ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex(0); 938481cef25SGreg Clayton } 939481cef25SGreg Clayton 940481cef25SGreg Clayton SymbolContext frame_sc; 941b9c1b51eSKate Stone if (!frame_sp) { 942481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 943481cef25SGreg Clayton return sb_error; 944481cef25SGreg Clayton } 945481cef25SGreg Clayton 946481cef25SGreg Clayton // If we have a frame, get its line 947b9c1b51eSKate Stone frame_sc = frame_sp->GetSymbolContext( 948b9c1b51eSKate Stone eSymbolContextCompUnit | eSymbolContextFunction | 949b9c1b51eSKate Stone eSymbolContextLineEntry | eSymbolContextSymbol); 950481cef25SGreg Clayton 951b9c1b51eSKate Stone if (frame_sc.comp_unit == NULL) { 952b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat( 953b9c1b51eSKate Stone "frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 954481cef25SGreg Clayton return sb_error; 955481cef25SGreg Clayton } 956481cef25SGreg Clayton 957481cef25SGreg Clayton FileSpec step_file_spec; 958b9c1b51eSKate Stone if (sb_file_spec.IsValid()) { 959481cef25SGreg Clayton // The file spec passed in was valid, so use it 960481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 961b9c1b51eSKate Stone } else { 962481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 963481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 964b9c1b51eSKate Stone else { 965481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 966481cef25SGreg Clayton return sb_error; 967481cef25SGreg Clayton } 968481cef25SGreg Clayton } 969481cef25SGreg Clayton 9709b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 9719b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 972b9c1b51eSKate Stone // function, and then if there are no addresses remaining, give an 97305097246SAdrian Prantl // appropriate error message. 9749b70ddb3SJim Ingham 9759b70ddb3SJim Ingham bool all_in_function = true; 9769b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 9779b70ddb3SJim Ingham 978481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 9797ba6e991SJim Ingham const bool abort_other_plans = false; 980c02e3344SJim Ingham const bool stop_other_threads = false; 981481cef25SGreg Clayton const bool check_inlines = true; 982481cef25SGreg Clayton const bool exact = false; 983481cef25SGreg Clayton 984481cef25SGreg Clayton SymbolContextList sc_list; 985b9c1b51eSKate Stone const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext( 986b9c1b51eSKate Stone step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry, 9879b70ddb3SJim Ingham sc_list); 988b9c1b51eSKate Stone if (num_matches > 0) { 989481cef25SGreg Clayton SymbolContext sc; 990b9c1b51eSKate Stone for (uint32_t i = 0; i < num_matches; ++i) { 991b9c1b51eSKate Stone if (sc_list.GetContextAtIndex(i, sc)) { 992b9c1b51eSKate Stone addr_t step_addr = 993b9c1b51eSKate Stone sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 994b9c1b51eSKate Stone if (step_addr != LLDB_INVALID_ADDRESS) { 9959b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 996481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 9979b70ddb3SJim Ingham else 9989b70ddb3SJim Ingham all_in_function = false; 999481cef25SGreg Clayton } 1000481cef25SGreg Clayton } 1001481cef25SGreg Clayton } 1002481cef25SGreg Clayton } 1003481cef25SGreg Clayton 1004b9c1b51eSKate Stone if (step_over_until_addrs.empty()) { 1005b9c1b51eSKate Stone if (all_in_function) { 1006481cef25SGreg Clayton step_file_spec.GetPath(path, sizeof(path)); 1007b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, 1008b9c1b51eSKate Stone line); 1009b9c1b51eSKate Stone } else 101086edbf41SGreg Clayton sb_error.SetErrorString("step until target not in current function"); 1011b9c1b51eSKate Stone } else { 1012e103ae92SJonas Devlieghere Status new_plan_status; 1013b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil( 1014b9c1b51eSKate Stone abort_other_plans, &step_over_until_addrs[0], 1015b9c1b51eSKate Stone step_over_until_addrs.size(), stop_other_threads, 1016e103ae92SJonas Devlieghere frame_sp->GetFrameIndex(), new_plan_status)); 1017481cef25SGreg Clayton 1018e103ae92SJonas Devlieghere if (new_plan_status.Success()) 10194d56e9c1SJim Ingham sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 1020e103ae92SJonas Devlieghere else 1021e103ae92SJonas Devlieghere sb_error.SetErrorString(new_plan_status.AsCString()); 1022481cef25SGreg Clayton } 1023b9c1b51eSKate Stone } else { 1024481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 1025481cef25SGreg Clayton } 1026481cef25SGreg Clayton return sb_error; 1027481cef25SGreg Clayton } 1028481cef25SGreg Clayton 1029b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { 1030000ca185SOleksiy Vyalov return StepUsingScriptedThreadPlan(script_class_name, true); 1031c915a7d2SJim Ingham } 1032c915a7d2SJim Ingham 1033b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, 1034b9c1b51eSKate Stone bool resume_immediately) { 10352bdbfd50SJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1036e103ae92SJonas Devlieghere SBError error; 10372bdbfd50SJim Ingham 1038bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1039bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10402bdbfd50SJim Ingham 1041b9c1b51eSKate Stone if (log) { 10422bdbfd50SJim Ingham log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s", 1043b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name); 10442bdbfd50SJim Ingham } 10452bdbfd50SJim Ingham 1046b9c1b51eSKate Stone if (!exe_ctx.HasThreadScope()) { 1047e103ae92SJonas Devlieghere error.SetErrorString("this SBThread object is invalid"); 1048e103ae92SJonas Devlieghere return error; 10492bdbfd50SJim Ingham } 10502bdbfd50SJim Ingham 10512bdbfd50SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 1052e103ae92SJonas Devlieghere Status new_plan_status; 1053e103ae92SJonas Devlieghere ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted( 1054e103ae92SJonas Devlieghere false, script_class_name, false, new_plan_status); 10552bdbfd50SJim Ingham 1056e103ae92SJonas Devlieghere if (new_plan_status.Fail()) { 1057e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 1058e103ae92SJonas Devlieghere return error; 1059c915a7d2SJim Ingham } 1060c915a7d2SJim Ingham 1061e103ae92SJonas Devlieghere if (!resume_immediately) 1062e103ae92SJonas Devlieghere return error; 1063c915a7d2SJim Ingham 1064e103ae92SJonas Devlieghere if (new_plan_status.Success()) 1065e103ae92SJonas Devlieghere error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 1066e103ae92SJonas Devlieghere else 1067e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 10682bdbfd50SJim Ingham 1069e103ae92SJonas Devlieghere return error; 10702bdbfd50SJim Ingham } 10712bdbfd50SJim Ingham 1072b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) { 1073f86248d9SRichard Mitton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1074f86248d9SRichard Mitton SBError sb_error; 1075f86248d9SRichard Mitton 1076bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1077bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1078f86248d9SRichard Mitton 1079f86248d9SRichard Mitton if (log) 1080324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)", 1081324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1082324a1036SSaleem Abdulrasool file_spec->GetPath().c_str(), line); 1083f86248d9SRichard Mitton 1084b9c1b51eSKate Stone if (!exe_ctx.HasThreadScope()) { 1085f86248d9SRichard Mitton sb_error.SetErrorString("this SBThread object is invalid"); 1086f86248d9SRichard Mitton return sb_error; 1087f86248d9SRichard Mitton } 1088f86248d9SRichard Mitton 1089f86248d9SRichard Mitton Thread *thread = exe_ctx.GetThreadPtr(); 1090f86248d9SRichard Mitton 109197206d57SZachary Turner Status err = thread->JumpToLine(file_spec.get(), line, true); 1092f86248d9SRichard Mitton sb_error.SetError(err); 1093f86248d9SRichard Mitton return sb_error; 1094f86248d9SRichard Mitton } 1095f86248d9SRichard Mitton 1096b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) { 10974413758cSJim Ingham SBError sb_error; 10984413758cSJim Ingham 10995160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 11004413758cSJim Ingham 1101bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1102bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11034413758cSJim Ingham 11044413758cSJim Ingham if (log) 1105324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)", 1106324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1107324a1036SSaleem Abdulrasool frame.GetFrameID()); 11084413758cSJim Ingham 1109b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 11104413758cSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 1111b9c1b51eSKate Stone sb_error.SetError( 1112b9c1b51eSKate Stone thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 11134413758cSJim Ingham } 11144413758cSJim Ingham 11154413758cSJim Ingham return sb_error; 11164413758cSJim Ingham } 11174413758cSJim Ingham 1118b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() { 11194ac8e93aSJim Ingham SBError sb_error; 11204ac8e93aSJim Ingham 11214ac8e93aSJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 11224ac8e93aSJim Ingham 11234ac8e93aSJim Ingham std::unique_lock<std::recursive_mutex> lock; 11244ac8e93aSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11254ac8e93aSJim Ingham 11264ac8e93aSJim Ingham if (log) 11274ac8e93aSJim Ingham log->Printf("SBThread(%p)::UnwindExpressionEvaluation", 11284ac8e93aSJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr())); 11294ac8e93aSJim Ingham 1130b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 11314ac8e93aSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 11324ac8e93aSJim Ingham sb_error.SetError(thread->UnwindInnermostExpression()); 11334ac8e93aSJim Ingham if (sb_error.Success()) 11344ac8e93aSJim Ingham thread->SetSelectedFrameByIndex(0, false); 11354ac8e93aSJim Ingham } 11364ac8e93aSJim Ingham 11374ac8e93aSJim Ingham return sb_error; 11384ac8e93aSJim Ingham } 1139481cef25SGreg Clayton 1140b9c1b51eSKate Stone bool SBThread::Suspend() { 1141859f54b3SAlexander Polyakov SBError error; // Ignored 1142859f54b3SAlexander Polyakov return Suspend(error); 1143859f54b3SAlexander Polyakov } 1144859f54b3SAlexander Polyakov 1145859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) { 11465160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1147b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1148b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1149b2e7d28eSJim Ingham 1150c9858e4dSGreg Clayton bool result = false; 1151b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1152c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1153b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11541ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended); 1155c9858e4dSGreg Clayton result = true; 1156b9c1b51eSKate Stone } else { 1157859f54b3SAlexander Polyakov error.SetErrorString("process is running"); 1158c9858e4dSGreg Clayton if (log) 1159324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Suspend() => error: process is running", 1160324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1161c9858e4dSGreg Clayton } 1162859f54b3SAlexander Polyakov } else 1163859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 1164c9858e4dSGreg Clayton if (log) 1165324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Suspend() => %i", 1166324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), result); 1167c9858e4dSGreg Clayton return result; 1168722a0cdcSGreg Clayton } 1169722a0cdcSGreg Clayton 1170b9c1b51eSKate Stone bool SBThread::Resume() { 1171859f54b3SAlexander Polyakov SBError error; // Ignored 1172859f54b3SAlexander Polyakov return Resume(error); 1173859f54b3SAlexander Polyakov } 1174859f54b3SAlexander Polyakov 1175859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) { 11765160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1177b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1178b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1179b2e7d28eSJim Ingham 1180c9858e4dSGreg Clayton bool result = false; 1181b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1182c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1183b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11846c9ed91cSJim Ingham const bool override_suspend = true; 11856c9ed91cSJim Ingham exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend); 1186c9858e4dSGreg Clayton result = true; 1187b9c1b51eSKate Stone } else { 1188859f54b3SAlexander Polyakov error.SetErrorString("process is running"); 1189c9858e4dSGreg Clayton if (log) 1190324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Resume() => error: process is running", 1191324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1192c9858e4dSGreg Clayton } 1193859f54b3SAlexander Polyakov } else 1194859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 1195c9858e4dSGreg Clayton if (log) 1196324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Resume() => %i", 1197324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), result); 1198c9858e4dSGreg Clayton return result; 1199722a0cdcSGreg Clayton } 1200722a0cdcSGreg Clayton 1201b9c1b51eSKate Stone bool SBThread::IsSuspended() { 1202b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1203b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1204b2e7d28eSJim Ingham 12051ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 12061ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended; 1207722a0cdcSGreg Clayton return false; 1208722a0cdcSGreg Clayton } 1209722a0cdcSGreg Clayton 1210b9c1b51eSKate Stone bool SBThread::IsStopped() { 1211b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1212b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1213b2e7d28eSJim Ingham 1214a75418dbSAndrew Kaylor if (exe_ctx.HasThreadScope()) 1215a75418dbSAndrew Kaylor return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1216a75418dbSAndrew Kaylor return false; 1217a75418dbSAndrew Kaylor } 1218a75418dbSAndrew Kaylor 1219b9c1b51eSKate Stone SBProcess SBThread::GetProcess() { 1220b9556accSGreg Clayton SBProcess sb_process; 1221b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1222b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1223b2e7d28eSJim Ingham 1224b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1225b9c1b51eSKate Stone // Have to go up to the target so we can get a shared pointer to our 1226b9c1b51eSKate Stone // process... 12271ac04c30SGreg Clayton sb_process.SetSP(exe_ctx.GetProcessSP()); 122830fdc8d8SChris Lattner } 1229ceb6b139SCaroline Tice 12305160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1231b9c1b51eSKate Stone if (log) { 1232481cef25SGreg Clayton SBStream frame_desc_strm; 1233b9556accSGreg Clayton sb_process.GetDescription(frame_desc_strm); 1234324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s", 1235324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1236324a1036SSaleem Abdulrasool static_cast<void *>(sb_process.GetSP().get()), 1237324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1238ceb6b139SCaroline Tice } 1239ceb6b139SCaroline Tice 1240b9556accSGreg Clayton return sb_process; 124130fdc8d8SChris Lattner } 124230fdc8d8SChris Lattner 1243b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() { 12445160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1245ceb6b139SCaroline Tice 1246ceb6b139SCaroline Tice uint32_t num_frames = 0; 1247bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1248bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12494fc6cb9cSJim Ingham 1250b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12517fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1252b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12531ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1254b9c1b51eSKate Stone } else { 1255c9858e4dSGreg Clayton if (log) 1256324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetNumFrames() => error: process is running", 1257324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1258c9858e4dSGreg Clayton } 12597fdf9ef1SGreg Clayton } 1260ceb6b139SCaroline Tice 1261ceb6b139SCaroline Tice if (log) 1262324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetNumFrames () => %u", 1263324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames); 1264ceb6b139SCaroline Tice 1265ceb6b139SCaroline Tice return num_frames; 126630fdc8d8SChris Lattner } 126730fdc8d8SChris Lattner 1268b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) { 12695160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1270ceb6b139SCaroline Tice 127130fdc8d8SChris Lattner SBFrame sb_frame; 1272b57e4a1bSJason Molenda StackFrameSP frame_sp; 1273bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1274bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12754fc6cb9cSJim Ingham 1276b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12777fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1278b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12791ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx); 1280b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1281b9c1b51eSKate Stone } else { 1282c9858e4dSGreg Clayton if (log) 1283b9c1b51eSKate Stone log->Printf( 1284b9c1b51eSKate Stone "SBThread(%p)::GetFrameAtIndex() => error: process is running", 1285324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1286c9858e4dSGreg Clayton } 12877fdf9ef1SGreg Clayton } 1288ceb6b139SCaroline Tice 1289b9c1b51eSKate Stone if (log) { 1290481cef25SGreg Clayton SBStream frame_desc_strm; 1291481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 12924838131bSGreg Clayton log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1293324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), idx, 1294b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1295ceb6b139SCaroline Tice } 1296ceb6b139SCaroline Tice 129730fdc8d8SChris Lattner return sb_frame; 129830fdc8d8SChris Lattner } 129930fdc8d8SChris Lattner 1300b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() { 13015160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1302f028a1fbSGreg Clayton 1303f028a1fbSGreg Clayton SBFrame sb_frame; 1304b57e4a1bSJason Molenda StackFrameSP frame_sp; 1305bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1306bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 13074fc6cb9cSJim Ingham 1308b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13097fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1310b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13111ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame(); 1312b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1313b9c1b51eSKate Stone } else { 1314c9858e4dSGreg Clayton if (log) 1315b9c1b51eSKate Stone log->Printf( 1316b9c1b51eSKate Stone "SBThread(%p)::GetSelectedFrame() => error: process is running", 1317324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1318c9858e4dSGreg Clayton } 13197fdf9ef1SGreg Clayton } 1320f028a1fbSGreg Clayton 1321b9c1b51eSKate Stone if (log) { 1322481cef25SGreg Clayton SBStream frame_desc_strm; 1323481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 1324f028a1fbSGreg Clayton log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1325324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1326b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1327f028a1fbSGreg Clayton } 1328f028a1fbSGreg Clayton 1329f028a1fbSGreg Clayton return sb_frame; 1330f028a1fbSGreg Clayton } 1331f028a1fbSGreg Clayton 1332b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) { 13335160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1334f028a1fbSGreg Clayton 1335f028a1fbSGreg Clayton SBFrame sb_frame; 1336b57e4a1bSJason Molenda StackFrameSP frame_sp; 1337bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1338bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 13394fc6cb9cSJim Ingham 1340b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13417fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1342b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13431ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 13441ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex(idx); 1345b9c1b51eSKate Stone if (frame_sp) { 13461ac04c30SGreg Clayton thread->SetSelectedFrame(frame_sp.get()); 1347b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1348f028a1fbSGreg Clayton } 1349b9c1b51eSKate Stone } else { 1350c9858e4dSGreg Clayton if (log) 1351b9c1b51eSKate Stone log->Printf( 1352b9c1b51eSKate Stone "SBThread(%p)::SetSelectedFrame() => error: process is running", 1353324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1354c9858e4dSGreg Clayton } 13557fdf9ef1SGreg Clayton } 1356f028a1fbSGreg Clayton 1357b9c1b51eSKate Stone if (log) { 1358481cef25SGreg Clayton SBStream frame_desc_strm; 1359481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 1360f028a1fbSGreg Clayton log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1361324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), idx, 1362b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1363f028a1fbSGreg Clayton } 1364f028a1fbSGreg Clayton return sb_frame; 1365f028a1fbSGreg Clayton } 1366f028a1fbSGreg Clayton 1367b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) { 13684f465cffSJim Ingham return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 13694f465cffSJim Ingham } 13704f465cffSJim Ingham 1371b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) { 13724f465cffSJim Ingham return Thread::ThreadEventData::GetStackFrameFromEvent(event.get()); 13734f465cffSJim Ingham } 13744f465cffSJim Ingham 1375b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) { 13764f465cffSJim Ingham return Thread::ThreadEventData::GetThreadFromEvent(event.get()); 13774f465cffSJim Ingham } 1378f028a1fbSGreg Clayton 1379b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const { 1380b9c1b51eSKate Stone return m_opaque_sp->GetThreadSP().get() == 1381b9c1b51eSKate Stone rhs.m_opaque_sp->GetThreadSP().get(); 138230fdc8d8SChris Lattner } 138330fdc8d8SChris Lattner 1384b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const { 1385b9c1b51eSKate Stone return m_opaque_sp->GetThreadSP().get() != 1386b9c1b51eSKate Stone rhs.m_opaque_sp->GetThreadSP().get(); 138730fdc8d8SChris Lattner } 1388dde9cff3SCaroline Tice 1389b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const { 13904f465cffSJim Ingham Stream &strm = status.ref(); 13914f465cffSJim Ingham 1392b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1393b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1394b2e7d28eSJim Ingham 1395b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13966a9767c7SJim Ingham exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true); 1397b9c1b51eSKate Stone } else 13984f465cffSJim Ingham strm.PutCString("No status"); 13994f465cffSJim Ingham 14004f465cffSJim Ingham return true; 14014f465cffSJim Ingham } 14024f465cffSJim Ingham 1403b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const { 14046a9767c7SJim Ingham return GetDescription(description, false); 14056a9767c7SJim Ingham } 14066a9767c7SJim Ingham 14076a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const { 1408da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1409da7bc7d0SGreg Clayton 1410b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1411b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1412b2e7d28eSJim Ingham 1413b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1414b9c1b51eSKate Stone exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, 14156a9767c7SJim Ingham LLDB_INVALID_THREAD_ID, 14166a9767c7SJim Ingham stop_format); 1417b9c1b51eSKate Stone // strm.Printf("SBThread: tid = 0x%4.4" PRIx64, 1418b9c1b51eSKate Stone // exe_ctx.GetThreadPtr()->GetID()); 1419b9c1b51eSKate Stone } else 1420da7bc7d0SGreg Clayton strm.PutCString("No value"); 1421ceb6b139SCaroline Tice 1422ceb6b139SCaroline Tice return true; 1423ceb6b139SCaroline Tice } 14245dd4916fSJason Molenda 1425b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) { 14265dd4916fSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1427bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1428bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 14295dd4916fSJason Molenda SBThread sb_origin_thread; 14305dd4916fSJason Molenda 1431b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 14325dd4916fSJason Molenda Process::StopLocker stop_locker; 1433b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 14347a2f7904SJason Molenda ThreadSP real_thread(exe_ctx.GetThreadSP()); 1435b9c1b51eSKate Stone if (real_thread) { 14365dd4916fSJason Molenda ConstString type_const(type); 14377a2f7904SJason Molenda Process *process = exe_ctx.GetProcessPtr(); 1438b9c1b51eSKate Stone if (process) { 14397a2f7904SJason Molenda SystemRuntime *runtime = process->GetSystemRuntime(); 1440b9c1b51eSKate Stone if (runtime) { 1441b9c1b51eSKate Stone ThreadSP new_thread_sp( 1442b9c1b51eSKate Stone runtime->GetExtendedBacktraceThread(real_thread, type_const)); 1443b9c1b51eSKate Stone if (new_thread_sp) { 1444b9c1b51eSKate Stone // Save this in the Process' ExtendedThreadList so a strong 144505097246SAdrian Prantl // pointer retains the object. 14467a2f7904SJason Molenda process->GetExtendedThreadList().AddThread(new_thread_sp); 14477a2f7904SJason Molenda sb_origin_thread.SetThread(new_thread_sp); 1448b9c1b51eSKate Stone if (log) { 1449a6e9130dSJason Molenda const char *queue_name = new_thread_sp->GetQueueName(); 1450a6e9130dSJason Molenda if (queue_name == NULL) 1451a6e9130dSJason Molenda queue_name = ""; 1452b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new " 1453b9c1b51eSKate Stone "extended Thread " 1454b9c1b51eSKate Stone "created (%p) with queue_id 0x%" PRIx64 1455b9c1b51eSKate Stone " queue name '%s'", 1456324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1457324a1036SSaleem Abdulrasool static_cast<void *>(new_thread_sp.get()), 1458b9c1b51eSKate Stone new_thread_sp->GetQueueID(), queue_name); 1459a6e9130dSJason Molenda } 1460a6e9130dSJason Molenda } 14617a2f7904SJason Molenda } 14625dd4916fSJason Molenda } 14635dd4916fSJason Molenda } 1464b9c1b51eSKate Stone } else { 14655dd4916fSJason Molenda if (log) 1466b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: " 1467b9c1b51eSKate Stone "process is running", 1468324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 14695dd4916fSJason Molenda } 14705dd4916fSJason Molenda } 14715dd4916fSJason Molenda 1472a6682a41SJonas Devlieghere if (log && !sb_origin_thread.IsValid()) 1473b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a " 1474b9c1b51eSKate Stone "Valid thread", 1475324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 14765dd4916fSJason Molenda return sb_origin_thread; 14775dd4916fSJason Molenda } 14788ee9cb58SJason Molenda 1479b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() { 14808ee9cb58SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 14818ee9cb58SJason Molenda if (thread_sp) 14828ee9cb58SJason Molenda return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 14838ee9cb58SJason Molenda return LLDB_INVALID_INDEX32; 14848ee9cb58SJason Molenda } 1485b4892cd2SJason Molenda 1486e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() { 1487e60bc53bSKuba Mracek ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1488e60bc53bSKuba Mracek if (!thread_sp) return SBValue(); 1489e60bc53bSKuba Mracek 1490e60bc53bSKuba Mracek return SBValue(thread_sp->GetCurrentException()); 1491e60bc53bSKuba Mracek } 1492e60bc53bSKuba Mracek 1493e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() { 1494e60bc53bSKuba Mracek ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1495e60bc53bSKuba Mracek if (!thread_sp) return SBThread(); 1496e60bc53bSKuba Mracek 1497e60bc53bSKuba Mracek return SBThread(thread_sp->GetCurrentExceptionBacktrace()); 1498c9e1190aSKuba Mracek } 1499e60bc53bSKuba Mracek 1500b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() { 1501b4892cd2SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1502b4892cd2SJason Molenda if (thread_sp) 1503b4892cd2SJason Molenda return thread_sp->SafeToCallFunctions(); 1504b4892cd2SJason Molenda return true; 1505b4892cd2SJason Molenda } 15062bdbfd50SJim Ingham 1507b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() { 15082bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 15092bdbfd50SJim Ingham if (thread_sp) 15102bdbfd50SJim Ingham return thread_sp.get(); 15112bdbfd50SJim Ingham else 15122bdbfd50SJim Ingham return NULL; 15132bdbfd50SJim Ingham } 15142bdbfd50SJim Ingham 1515b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() { 15162bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 15172bdbfd50SJim Ingham if (thread_sp) 15182bdbfd50SJim Ingham return thread_sp.get(); 15192bdbfd50SJim Ingham else 15202bdbfd50SJim Ingham return NULL; 15212bdbfd50SJim Ingham } 1522