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 (true), 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 // Mark the plan is complete, but don't override the success flag. 73 m_plan_complete = true; 74 return true; 75 } 76 77 Vote 78 ThreadPlan::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 99 Vote 100 ThreadPlan::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 111 bool 112 ThreadPlan::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 122 void 123 ThreadPlan::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 129 bool 130 ThreadPlan::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.4llx, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, " 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 158 lldb::user_id_t 159 ThreadPlan::GetNextID() 160 { 161 static uint32_t g_nextPlanID = 0; 162 return ++g_nextPlanID; 163 } 164 165 void 166 ThreadPlan::DidPush() 167 { 168 } 169 170 void 171 ThreadPlan::WillPop() 172 { 173 } 174 175 bool 176 ThreadPlan::OkayToDiscard() 177 { 178 if (!IsMasterPlan()) 179 return true; 180 else 181 return m_okay_to_discard; 182 } 183 184 lldb::StateType 185 ThreadPlan::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