1 //===-- SBThread.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/SBSymbolContext.h" 13 #include "lldb/API/SBFileSpec.h" 14 #include "lldb/API/SBStream.h" 15 #include "lldb/Breakpoint/BreakpointLocation.h" 16 #include "lldb/Core/Debugger.h" 17 #include "lldb/Core/State.h" 18 #include "lldb/Core/Stream.h" 19 #include "lldb/Core/StreamFile.h" 20 #include "lldb/Core/StructuredData.h" 21 #include "lldb/Interpreter/CommandInterpreter.h" 22 #include "lldb/Target/SystemRuntime.h" 23 #include "lldb/Target/Thread.h" 24 #include "lldb/Target/ThreadPlan.h" 25 #include "lldb/Target/Process.h" 26 #include "lldb/Target/Queue.h" 27 #include "lldb/Symbol/SymbolContext.h" 28 #include "lldb/Symbol/CompileUnit.h" 29 #include "lldb/Target/StopInfo.h" 30 #include "lldb/Target/Target.h" 31 #include "lldb/Target/ThreadPlan.h" 32 #include "lldb/Target/ThreadPlanPython.h" 33 #include "lldb/Target/ThreadPlanStepInstruction.h" 34 #include "lldb/Target/ThreadPlanStepOut.h" 35 #include "lldb/Target/ThreadPlanStepRange.h" 36 #include "lldb/Target/ThreadPlanStepInRange.h" 37 38 39 #include "lldb/API/SBAddress.h" 40 #include "lldb/API/SBDebugger.h" 41 #include "lldb/API/SBEvent.h" 42 #include "lldb/API/SBFrame.h" 43 #include "lldb/API/SBProcess.h" 44 #include "lldb/API/SBThreadPlan.h" 45 #include "lldb/API/SBValue.h" 46 47 using namespace lldb; 48 using namespace lldb_private; 49 50 //---------------------------------------------------------------------- 51 // Constructors 52 //---------------------------------------------------------------------- 53 SBThreadPlan::SBThreadPlan () 54 { 55 } 56 57 SBThreadPlan::SBThreadPlan (const ThreadPlanSP& lldb_object_sp) : 58 m_opaque_sp (lldb_object_sp) 59 { 60 } 61 62 SBThreadPlan::SBThreadPlan (const SBThreadPlan &rhs) : 63 m_opaque_sp (rhs.m_opaque_sp) 64 { 65 66 } 67 68 SBThreadPlan::SBThreadPlan (lldb::SBThread &sb_thread, const char *class_name) 69 { 70 Thread *thread = sb_thread.get(); 71 if (thread) 72 m_opaque_sp.reset(new ThreadPlanPython(*thread, class_name)); 73 } 74 75 //---------------------------------------------------------------------- 76 // Assignment operator 77 //---------------------------------------------------------------------- 78 79 const lldb::SBThreadPlan & 80 SBThreadPlan::operator = (const SBThreadPlan &rhs) 81 { 82 if (this != &rhs) 83 m_opaque_sp = rhs.m_opaque_sp; 84 return *this; 85 } 86 //---------------------------------------------------------------------- 87 // Destructor 88 //---------------------------------------------------------------------- 89 SBThreadPlan::~SBThreadPlan() 90 { 91 } 92 93 lldb_private::ThreadPlan * 94 SBThreadPlan::get() 95 { 96 return m_opaque_sp.get(); 97 } 98 99 bool 100 SBThreadPlan::IsValid() const 101 { 102 return m_opaque_sp.get() != NULL; 103 } 104 105 void 106 SBThreadPlan::Clear () 107 { 108 m_opaque_sp.reset(); 109 } 110 111 lldb::StopReason 112 SBThreadPlan::GetStopReason() 113 { 114 return eStopReasonNone; 115 } 116 117 size_t 118 SBThreadPlan::GetStopReasonDataCount() 119 { 120 return 0; 121 } 122 123 uint64_t 124 SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) 125 { 126 return 0; 127 } 128 129 SBThread 130 SBThreadPlan::GetThread () const 131 { 132 if (m_opaque_sp) 133 { 134 return SBThread(m_opaque_sp->GetThread().shared_from_this()); 135 } 136 else 137 return SBThread(); 138 } 139 140 bool 141 SBThreadPlan::GetDescription (lldb::SBStream &description) const 142 { 143 if (m_opaque_sp) 144 { 145 m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull); 146 } 147 else 148 { 149 description.Printf("Empty SBThreadPlan"); 150 } 151 return true; 152 } 153 154 void 155 SBThreadPlan::SetThreadPlan (const ThreadPlanSP& lldb_object_sp) 156 { 157 m_opaque_sp = lldb_object_sp; 158 } 159 160 void 161 SBThreadPlan::SetPlanComplete (bool success) 162 { 163 if (m_opaque_sp) 164 m_opaque_sp->SetPlanComplete (success); 165 } 166 167 bool 168 SBThreadPlan::IsPlanComplete() 169 { 170 if (m_opaque_sp) 171 return m_opaque_sp->IsPlanComplete(); 172 else 173 return true; 174 } 175 176 bool 177 SBThreadPlan::IsValid() 178 { 179 if (m_opaque_sp) 180 return m_opaque_sp->ValidatePlan(nullptr); 181 else 182 return false; 183 } 184 185 // This section allows an SBThreadPlan to push another of the common types of plans... 186 // 187 // FIXME, you should only be able to queue thread plans from inside the methods of a 188 // Scripted Thread Plan. Need a way to enforce that. 189 190 SBThreadPlan 191 SBThreadPlan::QueueThreadPlanForStepOverRange (SBAddress &sb_start_address, 192 lldb::addr_t size) 193 { 194 if (m_opaque_sp) 195 { 196 Address *start_address = sb_start_address.get(); 197 if (!start_address) 198 { 199 return SBThreadPlan(); 200 } 201 202 AddressRange range (*start_address, size); 203 SymbolContext sc; 204 start_address->CalculateSymbolContext(&sc); 205 return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange (false, 206 range, 207 sc, 208 eAllThreads)); 209 } 210 else 211 { 212 return SBThreadPlan(); 213 } 214 } 215 216 SBThreadPlan 217 SBThreadPlan::QueueThreadPlanForStepInRange (SBAddress &sb_start_address, 218 lldb::addr_t size) 219 { 220 if (m_opaque_sp) 221 { 222 Address *start_address = sb_start_address.get(); 223 if (!start_address) 224 { 225 return SBThreadPlan(); 226 } 227 228 AddressRange range (*start_address, size); 229 SymbolContext sc; 230 start_address->CalculateSymbolContext(&sc); 231 return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepInRange (false, 232 range, 233 sc, 234 NULL, 235 eAllThreads)); 236 } 237 else 238 { 239 return SBThreadPlan(); 240 } 241 } 242 243 SBThreadPlan 244 SBThreadPlan::QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn) 245 { 246 if (m_opaque_sp) 247 { 248 SymbolContext sc; 249 sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything); 250 return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOut (false, 251 &sc, 252 first_insn, 253 false, 254 eVoteYes, 255 eVoteNoOpinion, 256 frame_idx_to_step_to)); 257 } 258 else 259 { 260 return SBThreadPlan(); 261 } 262 } 263 264 SBThreadPlan 265 SBThreadPlan::QueueThreadPlanForRunToAddress (SBAddress sb_address) 266 { 267 if (m_opaque_sp) 268 { 269 Address *address = sb_address.get(); 270 if (!address) 271 return SBThreadPlan(); 272 273 return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress (false, 274 *address, 275 false)); 276 } 277 else 278 { 279 return SBThreadPlan(); 280 } 281 } 282 283 284