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