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/lldb-python.h" 11 12 #include "lldb/Target/ThreadPlan.h" 13 14 // C Includes 15 // C++ Includes 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Core/Debugger.h" 19 #include "lldb/Core/Log.h" 20 #include "lldb/Core/State.h" 21 #include "lldb/Target/RegisterContext.h" 22 #include "lldb/Target/Thread.h" 23 #include "lldb/Target/Process.h" 24 #include "lldb/Target/Target.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 //---------------------------------------------------------------------- 30 // ThreadPlan constructor 31 //---------------------------------------------------------------------- 32 ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) : 33 m_thread (thread), 34 m_stop_vote (stop_vote), 35 m_run_vote (run_vote), 36 m_kind (kind), 37 m_name (name), 38 m_plan_complete_mutex (Mutex::eMutexTypeRecursive), 39 m_plan_complete (false), 40 m_plan_private (false), 41 m_okay_to_discard (true), 42 m_is_master_plan (false), 43 m_plan_succeeded(true) 44 { 45 SetID (GetNextID()); 46 } 47 48 //---------------------------------------------------------------------- 49 // Destructor 50 //---------------------------------------------------------------------- 51 ThreadPlan::~ThreadPlan() 52 { 53 } 54 55 bool 56 ThreadPlan::IsPlanComplete () 57 { 58 Mutex::Locker locker(m_plan_complete_mutex); 59 return m_plan_complete; 60 } 61 62 void 63 ThreadPlan::SetPlanComplete (bool success) 64 { 65 Mutex::Locker locker(m_plan_complete_mutex); 66 m_plan_complete = true; 67 m_plan_succeeded = success; 68 } 69 70 bool 71 ThreadPlan::MischiefManaged () 72 { 73 Mutex::Locker locker(m_plan_complete_mutex); 74 // Mark the plan is complete, but don't override the success flag. 75 m_plan_complete = true; 76 return true; 77 } 78 79 Vote 80 ThreadPlan::ShouldReportStop (Event *event_ptr) 81 { 82 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 83 84 if (m_stop_vote == eVoteNoOpinion) 85 { 86 ThreadPlan *prev_plan = GetPreviousPlan (); 87 if (prev_plan) 88 { 89 Vote prev_vote = prev_plan->ShouldReportStop (event_ptr); 90 if (log) 91 log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", 92 GetVoteAsCString (prev_vote)); 93 return prev_vote; 94 } 95 } 96 if (log) 97 log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote)); 98 return m_stop_vote; 99 } 100 101 Vote 102 ThreadPlan::ShouldReportRun (Event *event_ptr) 103 { 104 if (m_run_vote == eVoteNoOpinion) 105 { 106 ThreadPlan *prev_plan = GetPreviousPlan (); 107 if (prev_plan) 108 return prev_plan->ShouldReportRun (event_ptr); 109 } 110 return m_run_vote; 111 } 112 113 bool 114 ThreadPlan::StopOthers () 115 { 116 ThreadPlan *prev_plan; 117 prev_plan = GetPreviousPlan (); 118 if (prev_plan == NULL) 119 return false; 120 else 121 return prev_plan->StopOthers(); 122 } 123 124 void 125 ThreadPlan::SetStopOthers (bool new_value) 126 { 127 // SetStopOthers doesn't work up the hierarchy. You have to set the 128 // explicit ThreadPlan you want to affect. 129 } 130 131 bool 132 ThreadPlan::WillResume (StateType resume_state, bool current_plan) 133 { 134 if (current_plan) 135 { 136 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 137 138 if (log) 139 { 140 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 141 addr_t pc = reg_ctx->GetPC(); 142 addr_t sp = reg_ctx->GetSP(); 143 addr_t fp = reg_ctx->GetFP(); 144 log->Printf("%s Thread #%u: tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", " 145 "plan = '%s', state = %s, stop others = %d", 146 __FUNCTION__, 147 m_thread.GetIndexID(), 148 m_thread.GetID(), 149 (uint64_t)pc, 150 (uint64_t)sp, 151 (uint64_t)fp, 152 m_name.c_str(), 153 StateAsCString(resume_state), 154 StopOthers()); 155 } 156 } 157 return true; 158 } 159 160 lldb::user_id_t 161 ThreadPlan::GetNextID() 162 { 163 static uint32_t g_nextPlanID = 0; 164 return ++g_nextPlanID; 165 } 166 167 void 168 ThreadPlan::DidPush() 169 { 170 } 171 172 void 173 ThreadPlan::WillPop() 174 { 175 } 176 177 bool 178 ThreadPlan::OkayToDiscard() 179 { 180 if (!IsMasterPlan()) 181 return true; 182 else 183 return m_okay_to_discard; 184 } 185 186 lldb::StateType 187 ThreadPlan::RunState () 188 { 189 if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled()) 190 return eStateStepping; 191 else 192 return GetPlanRunState(); 193 } 194