1254721Semaste//===-- SBThread.cpp --------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "lldb/API/SBThread.h" 13254721Semaste 14254721Semaste#include "lldb/API/SBSymbolContext.h" 15254721Semaste#include "lldb/API/SBFileSpec.h" 16254721Semaste#include "lldb/API/SBStream.h" 17254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h" 18254721Semaste#include "lldb/Core/Debugger.h" 19254721Semaste#include "lldb/Core/State.h" 20254721Semaste#include "lldb/Core/Stream.h" 21254721Semaste#include "lldb/Core/StreamFile.h" 22254721Semaste#include "lldb/Interpreter/CommandInterpreter.h" 23254721Semaste#include "lldb/Target/Thread.h" 24254721Semaste#include "lldb/Target/Process.h" 25254721Semaste#include "lldb/Symbol/SymbolContext.h" 26254721Semaste#include "lldb/Symbol/CompileUnit.h" 27254721Semaste#include "lldb/Target/StopInfo.h" 28254721Semaste#include "lldb/Target/Target.h" 29254721Semaste#include "lldb/Target/ThreadPlan.h" 30254721Semaste#include "lldb/Target/ThreadPlanStepInstruction.h" 31254721Semaste#include "lldb/Target/ThreadPlanStepOut.h" 32254721Semaste#include "lldb/Target/ThreadPlanStepRange.h" 33254721Semaste#include "lldb/Target/ThreadPlanStepInRange.h" 34254721Semaste 35254721Semaste 36254721Semaste#include "lldb/API/SBAddress.h" 37254721Semaste#include "lldb/API/SBDebugger.h" 38254721Semaste#include "lldb/API/SBEvent.h" 39254721Semaste#include "lldb/API/SBFrame.h" 40254721Semaste#include "lldb/API/SBProcess.h" 41254721Semaste#include "lldb/API/SBValue.h" 42254721Semaste 43254721Semasteusing namespace lldb; 44254721Semasteusing namespace lldb_private; 45254721Semaste 46254721Semasteconst char * 47254721SemasteSBThread::GetBroadcasterClassName () 48254721Semaste{ 49254721Semaste return Thread::GetStaticBroadcasterClass().AsCString(); 50254721Semaste} 51254721Semaste 52254721Semaste//---------------------------------------------------------------------- 53254721Semaste// Constructors 54254721Semaste//---------------------------------------------------------------------- 55254721SemasteSBThread::SBThread () : 56254721Semaste m_opaque_sp (new ExecutionContextRef()) 57254721Semaste{ 58254721Semaste} 59254721Semaste 60254721SemasteSBThread::SBThread (const ThreadSP& lldb_object_sp) : 61254721Semaste m_opaque_sp (new ExecutionContextRef(lldb_object_sp)) 62254721Semaste{ 63254721Semaste} 64254721Semaste 65254721SemasteSBThread::SBThread (const SBThread &rhs) : 66254721Semaste m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp)) 67254721Semaste{ 68254721Semaste 69254721Semaste} 70254721Semaste 71254721Semaste//---------------------------------------------------------------------- 72254721Semaste// Assignment operator 73254721Semaste//---------------------------------------------------------------------- 74254721Semaste 75254721Semasteconst lldb::SBThread & 76254721SemasteSBThread::operator = (const SBThread &rhs) 77254721Semaste{ 78254721Semaste if (this != &rhs) 79254721Semaste *m_opaque_sp = *rhs.m_opaque_sp; 80254721Semaste return *this; 81254721Semaste} 82254721Semaste 83254721Semaste//---------------------------------------------------------------------- 84254721Semaste// Destructor 85254721Semaste//---------------------------------------------------------------------- 86254721SemasteSBThread::~SBThread() 87254721Semaste{ 88254721Semaste} 89254721Semaste 90254721Semastebool 91254721SemasteSBThread::IsValid() const 92254721Semaste{ 93254721Semaste return m_opaque_sp->GetThreadSP().get() != NULL; 94254721Semaste} 95254721Semaste 96254721Semastevoid 97254721SemasteSBThread::Clear () 98254721Semaste{ 99254721Semaste m_opaque_sp->Clear(); 100254721Semaste} 101254721Semaste 102254721Semaste 103254721SemasteStopReason 104254721SemasteSBThread::GetStopReason() 105254721Semaste{ 106254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 107254721Semaste 108254721Semaste StopReason reason = eStopReasonInvalid; 109254721Semaste Mutex::Locker api_locker; 110254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 111254721Semaste 112254721Semaste if (exe_ctx.HasThreadScope()) 113254721Semaste { 114254721Semaste Process::StopLocker stop_locker; 115254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 116254721Semaste { 117254721Semaste return exe_ctx.GetThreadPtr()->GetStopReason(); 118254721Semaste } 119254721Semaste else 120254721Semaste { 121254721Semaste if (log) 122254721Semaste log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr()); 123254721Semaste } 124254721Semaste } 125254721Semaste 126254721Semaste if (log) 127254721Semaste log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(), 128254721Semaste Thread::StopReasonAsCString (reason)); 129254721Semaste 130254721Semaste return reason; 131254721Semaste} 132254721Semaste 133254721Semastesize_t 134254721SemasteSBThread::GetStopReasonDataCount () 135254721Semaste{ 136254721Semaste Mutex::Locker api_locker; 137254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 138254721Semaste 139254721Semaste if (exe_ctx.HasThreadScope()) 140254721Semaste { 141254721Semaste Process::StopLocker stop_locker; 142254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 143254721Semaste { 144254721Semaste StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 145254721Semaste if (stop_info_sp) 146254721Semaste { 147254721Semaste StopReason reason = stop_info_sp->GetStopReason(); 148254721Semaste switch (reason) 149254721Semaste { 150254721Semaste case eStopReasonInvalid: 151254721Semaste case eStopReasonNone: 152254721Semaste case eStopReasonTrace: 153254721Semaste case eStopReasonExec: 154254721Semaste case eStopReasonPlanComplete: 155254721Semaste case eStopReasonThreadExiting: 156254721Semaste // There is no data for these stop reasons. 157254721Semaste return 0; 158254721Semaste 159254721Semaste case eStopReasonBreakpoint: 160254721Semaste { 161254721Semaste break_id_t site_id = stop_info_sp->GetValue(); 162254721Semaste lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 163254721Semaste if (bp_site_sp) 164254721Semaste return bp_site_sp->GetNumberOfOwners () * 2; 165254721Semaste else 166254721Semaste return 0; // Breakpoint must have cleared itself... 167254721Semaste } 168254721Semaste break; 169254721Semaste 170254721Semaste case eStopReasonWatchpoint: 171254721Semaste return 1; 172254721Semaste 173254721Semaste case eStopReasonSignal: 174254721Semaste return 1; 175254721Semaste 176254721Semaste case eStopReasonException: 177254721Semaste return 1; 178254721Semaste } 179254721Semaste } 180254721Semaste } 181254721Semaste else 182254721Semaste { 183254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 184254721Semaste if (log) 185254721Semaste log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr()); 186254721Semaste } 187254721Semaste } 188254721Semaste return 0; 189254721Semaste} 190254721Semaste 191254721Semasteuint64_t 192254721SemasteSBThread::GetStopReasonDataAtIndex (uint32_t idx) 193254721Semaste{ 194254721Semaste Mutex::Locker api_locker; 195254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 196254721Semaste 197254721Semaste if (exe_ctx.HasThreadScope()) 198254721Semaste { 199254721Semaste Process::StopLocker stop_locker; 200254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 201254721Semaste { 202254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 203254721Semaste StopInfoSP stop_info_sp = thread->GetStopInfo (); 204254721Semaste if (stop_info_sp) 205254721Semaste { 206254721Semaste StopReason reason = stop_info_sp->GetStopReason(); 207254721Semaste switch (reason) 208254721Semaste { 209254721Semaste case eStopReasonInvalid: 210254721Semaste case eStopReasonNone: 211254721Semaste case eStopReasonTrace: 212254721Semaste case eStopReasonExec: 213254721Semaste case eStopReasonPlanComplete: 214254721Semaste case eStopReasonThreadExiting: 215254721Semaste // There is no data for these stop reasons. 216254721Semaste return 0; 217254721Semaste 218254721Semaste case eStopReasonBreakpoint: 219254721Semaste { 220254721Semaste break_id_t site_id = stop_info_sp->GetValue(); 221254721Semaste lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 222254721Semaste if (bp_site_sp) 223254721Semaste { 224254721Semaste uint32_t bp_index = idx / 2; 225254721Semaste BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 226254721Semaste if (bp_loc_sp) 227254721Semaste { 228254721Semaste if (bp_index & 1) 229254721Semaste { 230254721Semaste // Odd idx, return the breakpoint location ID 231254721Semaste return bp_loc_sp->GetID(); 232254721Semaste } 233254721Semaste else 234254721Semaste { 235254721Semaste // Even idx, return the breakpoint ID 236254721Semaste return bp_loc_sp->GetBreakpoint().GetID(); 237254721Semaste } 238254721Semaste } 239254721Semaste } 240254721Semaste return LLDB_INVALID_BREAK_ID; 241254721Semaste } 242254721Semaste break; 243254721Semaste 244254721Semaste case eStopReasonWatchpoint: 245254721Semaste return stop_info_sp->GetValue(); 246254721Semaste 247254721Semaste case eStopReasonSignal: 248254721Semaste return stop_info_sp->GetValue(); 249254721Semaste 250254721Semaste case eStopReasonException: 251254721Semaste return stop_info_sp->GetValue(); 252254721Semaste } 253254721Semaste } 254254721Semaste } 255254721Semaste else 256254721Semaste { 257254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 258254721Semaste if (log) 259254721Semaste log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); 260254721Semaste } 261254721Semaste } 262254721Semaste return 0; 263254721Semaste} 264254721Semaste 265254721Semastesize_t 266254721SemasteSBThread::GetStopDescription (char *dst, size_t dst_len) 267254721Semaste{ 268254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 269254721Semaste 270254721Semaste Mutex::Locker api_locker; 271254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 272254721Semaste 273254721Semaste if (exe_ctx.HasThreadScope()) 274254721Semaste { 275254721Semaste Process::StopLocker stop_locker; 276254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 277254721Semaste { 278254721Semaste 279254721Semaste StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 280254721Semaste if (stop_info_sp) 281254721Semaste { 282254721Semaste const char *stop_desc = stop_info_sp->GetDescription(); 283254721Semaste if (stop_desc) 284254721Semaste { 285254721Semaste if (log) 286254721Semaste log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 287254721Semaste exe_ctx.GetThreadPtr(), stop_desc); 288254721Semaste if (dst) 289254721Semaste return ::snprintf (dst, dst_len, "%s", stop_desc); 290254721Semaste else 291254721Semaste { 292254721Semaste // NULL dst passed in, return the length needed to contain the description 293254721Semaste return ::strlen (stop_desc) + 1; // Include the NULL byte for size 294254721Semaste } 295254721Semaste } 296254721Semaste else 297254721Semaste { 298254721Semaste size_t stop_desc_len = 0; 299254721Semaste switch (stop_info_sp->GetStopReason()) 300254721Semaste { 301254721Semaste case eStopReasonTrace: 302254721Semaste case eStopReasonPlanComplete: 303254721Semaste { 304254721Semaste static char trace_desc[] = "step"; 305254721Semaste stop_desc = trace_desc; 306254721Semaste stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 307254721Semaste } 308254721Semaste break; 309254721Semaste 310254721Semaste case eStopReasonBreakpoint: 311254721Semaste { 312254721Semaste static char bp_desc[] = "breakpoint hit"; 313254721Semaste stop_desc = bp_desc; 314254721Semaste stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 315254721Semaste } 316254721Semaste break; 317254721Semaste 318254721Semaste case eStopReasonWatchpoint: 319254721Semaste { 320254721Semaste static char wp_desc[] = "watchpoint hit"; 321254721Semaste stop_desc = wp_desc; 322254721Semaste stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 323254721Semaste } 324254721Semaste break; 325254721Semaste 326254721Semaste case eStopReasonSignal: 327254721Semaste { 328254721Semaste stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 329254721Semaste if (stop_desc == NULL || stop_desc[0] == '\0') 330254721Semaste { 331254721Semaste static char signal_desc[] = "signal"; 332254721Semaste stop_desc = signal_desc; 333254721Semaste stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 334254721Semaste } 335254721Semaste } 336254721Semaste break; 337254721Semaste 338254721Semaste case eStopReasonException: 339254721Semaste { 340254721Semaste char exc_desc[] = "exception"; 341254721Semaste stop_desc = exc_desc; 342254721Semaste stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 343254721Semaste } 344254721Semaste break; 345254721Semaste 346254721Semaste case eStopReasonExec: 347254721Semaste { 348254721Semaste char exc_desc[] = "exec"; 349254721Semaste stop_desc = exc_desc; 350254721Semaste stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 351254721Semaste } 352254721Semaste break; 353254721Semaste 354254721Semaste case eStopReasonThreadExiting: 355254721Semaste { 356254721Semaste char limbo_desc[] = "thread exiting"; 357254721Semaste stop_desc = limbo_desc; 358254721Semaste stop_desc_len = sizeof(limbo_desc); 359254721Semaste } 360254721Semaste break; 361254721Semaste default: 362254721Semaste break; 363254721Semaste } 364254721Semaste 365254721Semaste if (stop_desc && stop_desc[0]) 366254721Semaste { 367254721Semaste if (log) 368254721Semaste log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 369254721Semaste exe_ctx.GetThreadPtr(), stop_desc); 370254721Semaste 371254721Semaste if (dst) 372254721Semaste return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 373254721Semaste 374254721Semaste if (stop_desc_len == 0) 375254721Semaste stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 376254721Semaste 377254721Semaste return stop_desc_len; 378254721Semaste } 379254721Semaste } 380254721Semaste } 381254721Semaste } 382254721Semaste else 383254721Semaste { 384254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 385254721Semaste if (log) 386254721Semaste log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr()); 387254721Semaste } 388254721Semaste } 389254721Semaste if (dst) 390254721Semaste *dst = 0; 391254721Semaste return 0; 392254721Semaste} 393254721Semaste 394254721SemasteSBValue 395254721SemasteSBThread::GetStopReturnValue () 396254721Semaste{ 397254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 398254721Semaste ValueObjectSP return_valobj_sp; 399254721Semaste Mutex::Locker api_locker; 400254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 401254721Semaste 402254721Semaste if (exe_ctx.HasThreadScope()) 403254721Semaste { 404254721Semaste Process::StopLocker stop_locker; 405254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 406254721Semaste { 407254721Semaste StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 408254721Semaste if (stop_info_sp) 409254721Semaste { 410254721Semaste return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 411254721Semaste } 412254721Semaste } 413254721Semaste else 414254721Semaste { 415254721Semaste if (log) 416254721Semaste log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr()); 417254721Semaste } 418254721Semaste } 419254721Semaste 420254721Semaste if (log) 421254721Semaste log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(), 422254721Semaste return_valobj_sp.get() 423254721Semaste ? return_valobj_sp->GetValueAsCString() 424254721Semaste : "<no return value>"); 425254721Semaste 426254721Semaste return SBValue (return_valobj_sp); 427254721Semaste} 428254721Semaste 429254721Semastevoid 430254721SemasteSBThread::SetThread (const ThreadSP& lldb_object_sp) 431254721Semaste{ 432254721Semaste m_opaque_sp->SetThreadSP (lldb_object_sp); 433254721Semaste} 434254721Semaste 435254721Semaste 436254721Semastelldb::tid_t 437254721SemasteSBThread::GetThreadID () const 438254721Semaste{ 439254721Semaste ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 440254721Semaste if (thread_sp) 441254721Semaste return thread_sp->GetID(); 442254721Semaste return LLDB_INVALID_THREAD_ID; 443254721Semaste} 444254721Semaste 445254721Semasteuint32_t 446254721SemasteSBThread::GetIndexID () const 447254721Semaste{ 448254721Semaste ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 449254721Semaste if (thread_sp) 450254721Semaste return thread_sp->GetIndexID(); 451254721Semaste return LLDB_INVALID_INDEX32; 452254721Semaste} 453254721Semaste 454254721Semasteconst char * 455254721SemasteSBThread::GetName () const 456254721Semaste{ 457254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 458254721Semaste const char *name = NULL; 459254721Semaste Mutex::Locker api_locker; 460254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 461254721Semaste 462254721Semaste if (exe_ctx.HasThreadScope()) 463254721Semaste { 464254721Semaste Process::StopLocker stop_locker; 465254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 466254721Semaste { 467254721Semaste name = exe_ctx.GetThreadPtr()->GetName(); 468254721Semaste } 469254721Semaste else 470254721Semaste { 471254721Semaste if (log) 472254721Semaste log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr()); 473254721Semaste } 474254721Semaste } 475254721Semaste 476254721Semaste if (log) 477254721Semaste log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); 478254721Semaste 479254721Semaste return name; 480254721Semaste} 481254721Semaste 482254721Semasteconst char * 483254721SemasteSBThread::GetQueueName () const 484254721Semaste{ 485254721Semaste const char *name = NULL; 486254721Semaste Mutex::Locker api_locker; 487254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 488254721Semaste 489254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 490254721Semaste if (exe_ctx.HasThreadScope()) 491254721Semaste { 492254721Semaste Process::StopLocker stop_locker; 493254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 494254721Semaste { 495254721Semaste name = exe_ctx.GetThreadPtr()->GetQueueName(); 496254721Semaste } 497254721Semaste else 498254721Semaste { 499254721Semaste if (log) 500254721Semaste log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr()); 501254721Semaste } 502254721Semaste } 503254721Semaste 504254721Semaste if (log) 505254721Semaste log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); 506254721Semaste 507254721Semaste return name; 508254721Semaste} 509254721Semaste 510254721SemasteSBError 511254721SemasteSBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan) 512254721Semaste{ 513254721Semaste SBError sb_error; 514254721Semaste 515254721Semaste Process *process = exe_ctx.GetProcessPtr(); 516254721Semaste if (!process) 517254721Semaste { 518254721Semaste sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 519254721Semaste return sb_error; 520254721Semaste } 521254721Semaste 522254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 523254721Semaste if (!thread) 524254721Semaste { 525254721Semaste sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 526254721Semaste return sb_error; 527254721Semaste } 528254721Semaste 529254721Semaste // User level plans should be Master Plans so they can be interrupted, other plans executed, and 530254721Semaste // then a "continue" will resume the plan. 531254721Semaste if (new_plan != NULL) 532254721Semaste { 533254721Semaste new_plan->SetIsMasterPlan(true); 534254721Semaste new_plan->SetOkayToDiscard(false); 535254721Semaste } 536254721Semaste 537254721Semaste // Why do we need to set the current thread by ID here??? 538254721Semaste process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 539254721Semaste sb_error.ref() = process->Resume(); 540254721Semaste 541254721Semaste if (sb_error.Success()) 542254721Semaste { 543254721Semaste // If we are doing synchronous mode, then wait for the 544254721Semaste // process to stop yet again! 545254721Semaste if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 546254721Semaste process->WaitForProcessToStop (NULL); 547254721Semaste } 548254721Semaste 549254721Semaste return sb_error; 550254721Semaste} 551254721Semaste 552254721Semastevoid 553254721SemasteSBThread::StepOver (lldb::RunMode stop_other_threads) 554254721Semaste{ 555254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 556254721Semaste 557254721Semaste Mutex::Locker api_locker; 558254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 559254721Semaste 560254721Semaste 561254721Semaste if (log) 562254721Semaste log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), 563254721Semaste Thread::RunModeAsCString (stop_other_threads)); 564254721Semaste 565254721Semaste if (exe_ctx.HasThreadScope()) 566254721Semaste { 567254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 568254721Semaste bool abort_other_plans = false; 569254721Semaste StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 570254721Semaste 571254721Semaste ThreadPlanSP new_plan_sp; 572254721Semaste if (frame_sp) 573254721Semaste { 574254721Semaste if (frame_sp->HasDebugInformation ()) 575254721Semaste { 576254721Semaste SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 577254721Semaste new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, 578254721Semaste sc.line_entry.range, 579254721Semaste sc, 580254721Semaste stop_other_threads); 581254721Semaste } 582254721Semaste else 583254721Semaste { 584254721Semaste new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, 585254721Semaste abort_other_plans, 586254721Semaste stop_other_threads); 587254721Semaste } 588254721Semaste } 589254721Semaste 590254721Semaste // This returns an error, we should use it! 591254721Semaste ResumeNewPlan (exe_ctx, new_plan_sp.get()); 592254721Semaste } 593254721Semaste} 594254721Semaste 595254721Semastevoid 596254721SemasteSBThread::StepInto (lldb::RunMode stop_other_threads) 597254721Semaste{ 598254721Semaste StepInto (NULL, stop_other_threads); 599254721Semaste} 600254721Semaste 601254721Semastevoid 602254721SemasteSBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) 603254721Semaste{ 604254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 605254721Semaste 606254721Semaste Mutex::Locker api_locker; 607254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 608254721Semaste 609254721Semaste if (log) 610254721Semaste log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 611254721Semaste exe_ctx.GetThreadPtr(), 612254721Semaste target_name? target_name: "<NULL>", 613254721Semaste Thread::RunModeAsCString (stop_other_threads)); 614254721Semaste 615254721Semaste if (exe_ctx.HasThreadScope()) 616254721Semaste { 617254721Semaste bool abort_other_plans = false; 618254721Semaste 619254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 620254721Semaste StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 621254721Semaste ThreadPlanSP new_plan_sp; 622254721Semaste 623254721Semaste if (frame_sp && frame_sp->HasDebugInformation ()) 624254721Semaste { 625254721Semaste bool avoid_code_without_debug_info = true; 626254721Semaste SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 627254721Semaste new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, 628254721Semaste sc.line_entry.range, 629254721Semaste sc, 630254721Semaste target_name, 631254721Semaste stop_other_threads, 632254721Semaste avoid_code_without_debug_info); 633254721Semaste } 634254721Semaste else 635254721Semaste { 636254721Semaste new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, 637254721Semaste abort_other_plans, 638254721Semaste stop_other_threads); 639254721Semaste } 640254721Semaste 641254721Semaste // This returns an error, we should use it! 642254721Semaste ResumeNewPlan (exe_ctx, new_plan_sp.get()); 643254721Semaste } 644254721Semaste} 645254721Semaste 646254721Semastevoid 647254721SemasteSBThread::StepOut () 648254721Semaste{ 649254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 650254721Semaste 651254721Semaste Mutex::Locker api_locker; 652254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 653254721Semaste 654254721Semaste 655254721Semaste if (log) 656254721Semaste log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr()); 657254721Semaste 658254721Semaste if (exe_ctx.HasThreadScope()) 659254721Semaste { 660254721Semaste bool abort_other_plans = false; 661254721Semaste bool stop_other_threads = false; 662254721Semaste 663254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 664254721Semaste 665254721Semaste ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 666254721Semaste NULL, 667254721Semaste false, 668254721Semaste stop_other_threads, 669254721Semaste eVoteYes, 670254721Semaste eVoteNoOpinion, 671254721Semaste 0)); 672254721Semaste 673254721Semaste // This returns an error, we should use it! 674254721Semaste ResumeNewPlan (exe_ctx, new_plan_sp.get()); 675254721Semaste } 676254721Semaste} 677254721Semaste 678254721Semastevoid 679254721SemasteSBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 680254721Semaste{ 681254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 682254721Semaste 683254721Semaste Mutex::Locker api_locker; 684254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 685254721Semaste 686254721Semaste StackFrameSP frame_sp (sb_frame.GetFrameSP()); 687254721Semaste if (log) 688254721Semaste { 689254721Semaste SBStream frame_desc_strm; 690254721Semaste sb_frame.GetDescription (frame_desc_strm); 691254721Semaste log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); 692254721Semaste } 693254721Semaste 694254721Semaste if (exe_ctx.HasThreadScope()) 695254721Semaste { 696254721Semaste bool abort_other_plans = false; 697254721Semaste bool stop_other_threads = false; 698254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 699254721Semaste 700254721Semaste ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 701254721Semaste NULL, 702254721Semaste false, 703254721Semaste stop_other_threads, 704254721Semaste eVoteYes, 705254721Semaste eVoteNoOpinion, 706254721Semaste frame_sp->GetFrameIndex())); 707254721Semaste 708254721Semaste // This returns an error, we should use it! 709254721Semaste ResumeNewPlan (exe_ctx, new_plan_sp.get()); 710254721Semaste } 711254721Semaste} 712254721Semaste 713254721Semastevoid 714254721SemasteSBThread::StepInstruction (bool step_over) 715254721Semaste{ 716254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 717254721Semaste 718254721Semaste Mutex::Locker api_locker; 719254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 720254721Semaste 721254721Semaste 722254721Semaste 723254721Semaste if (log) 724254721Semaste log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over); 725254721Semaste 726254721Semaste if (exe_ctx.HasThreadScope()) 727254721Semaste { 728254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 729254721Semaste ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true)); 730254721Semaste 731254721Semaste // This returns an error, we should use it! 732254721Semaste ResumeNewPlan (exe_ctx, new_plan_sp.get()); 733254721Semaste } 734254721Semaste} 735254721Semaste 736254721Semastevoid 737254721SemasteSBThread::RunToAddress (lldb::addr_t addr) 738254721Semaste{ 739254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 740254721Semaste 741254721Semaste Mutex::Locker api_locker; 742254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 743254721Semaste 744254721Semaste 745254721Semaste if (log) 746254721Semaste log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr); 747254721Semaste 748254721Semaste if (exe_ctx.HasThreadScope()) 749254721Semaste { 750254721Semaste bool abort_other_plans = false; 751254721Semaste bool stop_other_threads = true; 752254721Semaste 753254721Semaste Address target_addr (addr); 754254721Semaste 755254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 756254721Semaste 757254721Semaste ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads)); 758254721Semaste 759254721Semaste // This returns an error, we should use it! 760254721Semaste ResumeNewPlan (exe_ctx, new_plan_sp.get()); 761254721Semaste } 762254721Semaste} 763254721Semaste 764254721SemasteSBError 765254721SemasteSBThread::StepOverUntil (lldb::SBFrame &sb_frame, 766254721Semaste lldb::SBFileSpec &sb_file_spec, 767254721Semaste uint32_t line) 768254721Semaste{ 769254721Semaste SBError sb_error; 770254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 771254721Semaste char path[PATH_MAX]; 772254721Semaste 773254721Semaste Mutex::Locker api_locker; 774254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 775254721Semaste 776254721Semaste StackFrameSP frame_sp (sb_frame.GetFrameSP()); 777254721Semaste 778254721Semaste if (log) 779254721Semaste { 780254721Semaste SBStream frame_desc_strm; 781254721Semaste sb_frame.GetDescription (frame_desc_strm); 782254721Semaste sb_file_spec->GetPath (path, sizeof(path)); 783254721Semaste log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 784254721Semaste exe_ctx.GetThreadPtr(), 785254721Semaste frame_sp.get(), 786254721Semaste frame_desc_strm.GetData(), 787254721Semaste path, line); 788254721Semaste } 789254721Semaste 790254721Semaste if (exe_ctx.HasThreadScope()) 791254721Semaste { 792254721Semaste Target *target = exe_ctx.GetTargetPtr(); 793254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 794254721Semaste 795254721Semaste if (line == 0) 796254721Semaste { 797254721Semaste sb_error.SetErrorString("invalid line argument"); 798254721Semaste return sb_error; 799254721Semaste } 800254721Semaste 801254721Semaste if (!frame_sp) 802254721Semaste { 803254721Semaste frame_sp = thread->GetSelectedFrame (); 804254721Semaste if (!frame_sp) 805254721Semaste frame_sp = thread->GetStackFrameAtIndex (0); 806254721Semaste } 807254721Semaste 808254721Semaste SymbolContext frame_sc; 809254721Semaste if (!frame_sp) 810254721Semaste { 811254721Semaste sb_error.SetErrorString("no valid frames in thread to step"); 812254721Semaste return sb_error; 813254721Semaste } 814254721Semaste 815254721Semaste // If we have a frame, get its line 816254721Semaste frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 817254721Semaste eSymbolContextFunction | 818254721Semaste eSymbolContextLineEntry | 819254721Semaste eSymbolContextSymbol ); 820254721Semaste 821254721Semaste if (frame_sc.comp_unit == NULL) 822254721Semaste { 823254721Semaste sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 824254721Semaste return sb_error; 825254721Semaste } 826254721Semaste 827254721Semaste FileSpec step_file_spec; 828254721Semaste if (sb_file_spec.IsValid()) 829254721Semaste { 830254721Semaste // The file spec passed in was valid, so use it 831254721Semaste step_file_spec = sb_file_spec.ref(); 832254721Semaste } 833254721Semaste else 834254721Semaste { 835254721Semaste if (frame_sc.line_entry.IsValid()) 836254721Semaste step_file_spec = frame_sc.line_entry.file; 837254721Semaste else 838254721Semaste { 839254721Semaste sb_error.SetErrorString("invalid file argument or no file for frame"); 840254721Semaste return sb_error; 841254721Semaste } 842254721Semaste } 843254721Semaste 844254721Semaste // Grab the current function, then we will make sure the "until" address is 845254721Semaste // within the function. We discard addresses that are out of the current 846254721Semaste // function, and then if there are no addresses remaining, give an appropriate 847254721Semaste // error message. 848254721Semaste 849254721Semaste bool all_in_function = true; 850254721Semaste AddressRange fun_range = frame_sc.function->GetAddressRange(); 851254721Semaste 852254721Semaste std::vector<addr_t> step_over_until_addrs; 853254721Semaste const bool abort_other_plans = false; 854254721Semaste const bool stop_other_threads = false; 855254721Semaste const bool check_inlines = true; 856254721Semaste const bool exact = false; 857254721Semaste 858254721Semaste SymbolContextList sc_list; 859254721Semaste const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 860254721Semaste line, 861254721Semaste check_inlines, 862254721Semaste exact, 863254721Semaste eSymbolContextLineEntry, 864254721Semaste sc_list); 865254721Semaste if (num_matches > 0) 866254721Semaste { 867254721Semaste SymbolContext sc; 868254721Semaste for (uint32_t i=0; i<num_matches; ++i) 869254721Semaste { 870254721Semaste if (sc_list.GetContextAtIndex(i, sc)) 871254721Semaste { 872254721Semaste addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 873254721Semaste if (step_addr != LLDB_INVALID_ADDRESS) 874254721Semaste { 875254721Semaste if (fun_range.ContainsLoadAddress(step_addr, target)) 876254721Semaste step_over_until_addrs.push_back(step_addr); 877254721Semaste else 878254721Semaste all_in_function = false; 879254721Semaste } 880254721Semaste } 881254721Semaste } 882254721Semaste } 883254721Semaste 884254721Semaste if (step_over_until_addrs.empty()) 885254721Semaste { 886254721Semaste if (all_in_function) 887254721Semaste { 888254721Semaste step_file_spec.GetPath (path, sizeof(path)); 889254721Semaste sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 890254721Semaste } 891254721Semaste else 892254721Semaste sb_error.SetErrorString ("step until target not in current function"); 893254721Semaste } 894254721Semaste else 895254721Semaste { 896254721Semaste ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans, 897254721Semaste &step_over_until_addrs[0], 898254721Semaste step_over_until_addrs.size(), 899254721Semaste stop_other_threads, 900254721Semaste frame_sp->GetFrameIndex())); 901254721Semaste 902254721Semaste sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); 903254721Semaste } 904254721Semaste } 905254721Semaste else 906254721Semaste { 907254721Semaste sb_error.SetErrorString("this SBThread object is invalid"); 908254721Semaste } 909254721Semaste return sb_error; 910254721Semaste} 911254721Semaste 912254721SemasteSBError 913254721SemasteSBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) 914254721Semaste{ 915254721Semaste SBError sb_error; 916254721Semaste 917254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 918254721Semaste 919254721Semaste Mutex::Locker api_locker; 920254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 921254721Semaste 922254721Semaste 923254721Semaste if (log) 924254721Semaste log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID()); 925254721Semaste 926254721Semaste if (exe_ctx.HasThreadScope()) 927254721Semaste { 928254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 929254721Semaste sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 930254721Semaste } 931254721Semaste 932254721Semaste return sb_error; 933254721Semaste} 934254721Semaste 935254721Semaste 936254721Semastebool 937254721SemasteSBThread::Suspend() 938254721Semaste{ 939254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 940254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get()); 941254721Semaste bool result = false; 942254721Semaste if (exe_ctx.HasThreadScope()) 943254721Semaste { 944254721Semaste Process::StopLocker stop_locker; 945254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 946254721Semaste { 947254721Semaste exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); 948254721Semaste result = true; 949254721Semaste } 950254721Semaste else 951254721Semaste { 952254721Semaste if (log) 953254721Semaste log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr()); 954254721Semaste } 955254721Semaste } 956254721Semaste if (log) 957254721Semaste log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result); 958254721Semaste return result; 959254721Semaste} 960254721Semaste 961254721Semastebool 962254721SemasteSBThread::Resume () 963254721Semaste{ 964254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 965254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get()); 966254721Semaste bool result = false; 967254721Semaste if (exe_ctx.HasThreadScope()) 968254721Semaste { 969254721Semaste Process::StopLocker stop_locker; 970254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 971254721Semaste { 972254721Semaste exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning); 973254721Semaste result = true; 974254721Semaste } 975254721Semaste else 976254721Semaste { 977254721Semaste if (log) 978254721Semaste log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr()); 979254721Semaste } 980254721Semaste } 981254721Semaste if (log) 982254721Semaste log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result); 983254721Semaste return result; 984254721Semaste} 985254721Semaste 986254721Semastebool 987254721SemasteSBThread::IsSuspended() 988254721Semaste{ 989254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get()); 990254721Semaste if (exe_ctx.HasThreadScope()) 991254721Semaste return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; 992254721Semaste return false; 993254721Semaste} 994254721Semaste 995254721Semastebool 996254721SemasteSBThread::IsStopped() 997254721Semaste{ 998254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get()); 999254721Semaste if (exe_ctx.HasThreadScope()) 1000254721Semaste return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1001254721Semaste return false; 1002254721Semaste} 1003254721Semaste 1004254721SemasteSBProcess 1005254721SemasteSBThread::GetProcess () 1006254721Semaste{ 1007254721Semaste SBProcess sb_process; 1008254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get()); 1009254721Semaste if (exe_ctx.HasThreadScope()) 1010254721Semaste { 1011254721Semaste // Have to go up to the target so we can get a shared pointer to our process... 1012254721Semaste sb_process.SetSP (exe_ctx.GetProcessSP()); 1013254721Semaste } 1014254721Semaste 1015254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1016254721Semaste if (log) 1017254721Semaste { 1018254721Semaste SBStream frame_desc_strm; 1019254721Semaste sb_process.GetDescription (frame_desc_strm); 1020254721Semaste log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(), 1021254721Semaste sb_process.GetSP().get(), frame_desc_strm.GetData()); 1022254721Semaste } 1023254721Semaste 1024254721Semaste return sb_process; 1025254721Semaste} 1026254721Semaste 1027254721Semasteuint32_t 1028254721SemasteSBThread::GetNumFrames () 1029254721Semaste{ 1030254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1031254721Semaste 1032254721Semaste uint32_t num_frames = 0; 1033254721Semaste Mutex::Locker api_locker; 1034254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1035254721Semaste 1036254721Semaste if (exe_ctx.HasThreadScope()) 1037254721Semaste { 1038254721Semaste Process::StopLocker stop_locker; 1039254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1040254721Semaste { 1041254721Semaste num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1042254721Semaste } 1043254721Semaste else 1044254721Semaste { 1045254721Semaste if (log) 1046254721Semaste log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr()); 1047254721Semaste } 1048254721Semaste } 1049254721Semaste 1050254721Semaste if (log) 1051254721Semaste log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames); 1052254721Semaste 1053254721Semaste return num_frames; 1054254721Semaste} 1055254721Semaste 1056254721SemasteSBFrame 1057254721SemasteSBThread::GetFrameAtIndex (uint32_t idx) 1058254721Semaste{ 1059254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1060254721Semaste 1061254721Semaste SBFrame sb_frame; 1062254721Semaste StackFrameSP frame_sp; 1063254721Semaste Mutex::Locker api_locker; 1064254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1065254721Semaste 1066254721Semaste if (exe_ctx.HasThreadScope()) 1067254721Semaste { 1068254721Semaste Process::StopLocker stop_locker; 1069254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1070254721Semaste { 1071254721Semaste frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); 1072254721Semaste sb_frame.SetFrameSP (frame_sp); 1073254721Semaste } 1074254721Semaste else 1075254721Semaste { 1076254721Semaste if (log) 1077254721Semaste log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); 1078254721Semaste } 1079254721Semaste } 1080254721Semaste 1081254721Semaste if (log) 1082254721Semaste { 1083254721Semaste SBStream frame_desc_strm; 1084254721Semaste sb_frame.GetDescription (frame_desc_strm); 1085254721Semaste log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1086254721Semaste exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); 1087254721Semaste } 1088254721Semaste 1089254721Semaste return sb_frame; 1090254721Semaste} 1091254721Semaste 1092254721Semastelldb::SBFrame 1093254721SemasteSBThread::GetSelectedFrame () 1094254721Semaste{ 1095254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1096254721Semaste 1097254721Semaste SBFrame sb_frame; 1098254721Semaste StackFrameSP frame_sp; 1099254721Semaste Mutex::Locker api_locker; 1100254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1101254721Semaste 1102254721Semaste if (exe_ctx.HasThreadScope()) 1103254721Semaste { 1104254721Semaste Process::StopLocker stop_locker; 1105254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1106254721Semaste { 1107254721Semaste frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); 1108254721Semaste sb_frame.SetFrameSP (frame_sp); 1109254721Semaste } 1110254721Semaste else 1111254721Semaste { 1112254721Semaste if (log) 1113254721Semaste log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); 1114254721Semaste } 1115254721Semaste } 1116254721Semaste 1117254721Semaste if (log) 1118254721Semaste { 1119254721Semaste SBStream frame_desc_strm; 1120254721Semaste sb_frame.GetDescription (frame_desc_strm); 1121254721Semaste log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1122254721Semaste exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); 1123254721Semaste } 1124254721Semaste 1125254721Semaste return sb_frame; 1126254721Semaste} 1127254721Semaste 1128254721Semastelldb::SBFrame 1129254721SemasteSBThread::SetSelectedFrame (uint32_t idx) 1130254721Semaste{ 1131254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1132254721Semaste 1133254721Semaste SBFrame sb_frame; 1134254721Semaste StackFrameSP frame_sp; 1135254721Semaste Mutex::Locker api_locker; 1136254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1137254721Semaste 1138254721Semaste if (exe_ctx.HasThreadScope()) 1139254721Semaste { 1140254721Semaste Process::StopLocker stop_locker; 1141254721Semaste if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1142254721Semaste { 1143254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 1144254721Semaste frame_sp = thread->GetStackFrameAtIndex (idx); 1145254721Semaste if (frame_sp) 1146254721Semaste { 1147254721Semaste thread->SetSelectedFrame (frame_sp.get()); 1148254721Semaste sb_frame.SetFrameSP (frame_sp); 1149254721Semaste } 1150254721Semaste } 1151254721Semaste else 1152254721Semaste { 1153254721Semaste if (log) 1154254721Semaste log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); 1155254721Semaste } 1156254721Semaste } 1157254721Semaste 1158254721Semaste if (log) 1159254721Semaste { 1160254721Semaste SBStream frame_desc_strm; 1161254721Semaste sb_frame.GetDescription (frame_desc_strm); 1162254721Semaste log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1163254721Semaste exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); 1164254721Semaste } 1165254721Semaste return sb_frame; 1166254721Semaste} 1167254721Semaste 1168254721Semastebool 1169254721SemasteSBThread::EventIsThreadEvent (const SBEvent &event) 1170254721Semaste{ 1171254721Semaste return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 1172254721Semaste} 1173254721Semaste 1174254721SemasteSBFrame 1175254721SemasteSBThread::GetStackFrameFromEvent (const SBEvent &event) 1176254721Semaste{ 1177254721Semaste return Thread::ThreadEventData::GetStackFrameFromEvent (event.get()); 1178254721Semaste 1179254721Semaste} 1180254721Semaste 1181254721SemasteSBThread 1182254721SemasteSBThread::GetThreadFromEvent (const SBEvent &event) 1183254721Semaste{ 1184254721Semaste return Thread::ThreadEventData::GetThreadFromEvent (event.get()); 1185254721Semaste} 1186254721Semaste 1187254721Semastebool 1188254721SemasteSBThread::operator == (const SBThread &rhs) const 1189254721Semaste{ 1190254721Semaste return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); 1191254721Semaste} 1192254721Semaste 1193254721Semastebool 1194254721SemasteSBThread::operator != (const SBThread &rhs) const 1195254721Semaste{ 1196254721Semaste return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); 1197254721Semaste} 1198254721Semaste 1199254721Semastebool 1200254721SemasteSBThread::GetStatus (SBStream &status) const 1201254721Semaste{ 1202254721Semaste Stream &strm = status.ref(); 1203254721Semaste 1204254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get()); 1205254721Semaste if (exe_ctx.HasThreadScope()) 1206254721Semaste { 1207254721Semaste exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); 1208254721Semaste } 1209254721Semaste else 1210254721Semaste strm.PutCString ("No status"); 1211254721Semaste 1212254721Semaste return true; 1213254721Semaste} 1214254721Semaste 1215254721Semastebool 1216254721SemasteSBThread::GetDescription (SBStream &description) const 1217254721Semaste{ 1218254721Semaste Stream &strm = description.ref(); 1219254721Semaste 1220254721Semaste ExecutionContext exe_ctx (m_opaque_sp.get()); 1221254721Semaste if (exe_ctx.HasThreadScope()) 1222254721Semaste { 1223254721Semaste strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID()); 1224254721Semaste } 1225254721Semaste else 1226254721Semaste strm.PutCString ("No value"); 1227254721Semaste 1228254721Semaste return true; 1229254721Semaste} 1230