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