1 //===-- SBThreadPlan.cpp ----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/API/SBThread.h" 11 12 #include "lldb/API/SBFileSpec.h" 13 #include "lldb/API/SBStream.h" 14 #include "lldb/API/SBSymbolContext.h" 15 #include "lldb/Breakpoint/BreakpointLocation.h" 16 #include "lldb/Core/Debugger.h" 17 #include "lldb/Core/State.h" 18 #include "lldb/Core/StreamFile.h" 19 #include "lldb/Interpreter/CommandInterpreter.h" 20 #include "lldb/Symbol/CompileUnit.h" 21 #include "lldb/Symbol/SymbolContext.h" 22 #include "lldb/Target/Process.h" 23 #include "lldb/Target/Queue.h" 24 #include "lldb/Target/StopInfo.h" 25 #include "lldb/Target/SystemRuntime.h" 26 #include "lldb/Target/Target.h" 27 #include "lldb/Target/Thread.h" 28 #include "lldb/Target/ThreadPlan.h" 29 #include "lldb/Target/ThreadPlanPython.h" 30 #include "lldb/Target/ThreadPlanStepInRange.h" 31 #include "lldb/Target/ThreadPlanStepInstruction.h" 32 #include "lldb/Target/ThreadPlanStepOut.h" 33 #include "lldb/Target/ThreadPlanStepRange.h" 34 #include "lldb/Utility/Stream.h" 35 #include "lldb/Utility/StructuredData.h" 36 37 #include "lldb/API/SBAddress.h" 38 #include "lldb/API/SBDebugger.h" 39 #include "lldb/API/SBEvent.h" 40 #include "lldb/API/SBFrame.h" 41 #include "lldb/API/SBProcess.h" 42 #include "lldb/API/SBThreadPlan.h" 43 #include "lldb/API/SBValue.h" 44 45 using namespace lldb; 46 using namespace lldb_private; 47 48 //---------------------------------------------------------------------- 49 // Constructors 50 //---------------------------------------------------------------------- 51 SBThreadPlan::SBThreadPlan() {} 52 53 SBThreadPlan::SBThreadPlan(const ThreadPlanSP &lldb_object_sp) 54 : m_opaque_sp(lldb_object_sp) {} 55 56 SBThreadPlan::SBThreadPlan(const SBThreadPlan &rhs) 57 : m_opaque_sp(rhs.m_opaque_sp) {} 58 59 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) { 60 Thread *thread = sb_thread.get(); 61 if (thread) 62 m_opaque_sp.reset(new ThreadPlanPython(*thread, class_name)); 63 } 64 65 //---------------------------------------------------------------------- 66 // Assignment operator 67 //---------------------------------------------------------------------- 68 69 const lldb::SBThreadPlan &SBThreadPlan::operator=(const SBThreadPlan &rhs) { 70 if (this != &rhs) 71 m_opaque_sp = rhs.m_opaque_sp; 72 return *this; 73 } 74 //---------------------------------------------------------------------- 75 // Destructor 76 //---------------------------------------------------------------------- 77 SBThreadPlan::~SBThreadPlan() {} 78 79 lldb_private::ThreadPlan *SBThreadPlan::get() { return m_opaque_sp.get(); } 80 81 bool SBThreadPlan::IsValid() const { return m_opaque_sp.get() != NULL; } 82 83 void SBThreadPlan::Clear() { m_opaque_sp.reset(); } 84 85 lldb::StopReason SBThreadPlan::GetStopReason() { return eStopReasonNone; } 86 87 size_t SBThreadPlan::GetStopReasonDataCount() { return 0; } 88 89 uint64_t SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) { return 0; } 90 91 SBThread SBThreadPlan::GetThread() const { 92 if (m_opaque_sp) { 93 return SBThread(m_opaque_sp->GetThread().shared_from_this()); 94 } else 95 return SBThread(); 96 } 97 98 bool SBThreadPlan::GetDescription(lldb::SBStream &description) const { 99 if (m_opaque_sp) { 100 m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull); 101 } else { 102 description.Printf("Empty SBThreadPlan"); 103 } 104 return true; 105 } 106 107 void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_sp) { 108 m_opaque_sp = lldb_object_sp; 109 } 110 111 void SBThreadPlan::SetPlanComplete(bool success) { 112 if (m_opaque_sp) 113 m_opaque_sp->SetPlanComplete(success); 114 } 115 116 bool SBThreadPlan::IsPlanComplete() { 117 if (m_opaque_sp) 118 return m_opaque_sp->IsPlanComplete(); 119 else 120 return true; 121 } 122 123 bool SBThreadPlan::IsPlanStale() { 124 if (m_opaque_sp) 125 return m_opaque_sp->IsPlanStale(); 126 else 127 return true; 128 } 129 130 bool SBThreadPlan::IsValid() { 131 if (m_opaque_sp) 132 return m_opaque_sp->ValidatePlan(nullptr); 133 else 134 return false; 135 } 136 137 // This section allows an SBThreadPlan to push another of the common types of 138 // plans... 139 // 140 // FIXME, you should only be able to queue thread plans from inside the methods 141 // of a 142 // Scripted Thread Plan. Need a way to enforce that. 143 144 SBThreadPlan 145 SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address, 146 lldb::addr_t size) { 147 if (m_opaque_sp) { 148 Address *start_address = sb_start_address.get(); 149 if (!start_address) { 150 return SBThreadPlan(); 151 } 152 153 AddressRange range(*start_address, size); 154 SymbolContext sc; 155 start_address->CalculateSymbolContext(&sc); 156 return SBThreadPlan( 157 m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange( 158 false, range, sc, eAllThreads)); 159 } else { 160 return SBThreadPlan(); 161 } 162 } 163 164 SBThreadPlan 165 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address, 166 lldb::addr_t size) { 167 if (m_opaque_sp) { 168 Address *start_address = sb_start_address.get(); 169 if (!start_address) { 170 return SBThreadPlan(); 171 } 172 173 AddressRange range(*start_address, size); 174 SymbolContext sc; 175 start_address->CalculateSymbolContext(&sc); 176 return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepInRange( 177 false, range, sc, NULL, eAllThreads)); 178 } else { 179 return SBThreadPlan(); 180 } 181 } 182 183 SBThreadPlan 184 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, 185 bool first_insn) { 186 if (m_opaque_sp) { 187 SymbolContext sc; 188 sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext( 189 lldb::eSymbolContextEverything); 190 return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOut( 191 false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion, 192 frame_idx_to_step_to)); 193 } else { 194 return SBThreadPlan(); 195 } 196 } 197 198 SBThreadPlan 199 SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) { 200 if (m_opaque_sp) { 201 Address *address = sb_address.get(); 202 if (!address) 203 return SBThreadPlan(); 204 205 return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress( 206 false, *address, false)); 207 } else { 208 return SBThreadPlan(); 209 } 210 } 211