ThreadPlan.cpp revision 745ac7a5826fe7c392007941a4046bfb1a8dff81
1//===-- ThreadPlan.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/Target/ThreadPlan.h" 11 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "lldb/Core/Debugger.h" 17#include "lldb/Core/Log.h" 18#include "lldb/Core/State.h" 19#include "lldb/Target/RegisterContext.h" 20#include "lldb/Target/Thread.h" 21#include "lldb/Target/Process.h" 22#include "lldb/Target/Target.h" 23 24using namespace lldb; 25using namespace lldb_private; 26 27//---------------------------------------------------------------------- 28// ThreadPlan constructor 29//---------------------------------------------------------------------- 30ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) : 31 m_thread (thread), 32 m_stop_vote (stop_vote), 33 m_run_vote (run_vote), 34 m_kind (kind), 35 m_name (name), 36 m_plan_complete_mutex (Mutex::eMutexTypeRecursive), 37 m_plan_complete (false), 38 m_plan_private (false), 39 m_okay_to_discard (false) 40{ 41 SetID (GetNextID()); 42} 43 44//---------------------------------------------------------------------- 45// Destructor 46//---------------------------------------------------------------------- 47ThreadPlan::~ThreadPlan() 48{ 49} 50 51const char * 52ThreadPlan::GetName () const 53{ 54 return m_name.c_str(); 55} 56 57Thread & 58ThreadPlan::GetThread() 59{ 60 return m_thread; 61} 62 63 64const Thread & 65ThreadPlan::GetThread() const 66{ 67 return m_thread; 68} 69 70bool 71ThreadPlan::IsPlanComplete () 72{ 73 Mutex::Locker locker(m_plan_complete_mutex); 74 return m_plan_complete; 75} 76 77void 78ThreadPlan::SetPlanComplete () 79{ 80 Mutex::Locker locker(m_plan_complete_mutex); 81 m_plan_complete = true; 82} 83 84bool 85ThreadPlan::MischiefManaged () 86{ 87 Mutex::Locker locker(m_plan_complete_mutex); 88 m_plan_complete = true; 89 return true; 90} 91 92Vote 93ThreadPlan::ShouldReportStop (Event *event_ptr) 94{ 95 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 96 97 if (m_stop_vote == eVoteNoOpinion) 98 { 99 ThreadPlan *prev_plan = GetPreviousPlan (); 100 if (prev_plan) 101 { 102 Vote prev_vote = prev_plan->ShouldReportStop (event_ptr); 103 if (log) 104 log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", GetVoteAsCString (prev_vote)); 105 return prev_vote; 106 } 107 } 108 if (log) 109 log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote)); 110 return m_stop_vote; 111} 112 113Vote 114ThreadPlan::ShouldReportRun (Event *event_ptr) 115{ 116 if (m_run_vote == eVoteNoOpinion) 117 { 118 ThreadPlan *prev_plan = GetPreviousPlan (); 119 if (prev_plan) 120 return prev_plan->ShouldReportRun (event_ptr); 121 } 122 return m_run_vote; 123} 124 125bool 126ThreadPlan::StopOthers () 127{ 128 ThreadPlan *prev_plan; 129 prev_plan = GetPreviousPlan (); 130 if (prev_plan == NULL) 131 return false; 132 else 133 return prev_plan->StopOthers(); 134} 135 136bool 137ThreadPlan::WillResume (StateType resume_state, bool current_plan) 138{ 139 if (current_plan) 140 { 141 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 142 143 if (log) 144 { 145 RegisterContext *reg_ctx = m_thread.GetRegisterContext(); 146 addr_t pc = reg_ctx->GetPC(); 147 addr_t sp = reg_ctx->GetSP(); 148 addr_t fp = reg_ctx->GetFP(); 149 log->Printf("%s Thread #%u: tid = 0x%4.4x, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, plan = '%s', state = %s, stop others = %d", 150 __FUNCTION__, 151 m_thread.GetIndexID(), 152 m_thread.GetID(), 153 (uint64_t)pc, 154 (uint64_t)sp, 155 (uint64_t)fp, 156 m_name.c_str(), 157 StateAsCString(resume_state), 158 StopOthers()); 159 } 160 } 161 return true; 162} 163 164lldb::user_id_t 165ThreadPlan::GetNextID() 166{ 167 static uint32_t g_nextPlanID = 0; 168 return ++g_nextPlanID; 169} 170 171void 172ThreadPlan::DidPush() 173{ 174} 175 176void 177ThreadPlan::WillPop() 178{ 179} 180 181void 182ThreadPlan::PushPlan (ThreadPlanSP &thread_plan_sp) 183{ 184 m_thread.PushPlan (thread_plan_sp); 185} 186 187ThreadPlan * 188ThreadPlan::GetPreviousPlan () 189{ 190 return m_thread.GetPreviousPlan (this); 191} 192 193void 194ThreadPlan::SetPrivate (bool input) 195{ 196 m_plan_private = input; 197} 198 199bool 200ThreadPlan::GetPrivate (void) 201{ 202 return m_plan_private; 203} 204 205bool 206ThreadPlan::OkayToDiscard() 207{ 208 if (!IsMasterPlan()) 209 return true; 210 else 211 return m_okay_to_discard; 212} 213 214lldb::StateType 215ThreadPlan::RunState () 216{ 217 if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled()) 218 return eStateStepping; 219 else 220 return GetPlanRunState(); 221} 222