ThreadPlan.cpp revision 5f35a4be95aed0e5b2cb36f7d785bcbfc67284ae
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 (true), 40 m_is_master_plan (false), 41 m_plan_succeeded(true) 42{ 43 SetID (GetNextID()); 44} 45 46//---------------------------------------------------------------------- 47// Destructor 48//---------------------------------------------------------------------- 49ThreadPlan::~ThreadPlan() 50{ 51} 52 53bool 54ThreadPlan::IsPlanComplete () 55{ 56 Mutex::Locker locker(m_plan_complete_mutex); 57 return m_plan_complete; 58} 59 60void 61ThreadPlan::SetPlanComplete (bool success) 62{ 63 Mutex::Locker locker(m_plan_complete_mutex); 64 m_plan_complete = true; 65 m_plan_succeeded = success; 66} 67 68bool 69ThreadPlan::MischiefManaged () 70{ 71 Mutex::Locker locker(m_plan_complete_mutex); 72 // Mark the plan is complete, but don't override the success flag. 73 m_plan_complete = true; 74 return true; 75} 76 77Vote 78ThreadPlan::ShouldReportStop (Event *event_ptr) 79{ 80 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 81 82 if (m_stop_vote == eVoteNoOpinion) 83 { 84 ThreadPlan *prev_plan = GetPreviousPlan (); 85 if (prev_plan) 86 { 87 Vote prev_vote = prev_plan->ShouldReportStop (event_ptr); 88 if (log) 89 log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", 90 GetVoteAsCString (prev_vote)); 91 return prev_vote; 92 } 93 } 94 if (log) 95 log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote)); 96 return m_stop_vote; 97} 98 99Vote 100ThreadPlan::ShouldReportRun (Event *event_ptr) 101{ 102 if (m_run_vote == eVoteNoOpinion) 103 { 104 ThreadPlan *prev_plan = GetPreviousPlan (); 105 if (prev_plan) 106 return prev_plan->ShouldReportRun (event_ptr); 107 } 108 return m_run_vote; 109} 110 111bool 112ThreadPlan::StopOthers () 113{ 114 ThreadPlan *prev_plan; 115 prev_plan = GetPreviousPlan (); 116 if (prev_plan == NULL) 117 return false; 118 else 119 return prev_plan->StopOthers(); 120} 121 122void 123ThreadPlan::SetStopOthers (bool new_value) 124{ 125 // SetStopOthers doesn't work up the hierarchy. You have to set the 126 // explicit ThreadPlan you want to affect. 127} 128 129bool 130ThreadPlan::WillResume (StateType resume_state, bool current_plan) 131{ 132 if (current_plan) 133 { 134 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 135 136 if (log) 137 { 138 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 139 addr_t pc = reg_ctx->GetPC(); 140 addr_t sp = reg_ctx->GetSP(); 141 addr_t fp = reg_ctx->GetFP(); 142 log->Printf("%s Thread #%u: tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", " 143 "plan = '%s', state = %s, stop others = %d", 144 __FUNCTION__, 145 m_thread.GetIndexID(), 146 m_thread.GetID(), 147 (uint64_t)pc, 148 (uint64_t)sp, 149 (uint64_t)fp, 150 m_name.c_str(), 151 StateAsCString(resume_state), 152 StopOthers()); 153 } 154 } 155 return true; 156} 157 158lldb::user_id_t 159ThreadPlan::GetNextID() 160{ 161 static uint32_t g_nextPlanID = 0; 162 return ++g_nextPlanID; 163} 164 165void 166ThreadPlan::DidPush() 167{ 168} 169 170void 171ThreadPlan::WillPop() 172{ 173} 174 175bool 176ThreadPlan::OkayToDiscard() 177{ 178 if (!IsMasterPlan()) 179 return true; 180 else 181 return m_okay_to_discard; 182} 183 184lldb::StateType 185ThreadPlan::RunState () 186{ 187 if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled()) 188 return eStateStepping; 189 else 190 return GetPlanRunState(); 191} 192