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::IsPlanStale() 178 { 179 if (m_opaque_sp) 180 return m_opaque_sp->IsPlanStale(); 181 else 182 return true; 183 } 184 185 bool 186 SBThreadPlan::IsValid() 187 { 188 if (m_opaque_sp) 189 return m_opaque_sp->ValidatePlan(nullptr); 190 else 191 return false; 192 } 193 194 // This section allows an SBThreadPlan to push another of the common types of plans... 195 // 196 // FIXME, you should only be able to queue thread plans from inside the methods of a 197 // Scripted Thread Plan. Need a way to enforce that. 198 199 SBThreadPlan 200 SBThreadPlan::QueueThreadPlanForStepOverRange (SBAddress &sb_start_address, 201 lldb::addr_t size) 202 { 203 if (m_opaque_sp) 204 { 205 Address *start_address = sb_start_address.get(); 206 if (!start_address) 207 { 208 return SBThreadPlan(); 209 } 210 211 AddressRange range (*start_address, size); 212 SymbolContext sc; 213 start_address->CalculateSymbolContext(&sc); 214 return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange (false, 215 range, 216 sc, 217 eAllThreads)); 218 } 219 else 220 { 221 return SBThreadPlan(); 222 } 223 } 224 225 SBThreadPlan 226 SBThreadPlan::QueueThreadPlanForStepInRange (SBAddress &sb_start_address, 227 lldb::addr_t size) 228 { 229 if (m_opaque_sp) 230 { 231 Address *start_address = sb_start_address.get(); 232 if (!start_address) 233 { 234 return SBThreadPlan(); 235 } 236 237 AddressRange range (*start_address, size); 238 SymbolContext sc; 239 start_address->CalculateSymbolContext(&sc); 240 return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepInRange (false, 241 range, 242 sc, 243 NULL, 244 eAllThreads)); 245 } 246 else 247 { 248 return SBThreadPlan(); 249 } 250 } 251 252 SBThreadPlan 253 SBThreadPlan::QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn) 254 { 255 if (m_opaque_sp) 256 { 257 SymbolContext sc; 258 sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything); 259 return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOut (false, 260 &sc, 261 first_insn, 262 false, 263 eVoteYes, 264 eVoteNoOpinion, 265 frame_idx_to_step_to)); 266 } 267 else 268 { 269 return SBThreadPlan(); 270 } 271 } 272 273 SBThreadPlan 274 SBThreadPlan::QueueThreadPlanForRunToAddress (SBAddress sb_address) 275 { 276 if (m_opaque_sp) 277 { 278 Address *address = sb_address.get(); 279 if (!address) 280 return SBThreadPlan(); 281 282 return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress (false, 283 *address, 284 false)); 285 } 286 else 287 { 288 return SBThreadPlan(); 289 } 290 } 291 292 293