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/StreamFile.h" 18 #include "lldb/Interpreter/CommandInterpreter.h" 19 #include "lldb/Symbol/CompileUnit.h" 20 #include "lldb/Symbol/SymbolContext.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/Queue.h" 23 #include "lldb/Target/StopInfo.h" 24 #include "lldb/Target/SystemRuntime.h" 25 #include "lldb/Target/Target.h" 26 #include "lldb/Target/Thread.h" 27 #include "lldb/Target/ThreadPlan.h" 28 #include "lldb/Target/ThreadPlanPython.h" 29 #include "lldb/Target/ThreadPlanStepInRange.h" 30 #include "lldb/Target/ThreadPlanStepInstruction.h" 31 #include "lldb/Target/ThreadPlanStepOut.h" 32 #include "lldb/Target/ThreadPlanStepRange.h" 33 #include "lldb/Utility/State.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 Scripted Thread Plan. Need a way to enforce that. 142 143 SBThreadPlan 144 SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address, 145 lldb::addr_t size) { 146 if (m_opaque_sp) { 147 Address *start_address = sb_start_address.get(); 148 if (!start_address) { 149 return SBThreadPlan(); 150 } 151 152 AddressRange range(*start_address, size); 153 SymbolContext sc; 154 start_address->CalculateSymbolContext(&sc); 155 return SBThreadPlan( 156 m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange( 157 false, range, sc, eAllThreads)); 158 } else { 159 return SBThreadPlan(); 160 } 161 } 162 163 SBThreadPlan 164 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address, 165 lldb::addr_t size) { 166 if (m_opaque_sp) { 167 Address *start_address = sb_start_address.get(); 168 if (!start_address) { 169 return SBThreadPlan(); 170 } 171 172 AddressRange range(*start_address, size); 173 SymbolContext sc; 174 start_address->CalculateSymbolContext(&sc); 175 return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepInRange( 176 false, range, sc, NULL, eAllThreads)); 177 } else { 178 return SBThreadPlan(); 179 } 180 } 181 182 SBThreadPlan 183 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, 184 bool first_insn) { 185 if (m_opaque_sp) { 186 SymbolContext sc; 187 sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext( 188 lldb::eSymbolContextEverything); 189 return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOut( 190 false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion, 191 frame_idx_to_step_to)); 192 } else { 193 return SBThreadPlan(); 194 } 195 } 196 197 SBThreadPlan 198 SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) { 199 if (m_opaque_sp) { 200 Address *address = sb_address.get(); 201 if (!address) 202 return SBThreadPlan(); 203 204 return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress( 205 false, *address, false)); 206 } else { 207 return SBThreadPlan(); 208 } 209 } 210 211 SBThreadPlan 212 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) { 213 if (m_opaque_sp) { 214 return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted( 215 false, script_class_name, false)); 216 } else { 217 return SBThreadPlan(); 218 } 219 } 220