1*30fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner 10*30fdc8d8SChris Lattner #include "SBThread.h" 11*30fdc8d8SChris Lattner 12*30fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h" 13*30fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h" 14*30fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 15*30fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h" 16*30fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 17*30fdc8d8SChris Lattner #include "lldb/Target/Process.h" 18*30fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h" 19*30fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h" 20*30fdc8d8SChris Lattner #include "lldb/Target/Target.h" 21*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 22*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanContinue.h" 23*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 24*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 25*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 26*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h" 27*30fdc8d8SChris Lattner 28*30fdc8d8SChris Lattner 29*30fdc8d8SChris Lattner #include "SBAddress.h" 30*30fdc8d8SChris Lattner #include "SBFrame.h" 31*30fdc8d8SChris Lattner #include "SBSourceManager.h" 32*30fdc8d8SChris Lattner #include "SBDebugger.h" 33*30fdc8d8SChris Lattner #include "SBProcess.h" 34*30fdc8d8SChris Lattner 35*30fdc8d8SChris Lattner using namespace lldb; 36*30fdc8d8SChris Lattner using namespace lldb_private; 37*30fdc8d8SChris Lattner 38*30fdc8d8SChris Lattner SBThread::SBThread () : 39*30fdc8d8SChris Lattner m_lldb_object_sp () 40*30fdc8d8SChris Lattner { 41*30fdc8d8SChris Lattner } 42*30fdc8d8SChris Lattner 43*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 44*30fdc8d8SChris Lattner // Thread constructor 45*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 46*30fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) : 47*30fdc8d8SChris Lattner m_lldb_object_sp (lldb_object_sp) 48*30fdc8d8SChris Lattner { 49*30fdc8d8SChris Lattner } 50*30fdc8d8SChris Lattner 51*30fdc8d8SChris Lattner SBThread::SBThread (const SBThread &rhs) 52*30fdc8d8SChris Lattner { 53*30fdc8d8SChris Lattner m_lldb_object_sp = rhs.m_lldb_object_sp; 54*30fdc8d8SChris Lattner } 55*30fdc8d8SChris Lattner 56*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 57*30fdc8d8SChris Lattner // Destructor 58*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 59*30fdc8d8SChris Lattner SBThread::~SBThread() 60*30fdc8d8SChris Lattner { 61*30fdc8d8SChris Lattner } 62*30fdc8d8SChris Lattner 63*30fdc8d8SChris Lattner bool 64*30fdc8d8SChris Lattner SBThread::IsValid() const 65*30fdc8d8SChris Lattner { 66*30fdc8d8SChris Lattner return m_lldb_object_sp != NULL; 67*30fdc8d8SChris Lattner } 68*30fdc8d8SChris Lattner 69*30fdc8d8SChris Lattner StopReason 70*30fdc8d8SChris Lattner SBThread::GetStopReason() 71*30fdc8d8SChris Lattner { 72*30fdc8d8SChris Lattner if (m_lldb_object_sp) 73*30fdc8d8SChris Lattner { 74*30fdc8d8SChris Lattner lldb_private::Thread::StopInfo thread_stop_info; 75*30fdc8d8SChris Lattner if (m_lldb_object_sp->GetStopInfo(&thread_stop_info)) 76*30fdc8d8SChris Lattner return thread_stop_info.GetStopReason(); 77*30fdc8d8SChris Lattner } 78*30fdc8d8SChris Lattner return eStopReasonInvalid; 79*30fdc8d8SChris Lattner } 80*30fdc8d8SChris Lattner 81*30fdc8d8SChris Lattner size_t 82*30fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len) 83*30fdc8d8SChris Lattner { 84*30fdc8d8SChris Lattner if (m_lldb_object_sp) 85*30fdc8d8SChris Lattner { 86*30fdc8d8SChris Lattner lldb_private::Thread::StopInfo thread_stop_info; 87*30fdc8d8SChris Lattner if (m_lldb_object_sp->GetStopInfo(&thread_stop_info)) 88*30fdc8d8SChris Lattner { 89*30fdc8d8SChris Lattner const char *stop_desc = thread_stop_info.GetStopDescription(); 90*30fdc8d8SChris Lattner if (stop_desc) 91*30fdc8d8SChris Lattner { 92*30fdc8d8SChris Lattner if (dst) 93*30fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc); 94*30fdc8d8SChris Lattner else 95*30fdc8d8SChris Lattner { 96*30fdc8d8SChris Lattner // NULL dst passed in, return the length needed to contain the description 97*30fdc8d8SChris Lattner return ::strlen (stop_desc) + 1; // Include the NULL byte for size 98*30fdc8d8SChris Lattner } 99*30fdc8d8SChris Lattner } 100*30fdc8d8SChris Lattner else 101*30fdc8d8SChris Lattner { 102*30fdc8d8SChris Lattner const char *stop_desc = NULL; 103*30fdc8d8SChris Lattner size_t stop_desc_len = 0; 104*30fdc8d8SChris Lattner switch (thread_stop_info.GetStopReason()) 105*30fdc8d8SChris Lattner { 106*30fdc8d8SChris Lattner case eStopReasonTrace: 107*30fdc8d8SChris Lattner case eStopReasonPlanComplete: 108*30fdc8d8SChris Lattner { 109*30fdc8d8SChris Lattner static char trace_desc[] = "step"; 110*30fdc8d8SChris Lattner stop_desc = trace_desc; 111*30fdc8d8SChris Lattner stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 112*30fdc8d8SChris Lattner } 113*30fdc8d8SChris Lattner break; 114*30fdc8d8SChris Lattner 115*30fdc8d8SChris Lattner case eStopReasonBreakpoint: 116*30fdc8d8SChris Lattner { 117*30fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 118*30fdc8d8SChris Lattner stop_desc = bp_desc; 119*30fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 120*30fdc8d8SChris Lattner } 121*30fdc8d8SChris Lattner break; 122*30fdc8d8SChris Lattner 123*30fdc8d8SChris Lattner case eStopReasonWatchpoint: 124*30fdc8d8SChris Lattner { 125*30fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 126*30fdc8d8SChris Lattner stop_desc = wp_desc; 127*30fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 128*30fdc8d8SChris Lattner } 129*30fdc8d8SChris Lattner break; 130*30fdc8d8SChris Lattner 131*30fdc8d8SChris Lattner case eStopReasonSignal: 132*30fdc8d8SChris Lattner { 133*30fdc8d8SChris Lattner stop_desc = m_lldb_object_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (thread_stop_info.GetSignal()); 134*30fdc8d8SChris Lattner if (stop_desc == NULL || stop_desc[0] == '\0') 135*30fdc8d8SChris Lattner { 136*30fdc8d8SChris Lattner static char signal_desc[] = "signal"; 137*30fdc8d8SChris Lattner stop_desc = signal_desc; 138*30fdc8d8SChris Lattner stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 139*30fdc8d8SChris Lattner } 140*30fdc8d8SChris Lattner } 141*30fdc8d8SChris Lattner break; 142*30fdc8d8SChris Lattner 143*30fdc8d8SChris Lattner case eStopReasonException: 144*30fdc8d8SChris Lattner { 145*30fdc8d8SChris Lattner char exc_desc[] = "exception"; 146*30fdc8d8SChris Lattner stop_desc = exc_desc; 147*30fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 148*30fdc8d8SChris Lattner } 149*30fdc8d8SChris Lattner break; 150*30fdc8d8SChris Lattner } 151*30fdc8d8SChris Lattner 152*30fdc8d8SChris Lattner if (stop_desc && stop_desc[0]) 153*30fdc8d8SChris Lattner { 154*30fdc8d8SChris Lattner if (dst) 155*30fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 156*30fdc8d8SChris Lattner 157*30fdc8d8SChris Lattner if (stop_desc_len == 0) 158*30fdc8d8SChris Lattner stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 159*30fdc8d8SChris Lattner 160*30fdc8d8SChris Lattner return stop_desc_len; 161*30fdc8d8SChris Lattner } 162*30fdc8d8SChris Lattner } 163*30fdc8d8SChris Lattner } 164*30fdc8d8SChris Lattner } 165*30fdc8d8SChris Lattner if (dst) 166*30fdc8d8SChris Lattner *dst = 0; 167*30fdc8d8SChris Lattner return 0; 168*30fdc8d8SChris Lattner } 169*30fdc8d8SChris Lattner 170*30fdc8d8SChris Lattner void 171*30fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp) 172*30fdc8d8SChris Lattner { 173*30fdc8d8SChris Lattner m_lldb_object_sp = lldb_object_sp; 174*30fdc8d8SChris Lattner } 175*30fdc8d8SChris Lattner 176*30fdc8d8SChris Lattner 177*30fdc8d8SChris Lattner lldb::tid_t 178*30fdc8d8SChris Lattner SBThread::GetThreadID () const 179*30fdc8d8SChris Lattner { 180*30fdc8d8SChris Lattner if (m_lldb_object_sp) 181*30fdc8d8SChris Lattner return m_lldb_object_sp->GetID(); 182*30fdc8d8SChris Lattner else 183*30fdc8d8SChris Lattner return LLDB_INVALID_THREAD_ID; 184*30fdc8d8SChris Lattner } 185*30fdc8d8SChris Lattner 186*30fdc8d8SChris Lattner uint32_t 187*30fdc8d8SChris Lattner SBThread::GetIndexID () const 188*30fdc8d8SChris Lattner { 189*30fdc8d8SChris Lattner if (m_lldb_object_sp) 190*30fdc8d8SChris Lattner return m_lldb_object_sp->GetIndexID(); 191*30fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 192*30fdc8d8SChris Lattner } 193*30fdc8d8SChris Lattner const char * 194*30fdc8d8SChris Lattner SBThread::GetName () const 195*30fdc8d8SChris Lattner { 196*30fdc8d8SChris Lattner if (m_lldb_object_sp) 197*30fdc8d8SChris Lattner return m_lldb_object_sp->GetName(); 198*30fdc8d8SChris Lattner return NULL; 199*30fdc8d8SChris Lattner } 200*30fdc8d8SChris Lattner 201*30fdc8d8SChris Lattner const char * 202*30fdc8d8SChris Lattner SBThread::GetQueueName () const 203*30fdc8d8SChris Lattner { 204*30fdc8d8SChris Lattner if (m_lldb_object_sp) 205*30fdc8d8SChris Lattner return m_lldb_object_sp->GetQueueName(); 206*30fdc8d8SChris Lattner return NULL; 207*30fdc8d8SChris Lattner } 208*30fdc8d8SChris Lattner 209*30fdc8d8SChris Lattner 210*30fdc8d8SChris Lattner void 211*30fdc8d8SChris Lattner SBThread::DisplayFramesForCurrentContext (FILE *out, 212*30fdc8d8SChris Lattner FILE *err, 213*30fdc8d8SChris Lattner uint32_t first_frame, 214*30fdc8d8SChris Lattner uint32_t num_frames, 215*30fdc8d8SChris Lattner bool show_frame_info, 216*30fdc8d8SChris Lattner uint32_t num_frames_with_source, 217*30fdc8d8SChris Lattner uint32_t source_lines_before, 218*30fdc8d8SChris Lattner uint32_t source_lines_after) 219*30fdc8d8SChris Lattner { 220*30fdc8d8SChris Lattner if ((out == NULL) || (err == NULL)) 221*30fdc8d8SChris Lattner return; 222*30fdc8d8SChris Lattner 223*30fdc8d8SChris Lattner if (m_lldb_object_sp) 224*30fdc8d8SChris Lattner { 225*30fdc8d8SChris Lattner uint32_t num_stack_frames = m_lldb_object_sp->GetStackFrameCount (); 226*30fdc8d8SChris Lattner StackFrameSP frame_sp; 227*30fdc8d8SChris Lattner int frame_idx = 0; 228*30fdc8d8SChris Lattner 229*30fdc8d8SChris Lattner for (frame_idx = first_frame; frame_idx < first_frame + num_frames; ++frame_idx) 230*30fdc8d8SChris Lattner { 231*30fdc8d8SChris Lattner if (frame_idx >= num_stack_frames) 232*30fdc8d8SChris Lattner break; 233*30fdc8d8SChris Lattner 234*30fdc8d8SChris Lattner frame_sp = m_lldb_object_sp->GetStackFrameAtIndex (frame_idx); 235*30fdc8d8SChris Lattner if (!frame_sp) 236*30fdc8d8SChris Lattner break; 237*30fdc8d8SChris Lattner 238*30fdc8d8SChris Lattner SBFrame sb_frame (frame_sp); 239*30fdc8d8SChris Lattner if (DisplaySingleFrameForCurrentContext (out, 240*30fdc8d8SChris Lattner err, 241*30fdc8d8SChris Lattner sb_frame, 242*30fdc8d8SChris Lattner show_frame_info, 243*30fdc8d8SChris Lattner num_frames_with_source > first_frame - frame_idx, 244*30fdc8d8SChris Lattner source_lines_before, 245*30fdc8d8SChris Lattner source_lines_after) == false) 246*30fdc8d8SChris Lattner break; 247*30fdc8d8SChris Lattner } 248*30fdc8d8SChris Lattner } 249*30fdc8d8SChris Lattner } 250*30fdc8d8SChris Lattner 251*30fdc8d8SChris Lattner bool 252*30fdc8d8SChris Lattner SBThread::DisplaySingleFrameForCurrentContext (FILE *out, 253*30fdc8d8SChris Lattner FILE *err, 254*30fdc8d8SChris Lattner SBFrame &frame, 255*30fdc8d8SChris Lattner bool show_frame_info, 256*30fdc8d8SChris Lattner bool show_source, 257*30fdc8d8SChris Lattner uint32_t source_lines_after, 258*30fdc8d8SChris Lattner uint32_t source_lines_before) 259*30fdc8d8SChris Lattner { 260*30fdc8d8SChris Lattner bool success = false; 261*30fdc8d8SChris Lattner 262*30fdc8d8SChris Lattner if ((out == NULL) || (err == NULL)) 263*30fdc8d8SChris Lattner return false; 264*30fdc8d8SChris Lattner 265*30fdc8d8SChris Lattner if (m_lldb_object_sp && frame.IsValid()) 266*30fdc8d8SChris Lattner { 267*30fdc8d8SChris Lattner 268*30fdc8d8SChris Lattner StreamFile str (out); 269*30fdc8d8SChris Lattner 270*30fdc8d8SChris Lattner SBSymbolContext sc(frame.GetSymbolContext(eSymbolContextEverything)); 271*30fdc8d8SChris Lattner 272*30fdc8d8SChris Lattner if (show_frame_info && sc.IsValid()) 273*30fdc8d8SChris Lattner { 274*30fdc8d8SChris Lattner user_id_t frame_idx = (user_id_t) frame.GetFrameID(); 275*30fdc8d8SChris Lattner lldb::addr_t pc = frame.GetPC(); 276*30fdc8d8SChris Lattner ::fprintf (out, 277*30fdc8d8SChris Lattner " frame #%u: tid = 0x%4.4x, pc = 0x%llx ", 278*30fdc8d8SChris Lattner frame_idx, 279*30fdc8d8SChris Lattner GetThreadID(), 280*30fdc8d8SChris Lattner pc); 281*30fdc8d8SChris Lattner sc->DumpStopContext (&str, &m_lldb_object_sp->GetProcess(), *frame.GetPCAddress()); 282*30fdc8d8SChris Lattner fprintf (out, "\n"); 283*30fdc8d8SChris Lattner success = true; 284*30fdc8d8SChris Lattner } 285*30fdc8d8SChris Lattner 286*30fdc8d8SChris Lattner SBCompileUnit comp_unit(sc.GetCompileUnit()); 287*30fdc8d8SChris Lattner if (show_source && comp_unit.IsValid()) 288*30fdc8d8SChris Lattner { 289*30fdc8d8SChris Lattner success = false; 290*30fdc8d8SChris Lattner SBLineEntry line_entry; 291*30fdc8d8SChris Lattner if (line_entry.IsValid()) 292*30fdc8d8SChris Lattner { 293*30fdc8d8SChris Lattner SBSourceManager& source_manager = SBDebugger::GetSourceManager(); 294*30fdc8d8SChris Lattner SBFileSpec line_entry_file_spec = line_entry.GetFileSpec(); 295*30fdc8d8SChris Lattner 296*30fdc8d8SChris Lattner if (line_entry_file_spec.IsValid()) 297*30fdc8d8SChris Lattner { 298*30fdc8d8SChris Lattner source_manager.DisplaySourceLinesWithLineNumbers (line_entry_file_spec, 299*30fdc8d8SChris Lattner line_entry.GetLine(), 300*30fdc8d8SChris Lattner source_lines_after, 301*30fdc8d8SChris Lattner source_lines_before, "->", 302*30fdc8d8SChris Lattner out); 303*30fdc8d8SChris Lattner success = true; 304*30fdc8d8SChris Lattner } 305*30fdc8d8SChris Lattner } 306*30fdc8d8SChris Lattner } 307*30fdc8d8SChris Lattner } 308*30fdc8d8SChris Lattner return success; 309*30fdc8d8SChris Lattner } 310*30fdc8d8SChris Lattner 311*30fdc8d8SChris Lattner void 312*30fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads) 313*30fdc8d8SChris Lattner { 314*30fdc8d8SChris Lattner if (m_lldb_object_sp) 315*30fdc8d8SChris Lattner { 316*30fdc8d8SChris Lattner bool abort_other_plans = true; 317*30fdc8d8SChris Lattner StackFrameSP frame_sp(m_lldb_object_sp->GetStackFrameAtIndex (0)); 318*30fdc8d8SChris Lattner 319*30fdc8d8SChris Lattner if (frame_sp) 320*30fdc8d8SChris Lattner { 321*30fdc8d8SChris Lattner if (frame_sp->HasDebugInformation ()) 322*30fdc8d8SChris Lattner { 323*30fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 324*30fdc8d8SChris Lattner m_lldb_object_sp->QueueThreadPlanForStepRange (abort_other_plans, 325*30fdc8d8SChris Lattner eStepTypeOver, 326*30fdc8d8SChris Lattner sc.line_entry.range, 327*30fdc8d8SChris Lattner sc, 328*30fdc8d8SChris Lattner stop_other_threads); 329*30fdc8d8SChris Lattner 330*30fdc8d8SChris Lattner } 331*30fdc8d8SChris Lattner else 332*30fdc8d8SChris Lattner { 333*30fdc8d8SChris Lattner m_lldb_object_sp->QueueThreadPlanForStepSingleInstruction (true, 334*30fdc8d8SChris Lattner abort_other_plans, 335*30fdc8d8SChris Lattner stop_other_threads); 336*30fdc8d8SChris Lattner } 337*30fdc8d8SChris Lattner } 338*30fdc8d8SChris Lattner 339*30fdc8d8SChris Lattner Process &process = m_lldb_object_sp->GetProcess(); 340*30fdc8d8SChris Lattner // Why do we need to set the current thread by ID here??? 341*30fdc8d8SChris Lattner process.GetThreadList().SetCurrentThreadByID (m_lldb_object_sp->GetID()); 342*30fdc8d8SChris Lattner process.Resume(); 343*30fdc8d8SChris Lattner } 344*30fdc8d8SChris Lattner } 345*30fdc8d8SChris Lattner 346*30fdc8d8SChris Lattner void 347*30fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads) 348*30fdc8d8SChris Lattner { 349*30fdc8d8SChris Lattner if (m_lldb_object_sp) 350*30fdc8d8SChris Lattner { 351*30fdc8d8SChris Lattner bool abort_other_plans = true; 352*30fdc8d8SChris Lattner 353*30fdc8d8SChris Lattner StackFrameSP frame_sp(m_lldb_object_sp->GetStackFrameAtIndex (0)); 354*30fdc8d8SChris Lattner 355*30fdc8d8SChris Lattner if (frame_sp && frame_sp->HasDebugInformation ()) 356*30fdc8d8SChris Lattner { 357*30fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 358*30fdc8d8SChris Lattner ThreadPlan *new_plan = m_lldb_object_sp->QueueThreadPlanForStepRange (abort_other_plans, 359*30fdc8d8SChris Lattner eStepTypeInto, 360*30fdc8d8SChris Lattner sc.line_entry.range, 361*30fdc8d8SChris Lattner sc, 362*30fdc8d8SChris Lattner stop_other_threads); 363*30fdc8d8SChris Lattner if (new_plan) 364*30fdc8d8SChris Lattner { 365*30fdc8d8SChris Lattner ThreadPlanStepInRange *real_plan = dynamic_cast<ThreadPlanStepInRange *> (new_plan); 366*30fdc8d8SChris Lattner if (real_plan) 367*30fdc8d8SChris Lattner { 368*30fdc8d8SChris Lattner bool avoid_no_debug = true; 369*30fdc8d8SChris Lattner if (avoid_no_debug) 370*30fdc8d8SChris Lattner real_plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug); 371*30fdc8d8SChris Lattner else 372*30fdc8d8SChris Lattner real_plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug); 373*30fdc8d8SChris Lattner } 374*30fdc8d8SChris Lattner } 375*30fdc8d8SChris Lattner } 376*30fdc8d8SChris Lattner else 377*30fdc8d8SChris Lattner { 378*30fdc8d8SChris Lattner m_lldb_object_sp->QueueThreadPlanForStepSingleInstruction (false, 379*30fdc8d8SChris Lattner abort_other_plans, 380*30fdc8d8SChris Lattner stop_other_threads); 381*30fdc8d8SChris Lattner } 382*30fdc8d8SChris Lattner 383*30fdc8d8SChris Lattner Process &process = m_lldb_object_sp->GetProcess(); 384*30fdc8d8SChris Lattner // Why do we need to set the current thread by ID here??? 385*30fdc8d8SChris Lattner process.GetThreadList().SetCurrentThreadByID (m_lldb_object_sp->GetID()); 386*30fdc8d8SChris Lattner process.Resume(); 387*30fdc8d8SChris Lattner 388*30fdc8d8SChris Lattner } 389*30fdc8d8SChris Lattner } 390*30fdc8d8SChris Lattner 391*30fdc8d8SChris Lattner void 392*30fdc8d8SChris Lattner SBThread::StepOut () 393*30fdc8d8SChris Lattner { 394*30fdc8d8SChris Lattner if (m_lldb_object_sp) 395*30fdc8d8SChris Lattner { 396*30fdc8d8SChris Lattner bool abort_other_plans = true; 397*30fdc8d8SChris Lattner bool stop_other_threads = true; 398*30fdc8d8SChris Lattner 399*30fdc8d8SChris Lattner m_lldb_object_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion); 400*30fdc8d8SChris Lattner 401*30fdc8d8SChris Lattner Process &process = m_lldb_object_sp->GetProcess(); 402*30fdc8d8SChris Lattner process.GetThreadList().SetCurrentThreadByID (m_lldb_object_sp->GetID()); 403*30fdc8d8SChris Lattner process.Resume(); 404*30fdc8d8SChris Lattner } 405*30fdc8d8SChris Lattner } 406*30fdc8d8SChris Lattner 407*30fdc8d8SChris Lattner void 408*30fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over) 409*30fdc8d8SChris Lattner { 410*30fdc8d8SChris Lattner if (m_lldb_object_sp) 411*30fdc8d8SChris Lattner { 412*30fdc8d8SChris Lattner m_lldb_object_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true); 413*30fdc8d8SChris Lattner Process &process = m_lldb_object_sp->GetProcess(); 414*30fdc8d8SChris Lattner process.GetThreadList().SetCurrentThreadByID (m_lldb_object_sp->GetID()); 415*30fdc8d8SChris Lattner process.Resume(); 416*30fdc8d8SChris Lattner } 417*30fdc8d8SChris Lattner } 418*30fdc8d8SChris Lattner 419*30fdc8d8SChris Lattner void 420*30fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr) 421*30fdc8d8SChris Lattner { 422*30fdc8d8SChris Lattner if (m_lldb_object_sp) 423*30fdc8d8SChris Lattner { 424*30fdc8d8SChris Lattner bool abort_other_plans = true; 425*30fdc8d8SChris Lattner bool stop_other_threads = true; 426*30fdc8d8SChris Lattner 427*30fdc8d8SChris Lattner Address target_addr (NULL, addr); 428*30fdc8d8SChris Lattner 429*30fdc8d8SChris Lattner m_lldb_object_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads); 430*30fdc8d8SChris Lattner Process &process = m_lldb_object_sp->GetProcess(); 431*30fdc8d8SChris Lattner process.GetThreadList().SetCurrentThreadByID (m_lldb_object_sp->GetID()); 432*30fdc8d8SChris Lattner process.Resume(); 433*30fdc8d8SChris Lattner } 434*30fdc8d8SChris Lattner 435*30fdc8d8SChris Lattner } 436*30fdc8d8SChris Lattner 437*30fdc8d8SChris Lattner void 438*30fdc8d8SChris Lattner SBThread::Backtrace (uint32_t num_frames) 439*30fdc8d8SChris Lattner { 440*30fdc8d8SChris Lattner bool all_frames = false; 441*30fdc8d8SChris Lattner if (num_frames < 1) 442*30fdc8d8SChris Lattner all_frames = true; 443*30fdc8d8SChris Lattner 444*30fdc8d8SChris Lattner FILE *out = SBDebugger::GetOutputFileHandle(); 445*30fdc8d8SChris Lattner FILE *err = SBDebugger::GetErrorFileHandle(); 446*30fdc8d8SChris Lattner 447*30fdc8d8SChris Lattner if ((out == NULL) || (err == NULL)) 448*30fdc8d8SChris Lattner return; 449*30fdc8d8SChris Lattner 450*30fdc8d8SChris Lattner if (m_lldb_object_sp) 451*30fdc8d8SChris Lattner { 452*30fdc8d8SChris Lattner if (out && err) 453*30fdc8d8SChris Lattner { 454*30fdc8d8SChris Lattner int max_num_frames = m_lldb_object_sp->GetStackFrameCount(); 455*30fdc8d8SChris Lattner int last_frame = max_num_frames; 456*30fdc8d8SChris Lattner 457*30fdc8d8SChris Lattner if (!all_frames && (num_frames < last_frame)) 458*30fdc8d8SChris Lattner last_frame = num_frames; 459*30fdc8d8SChris Lattner 460*30fdc8d8SChris Lattner StackFrameSP frame_sp; 461*30fdc8d8SChris Lattner for (int i = 0; i < last_frame; ++i) 462*30fdc8d8SChris Lattner { 463*30fdc8d8SChris Lattner frame_sp = m_lldb_object_sp->GetStackFrameAtIndex (i); 464*30fdc8d8SChris Lattner if (!frame_sp) 465*30fdc8d8SChris Lattner break; 466*30fdc8d8SChris Lattner 467*30fdc8d8SChris Lattner SBFrame sb_frame (frame_sp); 468*30fdc8d8SChris Lattner if (DisplaySingleFrameForCurrentContext ((FILE *) out, (FILE *) err, sb_frame, true, false, 0, 0) == false) 469*30fdc8d8SChris Lattner break; 470*30fdc8d8SChris Lattner } 471*30fdc8d8SChris Lattner } 472*30fdc8d8SChris Lattner } 473*30fdc8d8SChris Lattner } 474*30fdc8d8SChris Lattner 475*30fdc8d8SChris Lattner SBProcess 476*30fdc8d8SChris Lattner SBThread::GetProcess () 477*30fdc8d8SChris Lattner { 478*30fdc8d8SChris Lattner SBProcess process; 479*30fdc8d8SChris Lattner if (m_lldb_object_sp) 480*30fdc8d8SChris Lattner { 481*30fdc8d8SChris Lattner // Have to go up to the target so we can get a shared pointer to our process... 482*30fdc8d8SChris Lattner process.SetProcess(m_lldb_object_sp->GetProcess().GetTarget().GetProcessSP()); 483*30fdc8d8SChris Lattner } 484*30fdc8d8SChris Lattner return process; 485*30fdc8d8SChris Lattner } 486*30fdc8d8SChris Lattner 487*30fdc8d8SChris Lattner uint32_t 488*30fdc8d8SChris Lattner SBThread::GetNumFrames () 489*30fdc8d8SChris Lattner { 490*30fdc8d8SChris Lattner if (m_lldb_object_sp) 491*30fdc8d8SChris Lattner return m_lldb_object_sp->GetStackFrameCount(); 492*30fdc8d8SChris Lattner return 0; 493*30fdc8d8SChris Lattner } 494*30fdc8d8SChris Lattner 495*30fdc8d8SChris Lattner SBFrame 496*30fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx) 497*30fdc8d8SChris Lattner { 498*30fdc8d8SChris Lattner SBFrame sb_frame; 499*30fdc8d8SChris Lattner if (m_lldb_object_sp) 500*30fdc8d8SChris Lattner sb_frame.SetFrame (m_lldb_object_sp->GetStackFrameAtIndex (idx)); 501*30fdc8d8SChris Lattner return sb_frame; 502*30fdc8d8SChris Lattner } 503*30fdc8d8SChris Lattner 504*30fdc8d8SChris Lattner const lldb::SBThread & 505*30fdc8d8SChris Lattner SBThread::operator = (const lldb::SBThread &rhs) 506*30fdc8d8SChris Lattner { 507*30fdc8d8SChris Lattner m_lldb_object_sp = rhs.m_lldb_object_sp; 508*30fdc8d8SChris Lattner return *this; 509*30fdc8d8SChris Lattner } 510*30fdc8d8SChris Lattner 511*30fdc8d8SChris Lattner bool 512*30fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const 513*30fdc8d8SChris Lattner { 514*30fdc8d8SChris Lattner return m_lldb_object_sp.get() == rhs.m_lldb_object_sp.get(); 515*30fdc8d8SChris Lattner } 516*30fdc8d8SChris Lattner 517*30fdc8d8SChris Lattner bool 518*30fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const 519*30fdc8d8SChris Lattner { 520*30fdc8d8SChris Lattner return m_lldb_object_sp.get() != rhs.m_lldb_object_sp.get(); 521*30fdc8d8SChris Lattner } 522*30fdc8d8SChris Lattner 523*30fdc8d8SChris Lattner lldb_private::Thread * 524*30fdc8d8SChris Lattner SBThread::GetLLDBObjectPtr () 525*30fdc8d8SChris Lattner { 526*30fdc8d8SChris Lattner return m_lldb_object_sp.get(); 527*30fdc8d8SChris Lattner } 528*30fdc8d8SChris Lattner 529*30fdc8d8SChris Lattner const lldb_private::Thread * 530*30fdc8d8SChris Lattner SBThread::operator->() const 531*30fdc8d8SChris Lattner { 532*30fdc8d8SChris Lattner return m_lldb_object_sp.get(); 533*30fdc8d8SChris Lattner } 534*30fdc8d8SChris Lattner 535*30fdc8d8SChris Lattner const lldb_private::Thread & 536*30fdc8d8SChris Lattner SBThread::operator*() const 537*30fdc8d8SChris Lattner { 538*30fdc8d8SChris Lattner return *m_lldb_object_sp; 539*30fdc8d8SChris Lattner } 540*30fdc8d8SChris Lattner 541*30fdc8d8SChris Lattner lldb_private::Thread * 542*30fdc8d8SChris Lattner SBThread::operator->() 543*30fdc8d8SChris Lattner { 544*30fdc8d8SChris Lattner return m_lldb_object_sp.get(); 545*30fdc8d8SChris Lattner } 546*30fdc8d8SChris Lattner 547*30fdc8d8SChris Lattner lldb_private::Thread & 548*30fdc8d8SChris Lattner SBThread::operator*() 549*30fdc8d8SChris Lattner { 550*30fdc8d8SChris Lattner return *m_lldb_object_sp; 551*30fdc8d8SChris Lattner } 552