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