130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 94c5de699SEli Friedman #include "lldb/API/SBThread.h" 10*bd4bf82aSJonas Devlieghere #include "Utils.h" 11*bd4bf82aSJonas Devlieghere #include "lldb/API/SBAddress.h" 12*bd4bf82aSJonas Devlieghere #include "lldb/API/SBDebugger.h" 13*bd4bf82aSJonas Devlieghere #include "lldb/API/SBEvent.h" 1430fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h" 15*bd4bf82aSJonas Devlieghere #include "lldb/API/SBFrame.h" 16*bd4bf82aSJonas Devlieghere #include "lldb/API/SBProcess.h" 17dde9cff3SCaroline Tice #include "lldb/API/SBStream.h" 18b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h" 19*bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadCollection.h" 20*bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadPlan.h" 21*bd4bf82aSJonas Devlieghere #include "lldb/API/SBValue.h" 224e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h" 236611103cSGreg Clayton #include "lldb/Core/Debugger.h" 2430fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h" 25a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h" 266611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2793749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h" 28b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h" 2930fdc8d8SChris Lattner #include "lldb/Target/Process.h" 30b9ffa98cSJason Molenda #include "lldb/Target/Queue.h" 31f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 32b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h" 3330fdc8d8SChris Lattner #include "lldb/Target/Target.h" 34b9c1b51eSKate Stone #include "lldb/Target/Thread.h" 3530fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 36b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h" 3730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 3830fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 3930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 40b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h" 41d821c997SPavel Labath #include "lldb/Utility/State.h" 42bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 43f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h" 445bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h" 4530fdc8d8SChris Lattner 46796ac80bSJonas Devlieghere #include <memory> 47796ac80bSJonas Devlieghere 4830fdc8d8SChris Lattner using namespace lldb; 4930fdc8d8SChris Lattner using namespace lldb_private; 5030fdc8d8SChris Lattner 51b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() { 524f465cffSJim Ingham return Thread::GetStaticBroadcasterClass().AsCString(); 534f465cffSJim Ingham } 544f465cffSJim Ingham 55cfd1acedSGreg Clayton //---------------------------------------------------------------------- 56cfd1acedSGreg Clayton // Constructors 57cfd1acedSGreg Clayton //---------------------------------------------------------------------- 58b9c1b51eSKate Stone SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {} 5930fdc8d8SChris Lattner 60b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp) 61b9c1b51eSKate Stone : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {} 6230fdc8d8SChris Lattner 63*bd4bf82aSJonas Devlieghere SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() { 64*bd4bf82aSJonas Devlieghere m_opaque_sp = clone(rhs.m_opaque_sp); 65*bd4bf82aSJonas Devlieghere } 6630fdc8d8SChris Lattner 6730fdc8d8SChris Lattner //---------------------------------------------------------------------- 68cfd1acedSGreg Clayton // Assignment operator 69cfd1acedSGreg Clayton //---------------------------------------------------------------------- 70cfd1acedSGreg Clayton 71b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) { 72cfd1acedSGreg Clayton if (this != &rhs) 73*bd4bf82aSJonas Devlieghere m_opaque_sp = clone(rhs.m_opaque_sp); 74cfd1acedSGreg Clayton return *this; 75cfd1acedSGreg Clayton } 76cfd1acedSGreg Clayton 77cfd1acedSGreg Clayton //---------------------------------------------------------------------- 7830fdc8d8SChris Lattner // Destructor 7930fdc8d8SChris Lattner //---------------------------------------------------------------------- 80b9c1b51eSKate Stone SBThread::~SBThread() {} 8130fdc8d8SChris Lattner 82b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const { 83b9ffa98cSJason Molenda SBQueue sb_queue; 84b9ffa98cSJason Molenda QueueSP queue_sp; 85bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 86bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 87b9ffa98cSJason Molenda 88b9ffa98cSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 89b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 90b9ffa98cSJason Molenda Process::StopLocker stop_locker; 91b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 92b9ffa98cSJason Molenda queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); 93b9c1b51eSKate Stone if (queue_sp) { 94b9ffa98cSJason Molenda sb_queue.SetQueue(queue_sp); 95b9ffa98cSJason Molenda } 96b9c1b51eSKate Stone } else { 97b9ffa98cSJason Molenda if (log) 98358cf1eaSGreg Clayton log->Printf("SBThread(%p)::GetQueue() => error: process is running", 99b9ffa98cSJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr())); 100b9ffa98cSJason Molenda } 101b9ffa98cSJason Molenda } 102b9ffa98cSJason Molenda 103b9ffa98cSJason Molenda if (log) 104358cf1eaSGreg Clayton log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)", 105b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), 106b9c1b51eSKate Stone static_cast<void *>(queue_sp.get())); 107b9ffa98cSJason Molenda 108b9ffa98cSJason Molenda return sb_queue; 109b9ffa98cSJason Molenda } 110b9ffa98cSJason Molenda 111b9c1b51eSKate Stone bool SBThread::IsValid() const { 112bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 113bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1147fa7dc36SJim Ingham 1157fa7dc36SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 1167fa7dc36SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 117b9c1b51eSKate Stone if (target && process) { 1187fa7dc36SJim Ingham Process::StopLocker stop_locker; 1197fa7dc36SJim Ingham if (stop_locker.TryLock(&process->GetRunLock())) 1207fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != NULL; 12130fdc8d8SChris Lattner } 1227fa7dc36SJim Ingham // Without a valid target & process, this thread can't be valid. 1237fa7dc36SJim Ingham return false; 1247fa7dc36SJim Ingham } 12530fdc8d8SChris Lattner 126b9c1b51eSKate Stone void SBThread::Clear() { m_opaque_sp->Clear(); } 12748e42549SGreg Clayton 128b9c1b51eSKate Stone StopReason SBThread::GetStopReason() { 1295160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 130ceb6b139SCaroline Tice 131ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 132bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 133bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1344fc6cb9cSJim Ingham 135b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1367fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 137b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13897d5cf05SGreg Clayton return exe_ctx.GetThreadPtr()->GetStopReason(); 139b9c1b51eSKate Stone } else { 140c9858e4dSGreg Clayton if (log) 141b9c1b51eSKate Stone log->Printf( 142b9c1b51eSKate Stone "SBThread(%p)::GetStopReason() => error: process is running", 143324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 144c9858e4dSGreg Clayton } 1457fdf9ef1SGreg Clayton } 146ceb6b139SCaroline Tice 147ceb6b139SCaroline Tice if (log) 148324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetStopReason () => %s", 149324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 150750cd175SCaroline Tice Thread::StopReasonAsCString(reason)); 151ceb6b139SCaroline Tice 152ceb6b139SCaroline Tice return reason; 15330fdc8d8SChris Lattner } 15430fdc8d8SChris Lattner 155b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() { 156bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 157bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1584fc6cb9cSJim Ingham 159b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1607fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 161b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1621ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 163b9c1b51eSKate Stone if (stop_info_sp) { 1644e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 165b9c1b51eSKate Stone switch (reason) { 1664e78f606SGreg Clayton case eStopReasonInvalid: 1674e78f606SGreg Clayton case eStopReasonNone: 1684e78f606SGreg Clayton case eStopReasonTrace: 16990ba8115SGreg Clayton case eStopReasonExec: 1704e78f606SGreg Clayton case eStopReasonPlanComplete: 171f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 172afdf842bSKuba Brecka case eStopReasonInstrumentation: 1734e78f606SGreg Clayton // There is no data for these stop reasons. 1744e78f606SGreg Clayton return 0; 1754e78f606SGreg Clayton 176b9c1b51eSKate Stone case eStopReasonBreakpoint: { 1774e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 178b9c1b51eSKate Stone lldb::BreakpointSiteSP bp_site_sp( 179b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 180b9c1b51eSKate Stone site_id)); 1814e78f606SGreg Clayton if (bp_site_sp) 1824e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners() * 2; 1834e78f606SGreg Clayton else 1844e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 185b9c1b51eSKate Stone } break; 1864e78f606SGreg Clayton 1874e78f606SGreg Clayton case eStopReasonWatchpoint: 188290fa41bSJohnny Chen return 1; 1894e78f606SGreg Clayton 1904e78f606SGreg Clayton case eStopReasonSignal: 1914e78f606SGreg Clayton return 1; 1924e78f606SGreg Clayton 1934e78f606SGreg Clayton case eStopReasonException: 1944e78f606SGreg Clayton return 1; 1954e78f606SGreg Clayton } 1964e78f606SGreg Clayton } 197b9c1b51eSKate Stone } else { 1985160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 199c9858e4dSGreg Clayton if (log) 200b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process " 201b9c1b51eSKate Stone "is running", 202324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 203c9858e4dSGreg Clayton } 2047fdf9ef1SGreg Clayton } 2054e78f606SGreg Clayton return 0; 2064e78f606SGreg Clayton } 2074e78f606SGreg Clayton 208b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) { 209bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 210bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 2114fc6cb9cSJim Ingham 212b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 2137fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 214b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 2151ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 2161ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo(); 217b9c1b51eSKate Stone if (stop_info_sp) { 2184e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 219b9c1b51eSKate Stone switch (reason) { 2204e78f606SGreg Clayton case eStopReasonInvalid: 2214e78f606SGreg Clayton case eStopReasonNone: 2224e78f606SGreg Clayton case eStopReasonTrace: 22390ba8115SGreg Clayton case eStopReasonExec: 2244e78f606SGreg Clayton case eStopReasonPlanComplete: 225f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 226afdf842bSKuba Brecka case eStopReasonInstrumentation: 2274e78f606SGreg Clayton // There is no data for these stop reasons. 2284e78f606SGreg Clayton return 0; 2294e78f606SGreg Clayton 230b9c1b51eSKate Stone case eStopReasonBreakpoint: { 2314e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 232b9c1b51eSKate Stone lldb::BreakpointSiteSP bp_site_sp( 233b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 234b9c1b51eSKate Stone site_id)); 235b9c1b51eSKate Stone if (bp_site_sp) { 2364e78f606SGreg Clayton uint32_t bp_index = idx / 2; 237b9c1b51eSKate Stone BreakpointLocationSP bp_loc_sp( 238b9c1b51eSKate Stone bp_site_sp->GetOwnerAtIndex(bp_index)); 239b9c1b51eSKate Stone if (bp_loc_sp) { 240b9c1b51eSKate Stone if (idx & 1) { 2414e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2424e78f606SGreg Clayton return bp_loc_sp->GetID(); 243b9c1b51eSKate Stone } else { 2444e78f606SGreg Clayton // Even idx, return the breakpoint ID 2454e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2464e78f606SGreg Clayton } 2474e78f606SGreg Clayton } 2484e78f606SGreg Clayton } 2494e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 250b9c1b51eSKate Stone } break; 2514e78f606SGreg Clayton 2524e78f606SGreg Clayton case eStopReasonWatchpoint: 253290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2544e78f606SGreg Clayton 2554e78f606SGreg Clayton case eStopReasonSignal: 2564e78f606SGreg Clayton return stop_info_sp->GetValue(); 2574e78f606SGreg Clayton 2584e78f606SGreg Clayton case eStopReasonException: 2594e78f606SGreg Clayton return stop_info_sp->GetValue(); 2604e78f606SGreg Clayton } 2614e78f606SGreg Clayton } 262b9c1b51eSKate Stone } else { 2635160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 264c9858e4dSGreg Clayton if (log) 265b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: " 266b9c1b51eSKate Stone "process is running", 267324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 268c9858e4dSGreg Clayton } 2697fdf9ef1SGreg Clayton } 2704e78f606SGreg Clayton return 0; 2714e78f606SGreg Clayton } 2724e78f606SGreg Clayton 273b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) { 274afdf842bSKuba Brecka Stream &strm = stream.ref(); 275afdf842bSKuba Brecka 276b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 277b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 278b2e7d28eSJim Ingham 279afdf842bSKuba Brecka if (!exe_ctx.HasThreadScope()) 280afdf842bSKuba Brecka return false; 281afdf842bSKuba Brecka 282afdf842bSKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 283afdf842bSKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 284afdf842bSKuba Brecka if (!info) 285afdf842bSKuba Brecka return false; 286afdf842bSKuba Brecka 287afdf842bSKuba Brecka info->Dump(strm); 288afdf842bSKuba Brecka 289afdf842bSKuba Brecka return true; 290afdf842bSKuba Brecka } 291afdf842bSKuba Brecka 2926a831436SKuba Brecka SBThreadCollection 293b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) { 2946a831436SKuba Brecka ThreadCollectionSP threads; 295796ac80bSJonas Devlieghere threads = std::make_shared<ThreadCollection>(); 2966a831436SKuba Brecka 297b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 298b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 299b2e7d28eSJim Ingham 3006a831436SKuba Brecka if (!exe_ctx.HasThreadScope()) 3011aad8fb7SKuba Brecka return threads; 3026a831436SKuba Brecka 3036a831436SKuba Brecka ProcessSP process_sp = exe_ctx.GetProcessSP(); 3046a831436SKuba Brecka 3056a831436SKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 3066a831436SKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 3076a831436SKuba Brecka if (!info) 3086a831436SKuba Brecka return threads; 3096a831436SKuba Brecka 310b9c1b51eSKate Stone return process_sp->GetInstrumentationRuntime(type) 311b9c1b51eSKate Stone ->GetBacktracesFromExtendedStopInfo(info); 3126a831436SKuba Brecka } 3136a831436SKuba Brecka 314b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) { 3155160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 316ceb6b139SCaroline Tice 317bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 318bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 3194fc6cb9cSJim Ingham 320b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 3217fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 322b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 3237fdf9ef1SGreg Clayton 3241ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 325b9c1b51eSKate Stone if (stop_info_sp) { 326b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 327b9c1b51eSKate Stone if (stop_desc) { 328ceb6b139SCaroline Tice if (log) 329b9c1b51eSKate Stone log->Printf( 330b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 331b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc); 33230fdc8d8SChris Lattner if (dst) 33330fdc8d8SChris Lattner return ::snprintf(dst, dst_len, "%s", stop_desc); 334b9c1b51eSKate Stone else { 335b9c1b51eSKate Stone // NULL dst passed in, return the length needed to contain the 336b9c1b51eSKate Stone // description 33730fdc8d8SChris Lattner return ::strlen(stop_desc) + 1; // Include the NULL byte for size 33830fdc8d8SChris Lattner } 339b9c1b51eSKate Stone } else { 34030fdc8d8SChris Lattner size_t stop_desc_len = 0; 341b9c1b51eSKate Stone switch (stop_info_sp->GetStopReason()) { 34230fdc8d8SChris Lattner case eStopReasonTrace: 343b9c1b51eSKate Stone case eStopReasonPlanComplete: { 34430fdc8d8SChris Lattner static char trace_desc[] = "step"; 34530fdc8d8SChris Lattner stop_desc = trace_desc; 346b9c1b51eSKate Stone stop_desc_len = 347b9c1b51eSKate Stone sizeof(trace_desc); // Include the NULL byte for size 348b9c1b51eSKate Stone } break; 34930fdc8d8SChris Lattner 350b9c1b51eSKate Stone case eStopReasonBreakpoint: { 35130fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 35230fdc8d8SChris Lattner stop_desc = bp_desc; 35330fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 354b9c1b51eSKate Stone } break; 35530fdc8d8SChris Lattner 356b9c1b51eSKate Stone case eStopReasonWatchpoint: { 35730fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 35830fdc8d8SChris Lattner stop_desc = wp_desc; 35930fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 360b9c1b51eSKate Stone } break; 36130fdc8d8SChris Lattner 362b9c1b51eSKate Stone case eStopReasonSignal: { 363b9c1b51eSKate Stone stop_desc = 364b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString( 365b9c1b51eSKate Stone stop_info_sp->GetValue()); 366b9c1b51eSKate Stone if (stop_desc == NULL || stop_desc[0] == '\0') { 36730fdc8d8SChris Lattner static char signal_desc[] = "signal"; 36830fdc8d8SChris Lattner stop_desc = signal_desc; 369b9c1b51eSKate Stone stop_desc_len = 370b9c1b51eSKate Stone sizeof(signal_desc); // Include the NULL byte for size 37130fdc8d8SChris Lattner } 372b9c1b51eSKate Stone } break; 37330fdc8d8SChris Lattner 374b9c1b51eSKate Stone case eStopReasonException: { 37530fdc8d8SChris Lattner char exc_desc[] = "exception"; 37630fdc8d8SChris Lattner stop_desc = exc_desc; 37730fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 378b9c1b51eSKate Stone } break; 379c982c768SGreg Clayton 380b9c1b51eSKate Stone case eStopReasonExec: { 38190ba8115SGreg Clayton char exc_desc[] = "exec"; 38290ba8115SGreg Clayton stop_desc = exc_desc; 38390ba8115SGreg Clayton stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 384b9c1b51eSKate Stone } break; 38590ba8115SGreg Clayton 386b9c1b51eSKate Stone case eStopReasonThreadExiting: { 387f85defaeSAndrew Kaylor char limbo_desc[] = "thread exiting"; 388f85defaeSAndrew Kaylor stop_desc = limbo_desc; 389f85defaeSAndrew Kaylor stop_desc_len = sizeof(limbo_desc); 390b9c1b51eSKate Stone } break; 391c982c768SGreg Clayton default: 392c982c768SGreg Clayton break; 39330fdc8d8SChris Lattner } 39430fdc8d8SChris Lattner 395b9c1b51eSKate Stone if (stop_desc && stop_desc[0]) { 396ceb6b139SCaroline Tice if (log) 397b9c1b51eSKate Stone log->Printf( 398b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 399b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc); 400ceb6b139SCaroline Tice 40130fdc8d8SChris Lattner if (dst) 402b9c1b51eSKate Stone return ::snprintf(dst, dst_len, "%s", stop_desc) + 403b9c1b51eSKate Stone 1; // Include the NULL byte 40430fdc8d8SChris Lattner 40530fdc8d8SChris Lattner if (stop_desc_len == 0) 40630fdc8d8SChris Lattner stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte 40730fdc8d8SChris Lattner 40830fdc8d8SChris Lattner return stop_desc_len; 40930fdc8d8SChris Lattner } 41030fdc8d8SChris Lattner } 41130fdc8d8SChris Lattner } 412b9c1b51eSKate Stone } else { 4135160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 414c9858e4dSGreg Clayton if (log) 415b9c1b51eSKate Stone log->Printf( 416b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription() => error: process is running", 417324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 418c9858e4dSGreg Clayton } 4197fdf9ef1SGreg Clayton } 42030fdc8d8SChris Lattner if (dst) 42130fdc8d8SChris Lattner *dst = 0; 42230fdc8d8SChris Lattner return 0; 42330fdc8d8SChris Lattner } 42430fdc8d8SChris Lattner 425b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() { 4265160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 42773ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 428bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 429bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4304fc6cb9cSJim Ingham 431b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 4327fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 433b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4341ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 435b9c1b51eSKate Stone if (stop_info_sp) { 43673ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp); 43773ca05a2SJim Ingham } 438b9c1b51eSKate Stone } else { 439c9858e4dSGreg Clayton if (log) 440b9c1b51eSKate Stone log->Printf( 441b9c1b51eSKate Stone "SBThread(%p)::GetStopReturnValue() => error: process is running", 442324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 443c9858e4dSGreg Clayton } 4447fdf9ef1SGreg Clayton } 44573ca05a2SJim Ingham 44673ca05a2SJim Ingham if (log) 447324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetStopReturnValue () => %s", 448324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 449b9c1b51eSKate Stone return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString() 45073ca05a2SJim Ingham : "<no return value>"); 45173ca05a2SJim Ingham 45273ca05a2SJim Ingham return SBValue(return_valobj_sp); 45373ca05a2SJim Ingham } 45473ca05a2SJim Ingham 455b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) { 4567fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP(lldb_object_sp); 45730fdc8d8SChris Lattner } 45830fdc8d8SChris Lattner 459b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const { 4607fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 46117a6ad05SGreg Clayton if (thread_sp) 4621ac04c30SGreg Clayton return thread_sp->GetID(); 4631ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 46430fdc8d8SChris Lattner } 46530fdc8d8SChris Lattner 466b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const { 4677fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 46817a6ad05SGreg Clayton if (thread_sp) 46917a6ad05SGreg Clayton return thread_sp->GetIndexID(); 47030fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 47130fdc8d8SChris Lattner } 4721ac04c30SGreg Clayton 473b9c1b51eSKate Stone const char *SBThread::GetName() const { 4745160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 4754838131bSGreg Clayton const char *name = NULL; 476bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 477bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4784fc6cb9cSJim Ingham 479b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 4807fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 481b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4821ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 483b9c1b51eSKate Stone } else { 484c9858e4dSGreg Clayton if (log) 485324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetName() => error: process is running", 486324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 487c9858e4dSGreg Clayton } 4887fdf9ef1SGreg Clayton } 489ceb6b139SCaroline Tice 490ceb6b139SCaroline Tice if (log) 491324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetName () => %s", 492324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 493324a1036SSaleem Abdulrasool name ? name : "NULL"); 494ceb6b139SCaroline Tice 4954838131bSGreg Clayton return name; 49630fdc8d8SChris Lattner } 49730fdc8d8SChris Lattner 498b9c1b51eSKate Stone const char *SBThread::GetQueueName() const { 4994838131bSGreg Clayton const char *name = NULL; 500bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 501bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5024fc6cb9cSJim Ingham 5035160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 504b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 5057fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 506b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 5071ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 508b9c1b51eSKate Stone } else { 509c9858e4dSGreg Clayton if (log) 510324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueName() => error: process is running", 511324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 512c9858e4dSGreg Clayton } 5137fdf9ef1SGreg Clayton } 514ceb6b139SCaroline Tice 515ceb6b139SCaroline Tice if (log) 516324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueName () => %s", 517324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 518324a1036SSaleem Abdulrasool name ? name : "NULL"); 519ceb6b139SCaroline Tice 5204838131bSGreg Clayton return name; 52130fdc8d8SChris Lattner } 52230fdc8d8SChris Lattner 523b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const { 5244fdb5863SJason Molenda queue_id_t id = LLDB_INVALID_QUEUE_ID; 525bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 526bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5274fdb5863SJason Molenda 5284fdb5863SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 529b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 5304fdb5863SJason Molenda Process::StopLocker stop_locker; 531b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 5324fdb5863SJason Molenda id = exe_ctx.GetThreadPtr()->GetQueueID(); 533b9c1b51eSKate Stone } else { 5344fdb5863SJason Molenda if (log) 535324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueID() => error: process is running", 536324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 5374fdb5863SJason Molenda } 5384fdb5863SJason Molenda } 5394fdb5863SJason Molenda 5404fdb5863SJason Molenda if (log) 541324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64, 542324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), id); 5434fdb5863SJason Molenda 5444fdb5863SJason Molenda return id; 5454fdb5863SJason Molenda } 5464fdb5863SJason Molenda 547b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { 548705b1809SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 549705b1809SJason Molenda bool success = false; 550bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 551bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 552705b1809SJason Molenda 553b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 554705b1809SJason Molenda Process::StopLocker stop_locker; 555b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 556705b1809SJason Molenda Thread *thread = exe_ctx.GetThreadPtr(); 557705b1809SJason Molenda StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); 558b9c1b51eSKate Stone if (info_root_sp) { 559b9c1b51eSKate Stone StructuredData::ObjectSP node = 560b9c1b51eSKate Stone info_root_sp->GetObjectForDotSeparatedPath(path); 561b9c1b51eSKate Stone if (node) { 5625bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeString) { 5632833321fSZachary Turner strm.Printf("%s", node->GetAsString()->GetValue().str().c_str()); 564705b1809SJason Molenda success = true; 565705b1809SJason Molenda } 5665bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeInteger) { 567705b1809SJason Molenda strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue()); 568705b1809SJason Molenda success = true; 569705b1809SJason Molenda } 5705bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeFloat) { 571705b1809SJason Molenda strm.Printf("0x%f", node->GetAsFloat()->GetValue()); 572705b1809SJason Molenda success = true; 573705b1809SJason Molenda } 5745bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeBoolean) { 575a6682a41SJonas Devlieghere if (node->GetAsBoolean()->GetValue()) 576705b1809SJason Molenda strm.Printf("true"); 577705b1809SJason Molenda else 578705b1809SJason Molenda strm.Printf("false"); 579705b1809SJason Molenda success = true; 580705b1809SJason Molenda } 5815bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeNull) { 582705b1809SJason Molenda strm.Printf("null"); 583705b1809SJason Molenda success = true; 584705b1809SJason Molenda } 585705b1809SJason Molenda } 586705b1809SJason Molenda } 587b9c1b51eSKate Stone } else { 588705b1809SJason Molenda if (log) 589b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: " 590b9c1b51eSKate Stone "process is running", 591705b1809SJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr())); 592705b1809SJason Molenda } 593705b1809SJason Molenda } 594705b1809SJason Molenda 595705b1809SJason Molenda if (log) 596753e13c0SJason Molenda log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"", 597753e13c0SJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData()); 598705b1809SJason Molenda 599705b1809SJason Molenda return success; 600705b1809SJason Molenda } 601705b1809SJason Molenda 602b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx, 603b9c1b51eSKate Stone ThreadPlan *new_plan) { 60464e7ead1SJim Ingham SBError sb_error; 60564e7ead1SJim Ingham 60664e7ead1SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 607b9c1b51eSKate Stone if (!process) { 60864e7ead1SJim Ingham sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 60964e7ead1SJim Ingham return sb_error; 61064e7ead1SJim Ingham } 61164e7ead1SJim Ingham 61264e7ead1SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 613b9c1b51eSKate Stone if (!thread) { 61464e7ead1SJim Ingham sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 61564e7ead1SJim Ingham return sb_error; 61664e7ead1SJim Ingham } 61764e7ead1SJim Ingham 618b9c1b51eSKate Stone // User level plans should be Master Plans so they can be interrupted, other 61905097246SAdrian Prantl // plans executed, and then a "continue" will resume the plan. 620b9c1b51eSKate Stone if (new_plan != NULL) { 62164e7ead1SJim Ingham new_plan->SetIsMasterPlan(true); 62264e7ead1SJim Ingham new_plan->SetOkayToDiscard(false); 62364e7ead1SJim Ingham } 62464e7ead1SJim Ingham 62564e7ead1SJim Ingham // Why do we need to set the current thread by ID here??? 62664e7ead1SJim Ingham process->GetThreadList().SetSelectedThreadByID(thread->GetID()); 62764e7ead1SJim Ingham 628dc6224e0SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution()) 629dc6224e0SGreg Clayton sb_error.ref() = process->Resume(); 630dc6224e0SGreg Clayton else 631dc6224e0SGreg Clayton sb_error.ref() = process->ResumeSynchronous(NULL); 63264e7ead1SJim Ingham 63364e7ead1SJim Ingham return sb_error; 63464e7ead1SJim Ingham } 63530fdc8d8SChris Lattner 636b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) { 637859f54b3SAlexander Polyakov SBError error; // Ignored 638859f54b3SAlexander Polyakov StepOver(stop_other_threads, error); 639859f54b3SAlexander Polyakov } 640859f54b3SAlexander Polyakov 641859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { 6425160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 643ceb6b139SCaroline Tice 644bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 645bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 64617a6ad05SGreg Clayton 647ceb6b139SCaroline Tice if (log) 648324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')", 649324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 650ceb6b139SCaroline Tice Thread::RunModeAsCString(stop_other_threads)); 651ceb6b139SCaroline Tice 652859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 653859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 654859f54b3SAlexander Polyakov return; 655859f54b3SAlexander Polyakov } 656859f54b3SAlexander Polyakov 6571ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 6587ba6e991SJim Ingham bool abort_other_plans = false; 659b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 66030fdc8d8SChris Lattner 661e103ae92SJonas Devlieghere Status new_plan_status; 6624d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 663b9c1b51eSKate Stone if (frame_sp) { 664b9c1b51eSKate Stone if (frame_sp->HasDebugInformation()) { 6654b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 66630fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 667b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepOverRange( 668b9c1b51eSKate Stone abort_other_plans, sc.line_entry, sc, stop_other_threads, 669e103ae92SJonas Devlieghere new_plan_status, avoid_no_debug); 670b9c1b51eSKate Stone } else { 671b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 672e103ae92SJonas Devlieghere true, abort_other_plans, stop_other_threads, new_plan_status); 67330fdc8d8SChris Lattner } 67430fdc8d8SChris Lattner } 675859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 67630fdc8d8SChris Lattner } 67730fdc8d8SChris Lattner 678b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) { 679c627682eSJim Ingham StepInto(NULL, stop_other_threads); 680c627682eSJim Ingham } 681c627682eSJim Ingham 682b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, 683b9c1b51eSKate Stone lldb::RunMode stop_other_threads) { 684859f54b3SAlexander Polyakov SBError error; // Ignored 685cbf6f9b2SJim Ingham StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads); 686cbf6f9b2SJim Ingham } 687cbf6f9b2SJim Ingham 688b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line, 689b9c1b51eSKate Stone SBError &error, lldb::RunMode stop_other_threads) { 6905160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 691ceb6b139SCaroline Tice 692bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 693bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 69417a6ad05SGreg Clayton 69517a6ad05SGreg Clayton if (log) 696b9c1b51eSKate Stone log->Printf( 697b9c1b51eSKate Stone "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 698324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 699c627682eSJim Ingham target_name ? target_name : "<NULL>", 70017a6ad05SGreg Clayton Thread::RunModeAsCString(stop_other_threads)); 701c627682eSJim Ingham 702859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 703859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 704859f54b3SAlexander Polyakov return; 705859f54b3SAlexander Polyakov } 706859f54b3SAlexander Polyakov 7077ba6e991SJim Ingham bool abort_other_plans = false; 70830fdc8d8SChris Lattner 7091ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 710b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 7114d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 712e103ae92SJonas Devlieghere Status new_plan_status; 71330fdc8d8SChris Lattner 714b9c1b51eSKate Stone if (frame_sp && frame_sp->HasDebugInformation()) { 715cbf6f9b2SJim Ingham SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 716cbf6f9b2SJim Ingham AddressRange range; 717cbf6f9b2SJim Ingham if (end_line == LLDB_INVALID_LINE_NUMBER) 718cbf6f9b2SJim Ingham range = sc.line_entry.range; 719b9c1b51eSKate Stone else { 720cbf6f9b2SJim Ingham if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref())) 721cbf6f9b2SJim Ingham return; 722cbf6f9b2SJim Ingham } 723cbf6f9b2SJim Ingham 724b9c1b51eSKate Stone const LazyBool step_out_avoids_code_without_debug_info = 725b9c1b51eSKate Stone eLazyBoolCalculate; 726b9c1b51eSKate Stone const LazyBool step_in_avoids_code_without_debug_info = 727b9c1b51eSKate Stone eLazyBoolCalculate; 728b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepInRange( 729b9c1b51eSKate Stone abort_other_plans, range, sc, target_name, stop_other_threads, 730e103ae92SJonas Devlieghere new_plan_status, step_in_avoids_code_without_debug_info, 7314b4b2478SJim Ingham step_out_avoids_code_without_debug_info); 732b9c1b51eSKate Stone } else { 733b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 734e103ae92SJonas Devlieghere false, abort_other_plans, stop_other_threads, new_plan_status); 73530fdc8d8SChris Lattner } 736e103ae92SJonas Devlieghere 737e103ae92SJonas Devlieghere if (new_plan_status.Success()) 738cbf6f9b2SJim Ingham error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 739e103ae92SJonas Devlieghere else 740e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 74130fdc8d8SChris Lattner } 74230fdc8d8SChris Lattner 743b9c1b51eSKate Stone void SBThread::StepOut() { 744859f54b3SAlexander Polyakov SBError error; // Ignored 745859f54b3SAlexander Polyakov StepOut(error); 746859f54b3SAlexander Polyakov } 747859f54b3SAlexander Polyakov 748859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) { 7495160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 750ceb6b139SCaroline Tice 751bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 752bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7534fc6cb9cSJim Ingham 75417a6ad05SGreg Clayton if (log) 755324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOut ()", 756324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 75717a6ad05SGreg Clayton 758859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 759859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 760859f54b3SAlexander Polyakov return; 761859f54b3SAlexander Polyakov } 762859f54b3SAlexander Polyakov 7637ba6e991SJim Ingham bool abort_other_plans = false; 76494b09246SJim Ingham bool stop_other_threads = false; 76530fdc8d8SChris Lattner 7661ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7671ac04c30SGreg Clayton 7684b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 769e103ae92SJonas Devlieghere Status new_plan_status; 770b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 771b9c1b51eSKate Stone abort_other_plans, NULL, false, stop_other_threads, eVoteYes, 772e103ae92SJonas Devlieghere eVoteNoOpinion, 0, new_plan_status, avoid_no_debug)); 773481cef25SGreg Clayton 774e103ae92SJonas Devlieghere if (new_plan_status.Success()) 775859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 776e103ae92SJonas Devlieghere else 777e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 778481cef25SGreg Clayton } 779481cef25SGreg Clayton 780859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) { 781859f54b3SAlexander Polyakov SBError error; // Ignored 782859f54b3SAlexander Polyakov StepOutOfFrame(sb_frame, error); 783859f54b3SAlexander Polyakov } 784859f54b3SAlexander Polyakov 785859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) { 7865160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 787481cef25SGreg Clayton 788bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 789bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7904fc6cb9cSJim Ingham 791b9c1b51eSKate Stone if (!sb_frame.IsValid()) { 792989a7558SJim Ingham if (log) 793b9c1b51eSKate Stone log->Printf( 794b9c1b51eSKate Stone "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.", 795989a7558SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr())); 796859f54b3SAlexander Polyakov error.SetErrorString("passed invalid SBFrame object"); 797989a7558SJim Ingham return; 798989a7558SJim Ingham } 799989a7558SJim Ingham 800b57e4a1bSJason Molenda StackFrameSP frame_sp(sb_frame.GetFrameSP()); 801b9c1b51eSKate Stone if (log) { 802481cef25SGreg Clayton SBStream frame_desc_strm; 803481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 804324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", 805324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 806b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 807481cef25SGreg Clayton } 808481cef25SGreg Clayton 809859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 810859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 811859f54b3SAlexander Polyakov return; 812859f54b3SAlexander Polyakov } 813859f54b3SAlexander Polyakov 8147ba6e991SJim Ingham bool abort_other_plans = false; 81594b09246SJim Ingham bool stop_other_threads = false; 8161ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 817b9c1b51eSKate Stone if (sb_frame.GetThread().GetThreadID() != thread->GetID()) { 818b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another " 819b9c1b51eSKate Stone "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.", 820989a7558SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr()), 821b9c1b51eSKate Stone sb_frame.GetThread().GetThreadID(), thread->GetID()); 822859f54b3SAlexander Polyakov error.SetErrorString("passed a frame from another thread"); 823859f54b3SAlexander Polyakov return; 824989a7558SJim Ingham } 825481cef25SGreg Clayton 826e103ae92SJonas Devlieghere Status new_plan_status; 827b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 828b9c1b51eSKate Stone abort_other_plans, NULL, false, stop_other_threads, eVoteYes, 829e103ae92SJonas Devlieghere eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status)); 83030fdc8d8SChris Lattner 831e103ae92SJonas Devlieghere if (new_plan_status.Success()) 832859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 833e103ae92SJonas Devlieghere else 834e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 83530fdc8d8SChris Lattner } 83630fdc8d8SChris Lattner 837b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) { 838859f54b3SAlexander Polyakov SBError error; // Ignored 839859f54b3SAlexander Polyakov StepInstruction(step_over, error); 840859f54b3SAlexander Polyakov } 841859f54b3SAlexander Polyakov 842859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) { 8435160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 844ceb6b139SCaroline Tice 845bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 846bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 847ceb6b139SCaroline Tice 84817a6ad05SGreg Clayton if (log) 849324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepInstruction (step_over=%i)", 850324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), step_over); 85117a6ad05SGreg Clayton 852859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 853859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 854859f54b3SAlexander Polyakov return; 855859f54b3SAlexander Polyakov } 856859f54b3SAlexander Polyakov 8571ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 858e103ae92SJonas Devlieghere Status new_plan_status; 859e103ae92SJonas Devlieghere ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction( 860e103ae92SJonas Devlieghere step_over, true, true, new_plan_status)); 86164e7ead1SJim Ingham 862e103ae92SJonas Devlieghere if (new_plan_status.Success()) 863859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 864e103ae92SJonas Devlieghere else 865e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 86630fdc8d8SChris Lattner } 86730fdc8d8SChris Lattner 868b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) { 869859f54b3SAlexander Polyakov SBError error; // Ignored 870859f54b3SAlexander Polyakov RunToAddress(addr, error); 871859f54b3SAlexander Polyakov } 872859f54b3SAlexander Polyakov 873859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) { 8745160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 875ceb6b139SCaroline Tice 876bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 877bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 878ceb6b139SCaroline Tice 87917a6ad05SGreg Clayton if (log) 880324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", 881324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), addr); 88217a6ad05SGreg Clayton 883859f54b3SAlexander Polyakov if (!exe_ctx.HasThreadScope()) { 884859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 885859f54b3SAlexander Polyakov return; 886859f54b3SAlexander Polyakov } 887859f54b3SAlexander Polyakov 8887ba6e991SJim Ingham bool abort_other_plans = false; 88930fdc8d8SChris Lattner bool stop_other_threads = true; 89030fdc8d8SChris Lattner 891e72dfb32SGreg Clayton Address target_addr(addr); 89230fdc8d8SChris Lattner 8931ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 8941ac04c30SGreg Clayton 895e103ae92SJonas Devlieghere Status new_plan_status; 896b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress( 897e103ae92SJonas Devlieghere abort_other_plans, target_addr, stop_other_threads, new_plan_status)); 89864e7ead1SJim Ingham 899e103ae92SJonas Devlieghere if (new_plan_status.Success()) 900859f54b3SAlexander Polyakov error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 901e103ae92SJonas Devlieghere else 902e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 90330fdc8d8SChris Lattner } 90430fdc8d8SChris Lattner 905b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, 906b9c1b51eSKate Stone lldb::SBFileSpec &sb_file_spec, uint32_t line) { 907481cef25SGreg Clayton SBError sb_error; 9085160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 909481cef25SGreg Clayton char path[PATH_MAX]; 910481cef25SGreg Clayton 911bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 912bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 9134fc6cb9cSJim Ingham 914b57e4a1bSJason Molenda StackFrameSP frame_sp(sb_frame.GetFrameSP()); 91517a6ad05SGreg Clayton 916b9c1b51eSKate Stone if (log) { 917481cef25SGreg Clayton SBStream frame_desc_strm; 918481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 919481cef25SGreg Clayton sb_file_spec->GetPath(path, sizeof(path)); 920b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, " 921b9c1b51eSKate Stone "file+line = %s:%u)", 922324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 923b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(), 924b9c1b51eSKate Stone path, line); 925481cef25SGreg Clayton } 926481cef25SGreg Clayton 927b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 9281ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 9291ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 930481cef25SGreg Clayton 931b9c1b51eSKate Stone if (line == 0) { 932481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 933481cef25SGreg Clayton return sb_error; 934481cef25SGreg Clayton } 935481cef25SGreg Clayton 936b9c1b51eSKate Stone if (!frame_sp) { 9371ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame(); 938481cef25SGreg Clayton if (!frame_sp) 9391ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex(0); 940481cef25SGreg Clayton } 941481cef25SGreg Clayton 942481cef25SGreg Clayton SymbolContext frame_sc; 943b9c1b51eSKate Stone if (!frame_sp) { 944481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 945481cef25SGreg Clayton return sb_error; 946481cef25SGreg Clayton } 947481cef25SGreg Clayton 948481cef25SGreg Clayton // If we have a frame, get its line 949b9c1b51eSKate Stone frame_sc = frame_sp->GetSymbolContext( 950b9c1b51eSKate Stone eSymbolContextCompUnit | eSymbolContextFunction | 951b9c1b51eSKate Stone eSymbolContextLineEntry | eSymbolContextSymbol); 952481cef25SGreg Clayton 953b9c1b51eSKate Stone if (frame_sc.comp_unit == NULL) { 954b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat( 955b9c1b51eSKate Stone "frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 956481cef25SGreg Clayton return sb_error; 957481cef25SGreg Clayton } 958481cef25SGreg Clayton 959481cef25SGreg Clayton FileSpec step_file_spec; 960b9c1b51eSKate Stone if (sb_file_spec.IsValid()) { 961481cef25SGreg Clayton // The file spec passed in was valid, so use it 962481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 963b9c1b51eSKate Stone } else { 964481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 965481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 966b9c1b51eSKate Stone else { 967481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 968481cef25SGreg Clayton return sb_error; 969481cef25SGreg Clayton } 970481cef25SGreg Clayton } 971481cef25SGreg Clayton 9729b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 9739b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 974b9c1b51eSKate Stone // function, and then if there are no addresses remaining, give an 97505097246SAdrian Prantl // appropriate error message. 9769b70ddb3SJim Ingham 9779b70ddb3SJim Ingham bool all_in_function = true; 9789b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 9799b70ddb3SJim Ingham 980481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 9817ba6e991SJim Ingham const bool abort_other_plans = false; 982c02e3344SJim Ingham const bool stop_other_threads = false; 983481cef25SGreg Clayton const bool check_inlines = true; 984481cef25SGreg Clayton const bool exact = false; 985481cef25SGreg Clayton 986481cef25SGreg Clayton SymbolContextList sc_list; 987b9c1b51eSKate Stone const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext( 988b9c1b51eSKate Stone step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry, 9899b70ddb3SJim Ingham sc_list); 990b9c1b51eSKate Stone if (num_matches > 0) { 991481cef25SGreg Clayton SymbolContext sc; 992b9c1b51eSKate Stone for (uint32_t i = 0; i < num_matches; ++i) { 993b9c1b51eSKate Stone if (sc_list.GetContextAtIndex(i, sc)) { 994b9c1b51eSKate Stone addr_t step_addr = 995b9c1b51eSKate Stone sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 996b9c1b51eSKate Stone if (step_addr != LLDB_INVALID_ADDRESS) { 9979b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 998481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 9999b70ddb3SJim Ingham else 10009b70ddb3SJim Ingham all_in_function = false; 1001481cef25SGreg Clayton } 1002481cef25SGreg Clayton } 1003481cef25SGreg Clayton } 1004481cef25SGreg Clayton } 1005481cef25SGreg Clayton 1006b9c1b51eSKate Stone if (step_over_until_addrs.empty()) { 1007b9c1b51eSKate Stone if (all_in_function) { 1008481cef25SGreg Clayton step_file_spec.GetPath(path, sizeof(path)); 1009b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, 1010b9c1b51eSKate Stone line); 1011b9c1b51eSKate Stone } else 101286edbf41SGreg Clayton sb_error.SetErrorString("step until target not in current function"); 1013b9c1b51eSKate Stone } else { 1014e103ae92SJonas Devlieghere Status new_plan_status; 1015b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil( 1016b9c1b51eSKate Stone abort_other_plans, &step_over_until_addrs[0], 1017b9c1b51eSKate Stone step_over_until_addrs.size(), stop_other_threads, 1018e103ae92SJonas Devlieghere frame_sp->GetFrameIndex(), new_plan_status)); 1019481cef25SGreg Clayton 1020e103ae92SJonas Devlieghere if (new_plan_status.Success()) 10214d56e9c1SJim Ingham sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 1022e103ae92SJonas Devlieghere else 1023e103ae92SJonas Devlieghere sb_error.SetErrorString(new_plan_status.AsCString()); 1024481cef25SGreg Clayton } 1025b9c1b51eSKate Stone } else { 1026481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 1027481cef25SGreg Clayton } 1028481cef25SGreg Clayton return sb_error; 1029481cef25SGreg Clayton } 1030481cef25SGreg Clayton 1031b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { 1032000ca185SOleksiy Vyalov return StepUsingScriptedThreadPlan(script_class_name, true); 1033c915a7d2SJim Ingham } 1034c915a7d2SJim Ingham 1035b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, 1036b9c1b51eSKate Stone bool resume_immediately) { 10372bdbfd50SJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1038e103ae92SJonas Devlieghere SBError error; 10392bdbfd50SJim Ingham 1040bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1041bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10422bdbfd50SJim Ingham 1043b9c1b51eSKate Stone if (log) { 10442bdbfd50SJim Ingham log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s", 1045b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name); 10462bdbfd50SJim Ingham } 10472bdbfd50SJim Ingham 1048b9c1b51eSKate Stone if (!exe_ctx.HasThreadScope()) { 1049e103ae92SJonas Devlieghere error.SetErrorString("this SBThread object is invalid"); 1050e103ae92SJonas Devlieghere return error; 10512bdbfd50SJim Ingham } 10522bdbfd50SJim Ingham 10532bdbfd50SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 1054e103ae92SJonas Devlieghere Status new_plan_status; 1055e103ae92SJonas Devlieghere ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted( 1056e103ae92SJonas Devlieghere false, script_class_name, false, new_plan_status); 10572bdbfd50SJim Ingham 1058e103ae92SJonas Devlieghere if (new_plan_status.Fail()) { 1059e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 1060e103ae92SJonas Devlieghere return error; 1061c915a7d2SJim Ingham } 1062c915a7d2SJim Ingham 1063e103ae92SJonas Devlieghere if (!resume_immediately) 1064e103ae92SJonas Devlieghere return error; 1065c915a7d2SJim Ingham 1066e103ae92SJonas Devlieghere if (new_plan_status.Success()) 1067e103ae92SJonas Devlieghere error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 1068e103ae92SJonas Devlieghere else 1069e103ae92SJonas Devlieghere error.SetErrorString(new_plan_status.AsCString()); 10702bdbfd50SJim Ingham 1071e103ae92SJonas Devlieghere return error; 10722bdbfd50SJim Ingham } 10732bdbfd50SJim Ingham 1074b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) { 1075f86248d9SRichard Mitton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1076f86248d9SRichard Mitton SBError sb_error; 1077f86248d9SRichard Mitton 1078bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1079bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1080f86248d9SRichard Mitton 1081f86248d9SRichard Mitton if (log) 1082324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)", 1083324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1084324a1036SSaleem Abdulrasool file_spec->GetPath().c_str(), line); 1085f86248d9SRichard Mitton 1086b9c1b51eSKate Stone if (!exe_ctx.HasThreadScope()) { 1087f86248d9SRichard Mitton sb_error.SetErrorString("this SBThread object is invalid"); 1088f86248d9SRichard Mitton return sb_error; 1089f86248d9SRichard Mitton } 1090f86248d9SRichard Mitton 1091f86248d9SRichard Mitton Thread *thread = exe_ctx.GetThreadPtr(); 1092f86248d9SRichard Mitton 109397206d57SZachary Turner Status err = thread->JumpToLine(file_spec.get(), line, true); 1094f86248d9SRichard Mitton sb_error.SetError(err); 1095f86248d9SRichard Mitton return sb_error; 1096f86248d9SRichard Mitton } 1097f86248d9SRichard Mitton 1098b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) { 10994413758cSJim Ingham SBError sb_error; 11004413758cSJim Ingham 11015160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 11024413758cSJim Ingham 1103bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1104bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11054413758cSJim Ingham 11064413758cSJim Ingham if (log) 1107324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)", 1108324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1109324a1036SSaleem Abdulrasool frame.GetFrameID()); 11104413758cSJim Ingham 1111b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 11124413758cSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 1113b9c1b51eSKate Stone sb_error.SetError( 1114b9c1b51eSKate Stone thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 11154413758cSJim Ingham } 11164413758cSJim Ingham 11174413758cSJim Ingham return sb_error; 11184413758cSJim Ingham } 11194413758cSJim Ingham 1120b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() { 11214ac8e93aSJim Ingham SBError sb_error; 11224ac8e93aSJim Ingham 11234ac8e93aSJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 11244ac8e93aSJim Ingham 11254ac8e93aSJim Ingham std::unique_lock<std::recursive_mutex> lock; 11264ac8e93aSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11274ac8e93aSJim Ingham 11284ac8e93aSJim Ingham if (log) 11294ac8e93aSJim Ingham log->Printf("SBThread(%p)::UnwindExpressionEvaluation", 11304ac8e93aSJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr())); 11314ac8e93aSJim Ingham 1132b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 11334ac8e93aSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 11344ac8e93aSJim Ingham sb_error.SetError(thread->UnwindInnermostExpression()); 11354ac8e93aSJim Ingham if (sb_error.Success()) 11364ac8e93aSJim Ingham thread->SetSelectedFrameByIndex(0, false); 11374ac8e93aSJim Ingham } 11384ac8e93aSJim Ingham 11394ac8e93aSJim Ingham return sb_error; 11404ac8e93aSJim Ingham } 1141481cef25SGreg Clayton 1142b9c1b51eSKate Stone bool SBThread::Suspend() { 1143859f54b3SAlexander Polyakov SBError error; // Ignored 1144859f54b3SAlexander Polyakov return Suspend(error); 1145859f54b3SAlexander Polyakov } 1146859f54b3SAlexander Polyakov 1147859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) { 11485160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1149b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1150b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1151b2e7d28eSJim Ingham 1152c9858e4dSGreg Clayton bool result = false; 1153b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1154c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1155b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11561ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended); 1157c9858e4dSGreg Clayton result = true; 1158b9c1b51eSKate Stone } else { 1159859f54b3SAlexander Polyakov error.SetErrorString("process is running"); 1160c9858e4dSGreg Clayton if (log) 1161324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Suspend() => error: process is running", 1162324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1163c9858e4dSGreg Clayton } 1164859f54b3SAlexander Polyakov } else 1165859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 1166c9858e4dSGreg Clayton if (log) 1167324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Suspend() => %i", 1168324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), result); 1169c9858e4dSGreg Clayton return result; 1170722a0cdcSGreg Clayton } 1171722a0cdcSGreg Clayton 1172b9c1b51eSKate Stone bool SBThread::Resume() { 1173859f54b3SAlexander Polyakov SBError error; // Ignored 1174859f54b3SAlexander Polyakov return Resume(error); 1175859f54b3SAlexander Polyakov } 1176859f54b3SAlexander Polyakov 1177859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) { 11785160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1179b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1180b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1181b2e7d28eSJim Ingham 1182c9858e4dSGreg Clayton bool result = false; 1183b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1184c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1185b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11866c9ed91cSJim Ingham const bool override_suspend = true; 11876c9ed91cSJim Ingham exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend); 1188c9858e4dSGreg Clayton result = true; 1189b9c1b51eSKate Stone } else { 1190859f54b3SAlexander Polyakov error.SetErrorString("process is running"); 1191c9858e4dSGreg Clayton if (log) 1192324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Resume() => error: process is running", 1193324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1194c9858e4dSGreg Clayton } 1195859f54b3SAlexander Polyakov } else 1196859f54b3SAlexander Polyakov error.SetErrorString("this SBThread object is invalid"); 1197c9858e4dSGreg Clayton if (log) 1198324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Resume() => %i", 1199324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), result); 1200c9858e4dSGreg Clayton return result; 1201722a0cdcSGreg Clayton } 1202722a0cdcSGreg Clayton 1203b9c1b51eSKate Stone bool SBThread::IsSuspended() { 1204b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1205b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1206b2e7d28eSJim Ingham 12071ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 12081ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended; 1209722a0cdcSGreg Clayton return false; 1210722a0cdcSGreg Clayton } 1211722a0cdcSGreg Clayton 1212b9c1b51eSKate Stone bool SBThread::IsStopped() { 1213b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1214b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1215b2e7d28eSJim Ingham 1216a75418dbSAndrew Kaylor if (exe_ctx.HasThreadScope()) 1217a75418dbSAndrew Kaylor return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1218a75418dbSAndrew Kaylor return false; 1219a75418dbSAndrew Kaylor } 1220a75418dbSAndrew Kaylor 1221b9c1b51eSKate Stone SBProcess SBThread::GetProcess() { 1222b9556accSGreg Clayton SBProcess sb_process; 1223b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1224b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1225b2e7d28eSJim Ingham 1226b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1227b9c1b51eSKate Stone // Have to go up to the target so we can get a shared pointer to our 1228b9c1b51eSKate Stone // process... 12291ac04c30SGreg Clayton sb_process.SetSP(exe_ctx.GetProcessSP()); 123030fdc8d8SChris Lattner } 1231ceb6b139SCaroline Tice 12325160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1233b9c1b51eSKate Stone if (log) { 1234481cef25SGreg Clayton SBStream frame_desc_strm; 1235b9556accSGreg Clayton sb_process.GetDescription(frame_desc_strm); 1236324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s", 1237324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1238324a1036SSaleem Abdulrasool static_cast<void *>(sb_process.GetSP().get()), 1239324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1240ceb6b139SCaroline Tice } 1241ceb6b139SCaroline Tice 1242b9556accSGreg Clayton return sb_process; 124330fdc8d8SChris Lattner } 124430fdc8d8SChris Lattner 1245b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() { 12465160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1247ceb6b139SCaroline Tice 1248ceb6b139SCaroline Tice uint32_t num_frames = 0; 1249bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1250bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12514fc6cb9cSJim Ingham 1252b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12537fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1254b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12551ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1256b9c1b51eSKate Stone } else { 1257c9858e4dSGreg Clayton if (log) 1258324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetNumFrames() => error: process is running", 1259324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1260c9858e4dSGreg Clayton } 12617fdf9ef1SGreg Clayton } 1262ceb6b139SCaroline Tice 1263ceb6b139SCaroline Tice if (log) 1264324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetNumFrames () => %u", 1265324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames); 1266ceb6b139SCaroline Tice 1267ceb6b139SCaroline Tice return num_frames; 126830fdc8d8SChris Lattner } 126930fdc8d8SChris Lattner 1270b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) { 12715160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1272ceb6b139SCaroline Tice 127330fdc8d8SChris Lattner SBFrame sb_frame; 1274b57e4a1bSJason Molenda StackFrameSP frame_sp; 1275bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1276bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12774fc6cb9cSJim Ingham 1278b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12797fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1280b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12811ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx); 1282b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1283b9c1b51eSKate Stone } else { 1284c9858e4dSGreg Clayton if (log) 1285b9c1b51eSKate Stone log->Printf( 1286b9c1b51eSKate Stone "SBThread(%p)::GetFrameAtIndex() => error: process is running", 1287324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1288c9858e4dSGreg Clayton } 12897fdf9ef1SGreg Clayton } 1290ceb6b139SCaroline Tice 1291b9c1b51eSKate Stone if (log) { 1292481cef25SGreg Clayton SBStream frame_desc_strm; 1293481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 12944838131bSGreg Clayton log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1295324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), idx, 1296b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1297ceb6b139SCaroline Tice } 1298ceb6b139SCaroline Tice 129930fdc8d8SChris Lattner return sb_frame; 130030fdc8d8SChris Lattner } 130130fdc8d8SChris Lattner 1302b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() { 13035160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1304f028a1fbSGreg Clayton 1305f028a1fbSGreg Clayton SBFrame sb_frame; 1306b57e4a1bSJason Molenda StackFrameSP frame_sp; 1307bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1308bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 13094fc6cb9cSJim Ingham 1310b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13117fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1312b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13131ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame(); 1314b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1315b9c1b51eSKate Stone } else { 1316c9858e4dSGreg Clayton if (log) 1317b9c1b51eSKate Stone log->Printf( 1318b9c1b51eSKate Stone "SBThread(%p)::GetSelectedFrame() => error: process is running", 1319324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1320c9858e4dSGreg Clayton } 13217fdf9ef1SGreg Clayton } 1322f028a1fbSGreg Clayton 1323b9c1b51eSKate Stone if (log) { 1324481cef25SGreg Clayton SBStream frame_desc_strm; 1325481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 1326f028a1fbSGreg Clayton log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1327324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1328b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1329f028a1fbSGreg Clayton } 1330f028a1fbSGreg Clayton 1331f028a1fbSGreg Clayton return sb_frame; 1332f028a1fbSGreg Clayton } 1333f028a1fbSGreg Clayton 1334b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) { 13355160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1336f028a1fbSGreg Clayton 1337f028a1fbSGreg Clayton SBFrame sb_frame; 1338b57e4a1bSJason Molenda StackFrameSP frame_sp; 1339bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1340bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 13414fc6cb9cSJim Ingham 1342b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13437fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1344b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13451ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 13461ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex(idx); 1347b9c1b51eSKate Stone if (frame_sp) { 13481ac04c30SGreg Clayton thread->SetSelectedFrame(frame_sp.get()); 1349b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1350f028a1fbSGreg Clayton } 1351b9c1b51eSKate Stone } else { 1352c9858e4dSGreg Clayton if (log) 1353b9c1b51eSKate Stone log->Printf( 1354b9c1b51eSKate Stone "SBThread(%p)::SetSelectedFrame() => error: process is running", 1355324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1356c9858e4dSGreg Clayton } 13577fdf9ef1SGreg Clayton } 1358f028a1fbSGreg Clayton 1359b9c1b51eSKate Stone if (log) { 1360481cef25SGreg Clayton SBStream frame_desc_strm; 1361481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 1362f028a1fbSGreg Clayton log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1363324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), idx, 1364b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1365f028a1fbSGreg Clayton } 1366f028a1fbSGreg Clayton return sb_frame; 1367f028a1fbSGreg Clayton } 1368f028a1fbSGreg Clayton 1369b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) { 13704f465cffSJim Ingham return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 13714f465cffSJim Ingham } 13724f465cffSJim Ingham 1373b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) { 13744f465cffSJim Ingham return Thread::ThreadEventData::GetStackFrameFromEvent(event.get()); 13754f465cffSJim Ingham } 13764f465cffSJim Ingham 1377b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) { 13784f465cffSJim Ingham return Thread::ThreadEventData::GetThreadFromEvent(event.get()); 13794f465cffSJim Ingham } 1380f028a1fbSGreg Clayton 1381b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const { 1382b9c1b51eSKate Stone return m_opaque_sp->GetThreadSP().get() == 1383b9c1b51eSKate Stone rhs.m_opaque_sp->GetThreadSP().get(); 138430fdc8d8SChris Lattner } 138530fdc8d8SChris Lattner 1386b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const { 1387b9c1b51eSKate Stone return m_opaque_sp->GetThreadSP().get() != 1388b9c1b51eSKate Stone rhs.m_opaque_sp->GetThreadSP().get(); 138930fdc8d8SChris Lattner } 1390dde9cff3SCaroline Tice 1391b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const { 13924f465cffSJim Ingham Stream &strm = status.ref(); 13934f465cffSJim Ingham 1394b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1395b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1396b2e7d28eSJim Ingham 1397b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13986a9767c7SJim Ingham exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true); 1399b9c1b51eSKate Stone } else 14004f465cffSJim Ingham strm.PutCString("No status"); 14014f465cffSJim Ingham 14024f465cffSJim Ingham return true; 14034f465cffSJim Ingham } 14044f465cffSJim Ingham 1405b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const { 14066a9767c7SJim Ingham return GetDescription(description, false); 14076a9767c7SJim Ingham } 14086a9767c7SJim Ingham 14096a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const { 1410da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1411da7bc7d0SGreg Clayton 1412b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1413b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1414b2e7d28eSJim Ingham 1415b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1416b9c1b51eSKate Stone exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, 14176a9767c7SJim Ingham LLDB_INVALID_THREAD_ID, 14186a9767c7SJim Ingham stop_format); 1419b9c1b51eSKate Stone // strm.Printf("SBThread: tid = 0x%4.4" PRIx64, 1420b9c1b51eSKate Stone // exe_ctx.GetThreadPtr()->GetID()); 1421b9c1b51eSKate Stone } else 1422da7bc7d0SGreg Clayton strm.PutCString("No value"); 1423ceb6b139SCaroline Tice 1424ceb6b139SCaroline Tice return true; 1425ceb6b139SCaroline Tice } 14265dd4916fSJason Molenda 1427b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) { 14285dd4916fSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1429bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1430bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 14315dd4916fSJason Molenda SBThread sb_origin_thread; 14325dd4916fSJason Molenda 1433b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 14345dd4916fSJason Molenda Process::StopLocker stop_locker; 1435b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 14367a2f7904SJason Molenda ThreadSP real_thread(exe_ctx.GetThreadSP()); 1437b9c1b51eSKate Stone if (real_thread) { 14385dd4916fSJason Molenda ConstString type_const(type); 14397a2f7904SJason Molenda Process *process = exe_ctx.GetProcessPtr(); 1440b9c1b51eSKate Stone if (process) { 14417a2f7904SJason Molenda SystemRuntime *runtime = process->GetSystemRuntime(); 1442b9c1b51eSKate Stone if (runtime) { 1443b9c1b51eSKate Stone ThreadSP new_thread_sp( 1444b9c1b51eSKate Stone runtime->GetExtendedBacktraceThread(real_thread, type_const)); 1445b9c1b51eSKate Stone if (new_thread_sp) { 1446b9c1b51eSKate Stone // Save this in the Process' ExtendedThreadList so a strong 144705097246SAdrian Prantl // pointer retains the object. 14487a2f7904SJason Molenda process->GetExtendedThreadList().AddThread(new_thread_sp); 14497a2f7904SJason Molenda sb_origin_thread.SetThread(new_thread_sp); 1450b9c1b51eSKate Stone if (log) { 1451a6e9130dSJason Molenda const char *queue_name = new_thread_sp->GetQueueName(); 1452a6e9130dSJason Molenda if (queue_name == NULL) 1453a6e9130dSJason Molenda queue_name = ""; 1454b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new " 1455b9c1b51eSKate Stone "extended Thread " 1456b9c1b51eSKate Stone "created (%p) with queue_id 0x%" PRIx64 1457b9c1b51eSKate Stone " queue name '%s'", 1458324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1459324a1036SSaleem Abdulrasool static_cast<void *>(new_thread_sp.get()), 1460b9c1b51eSKate Stone new_thread_sp->GetQueueID(), queue_name); 1461a6e9130dSJason Molenda } 1462a6e9130dSJason Molenda } 14637a2f7904SJason Molenda } 14645dd4916fSJason Molenda } 14655dd4916fSJason Molenda } 1466b9c1b51eSKate Stone } else { 14675dd4916fSJason Molenda if (log) 1468b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: " 1469b9c1b51eSKate Stone "process is running", 1470324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 14715dd4916fSJason Molenda } 14725dd4916fSJason Molenda } 14735dd4916fSJason Molenda 1474a6682a41SJonas Devlieghere if (log && !sb_origin_thread.IsValid()) 1475b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a " 1476b9c1b51eSKate Stone "Valid thread", 1477324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 14785dd4916fSJason Molenda return sb_origin_thread; 14795dd4916fSJason Molenda } 14808ee9cb58SJason Molenda 1481b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() { 14828ee9cb58SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 14838ee9cb58SJason Molenda if (thread_sp) 14848ee9cb58SJason Molenda return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 14858ee9cb58SJason Molenda return LLDB_INVALID_INDEX32; 14868ee9cb58SJason Molenda } 1487b4892cd2SJason Molenda 1488e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() { 1489e60bc53bSKuba Mracek ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1490e60bc53bSKuba Mracek if (!thread_sp) return SBValue(); 1491e60bc53bSKuba Mracek 1492e60bc53bSKuba Mracek return SBValue(thread_sp->GetCurrentException()); 1493e60bc53bSKuba Mracek } 1494e60bc53bSKuba Mracek 1495e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() { 1496e60bc53bSKuba Mracek ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1497e60bc53bSKuba Mracek if (!thread_sp) return SBThread(); 1498e60bc53bSKuba Mracek 1499e60bc53bSKuba Mracek return SBThread(thread_sp->GetCurrentExceptionBacktrace()); 1500c9e1190aSKuba Mracek } 1501e60bc53bSKuba Mracek 1502b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() { 1503b4892cd2SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1504b4892cd2SJason Molenda if (thread_sp) 1505b4892cd2SJason Molenda return thread_sp->SafeToCallFunctions(); 1506b4892cd2SJason Molenda return true; 1507b4892cd2SJason Molenda } 15082bdbfd50SJim Ingham 1509b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() { 15102bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 15112bdbfd50SJim Ingham if (thread_sp) 15122bdbfd50SJim Ingham return thread_sp.get(); 15132bdbfd50SJim Ingham else 15142bdbfd50SJim Ingham return NULL; 15152bdbfd50SJim Ingham } 15162bdbfd50SJim Ingham 1517b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() { 15182bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 15192bdbfd50SJim Ingham if (thread_sp) 15202bdbfd50SJim Ingham return thread_sp.get(); 15212bdbfd50SJim Ingham else 15222bdbfd50SJim Ingham return NULL; 15232bdbfd50SJim Ingham } 1524