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