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 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/Target/ThreadPlan.h" 15 #include "lldb/Core/Debugger.h" 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 #include "lldb/Target/Process.h" 21 #include "lldb/Target/Target.h" 22 #include "lldb/Utility/ConvertEnum.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(), 37 m_cached_plan_explains_stop(eLazyBoolCalculate), 38 m_plan_complete(false), 39 m_plan_private(false), 40 m_okay_to_discard(true), 41 m_is_master_plan(false), 42 m_plan_succeeded(true) 43 { 44 SetID(GetNextID()); 45 } 46 47 //---------------------------------------------------------------------- 48 // Destructor 49 //---------------------------------------------------------------------- 50 ThreadPlan::~ThreadPlan() = default; 51 52 bool 53 ThreadPlan::PlanExplainsStop (Event *event_ptr) 54 { 55 if (m_cached_plan_explains_stop == eLazyBoolCalculate) 56 { 57 bool actual_value = DoPlanExplainsStop(event_ptr); 58 m_cached_plan_explains_stop = actual_value ? eLazyBoolYes : eLazyBoolNo; 59 return actual_value; 60 } 61 else 62 { 63 return m_cached_plan_explains_stop == eLazyBoolYes; 64 } 65 } 66 67 bool 68 ThreadPlan::IsPlanComplete () 69 { 70 std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex); 71 return m_plan_complete; 72 } 73 74 void 75 ThreadPlan::SetPlanComplete (bool success) 76 { 77 std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex); 78 m_plan_complete = true; 79 m_plan_succeeded = success; 80 } 81 82 bool 83 ThreadPlan::MischiefManaged () 84 { 85 std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex); 86 // Mark the plan is complete, but don't override the success flag. 87 m_plan_complete = true; 88 return true; 89 } 90 91 Vote 92 ThreadPlan::ShouldReportStop (Event *event_ptr) 93 { 94 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 95 96 if (m_stop_vote == eVoteNoOpinion) 97 { 98 ThreadPlan *prev_plan = GetPreviousPlan (); 99 if (prev_plan) 100 { 101 Vote prev_vote = prev_plan->ShouldReportStop (event_ptr); 102 if (log) 103 log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", 104 GetVoteAsCString (prev_vote)); 105 return prev_vote; 106 } 107 } 108 if (log) 109 log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote)); 110 return m_stop_vote; 111 } 112 113 Vote 114 ThreadPlan::ShouldReportRun (Event *event_ptr) 115 { 116 if (m_run_vote == eVoteNoOpinion) 117 { 118 ThreadPlan *prev_plan = GetPreviousPlan (); 119 if (prev_plan) 120 return prev_plan->ShouldReportRun (event_ptr); 121 } 122 return m_run_vote; 123 } 124 125 bool 126 ThreadPlan::StopOthers () 127 { 128 ThreadPlan *prev_plan; 129 prev_plan = GetPreviousPlan (); 130 return (prev_plan == nullptr) ? false : prev_plan->StopOthers(); 131 } 132 133 void 134 ThreadPlan::SetStopOthers (bool new_value) 135 { 136 // SetStopOthers doesn't work up the hierarchy. You have to set the 137 // explicit ThreadPlan you want to affect. 138 } 139 140 bool 141 ThreadPlan::WillResume (StateType resume_state, bool current_plan) 142 { 143 m_cached_plan_explains_stop = eLazyBoolCalculate; 144 145 if (current_plan) 146 { 147 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 148 149 if (log) 150 { 151 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 152 assert (reg_ctx); 153 addr_t pc = reg_ctx->GetPC(); 154 addr_t sp = reg_ctx->GetSP(); 155 addr_t fp = reg_ctx->GetFP(); 156 log->Printf("%s Thread #%u (0x%p): tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", " 157 "plan = '%s', state = %s, stop others = %d", 158 __FUNCTION__, m_thread.GetIndexID(), 159 static_cast<void*>(&m_thread), m_thread.GetID(), 160 static_cast<uint64_t>(pc), static_cast<uint64_t>(sp), 161 static_cast<uint64_t>(fp), m_name.c_str(), 162 StateAsCString(resume_state), StopOthers()); 163 } 164 } 165 return DoWillResume (resume_state, current_plan); 166 } 167 168 lldb::user_id_t 169 ThreadPlan::GetNextID() 170 { 171 static uint32_t g_nextPlanID = 0; 172 return ++g_nextPlanID; 173 } 174 175 void 176 ThreadPlan::DidPush() 177 { 178 } 179 180 void 181 ThreadPlan::WillPop() 182 { 183 } 184 185 bool 186 ThreadPlan::OkayToDiscard() 187 { 188 return IsMasterPlan() ? m_okay_to_discard : true; 189 } 190 191 lldb::StateType 192 ThreadPlan::RunState () 193 { 194 if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled()) 195 return eStateStepping; 196 else 197 return GetPlanRunState(); 198 } 199 200 bool 201 ThreadPlan::IsUsuallyUnexplainedStopReason(lldb::StopReason reason) 202 { 203 switch (reason) 204 { 205 case eStopReasonWatchpoint: 206 case eStopReasonSignal: 207 case eStopReasonException: 208 case eStopReasonExec: 209 case eStopReasonThreadExiting: 210 case eStopReasonInstrumentation: 211 return true; 212 default: 213 return false; 214 } 215 } 216 217 //---------------------------------------------------------------------- 218 // ThreadPlanNull 219 //---------------------------------------------------------------------- 220 221 ThreadPlanNull::ThreadPlanNull (Thread &thread) : 222 ThreadPlan (ThreadPlan::eKindNull, 223 "Null Thread Plan", 224 thread, 225 eVoteNoOpinion, 226 eVoteNoOpinion) 227 { 228 } 229 230 ThreadPlanNull::~ThreadPlanNull() = default; 231 232 void 233 ThreadPlanNull::GetDescription (Stream *s, 234 lldb::DescriptionLevel level) 235 { 236 s->PutCString("Null thread plan - thread has been destroyed."); 237 } 238 239 bool 240 ThreadPlanNull::ValidatePlan (Stream *error) 241 { 242 #ifdef LLDB_CONFIGURATION_DEBUG 243 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 244 __PRETTY_FUNCTION__, 245 m_thread.GetID(), 246 m_thread.GetProtocolID()); 247 #else 248 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 249 if (log) 250 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 251 __PRETTY_FUNCTION__, 252 m_thread.GetID(), 253 m_thread.GetProtocolID()); 254 #endif 255 return true; 256 } 257 258 bool 259 ThreadPlanNull::ShouldStop (Event *event_ptr) 260 { 261 #ifdef LLDB_CONFIGURATION_DEBUG 262 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 263 __PRETTY_FUNCTION__, 264 m_thread.GetID(), 265 m_thread.GetProtocolID()); 266 #else 267 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 268 if (log) 269 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 270 __PRETTY_FUNCTION__, 271 m_thread.GetID(), 272 m_thread.GetProtocolID()); 273 #endif 274 return true; 275 } 276 277 bool 278 ThreadPlanNull::WillStop () 279 { 280 #ifdef LLDB_CONFIGURATION_DEBUG 281 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 282 __PRETTY_FUNCTION__, 283 m_thread.GetID(), 284 m_thread.GetProtocolID()); 285 #else 286 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 287 if (log) 288 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 289 __PRETTY_FUNCTION__, 290 m_thread.GetID(), 291 m_thread.GetProtocolID()); 292 #endif 293 return true; 294 } 295 296 bool 297 ThreadPlanNull::DoPlanExplainsStop (Event *event_ptr) 298 { 299 #ifdef LLDB_CONFIGURATION_DEBUG 300 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 301 __PRETTY_FUNCTION__, 302 m_thread.GetID(), 303 m_thread.GetProtocolID()); 304 #else 305 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 306 if (log) 307 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 308 __PRETTY_FUNCTION__, 309 m_thread.GetID(), 310 m_thread.GetProtocolID()); 311 #endif 312 return true; 313 } 314 315 // The null plan is never done. 316 bool 317 ThreadPlanNull::MischiefManaged () 318 { 319 // The null plan is never done. 320 #ifdef LLDB_CONFIGURATION_DEBUG 321 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 322 __PRETTY_FUNCTION__, 323 m_thread.GetID(), 324 m_thread.GetProtocolID()); 325 #else 326 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 327 if (log) 328 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 329 __PRETTY_FUNCTION__, 330 m_thread.GetID(), 331 m_thread.GetProtocolID()); 332 #endif 333 return false; 334 } 335 336 lldb::StateType 337 ThreadPlanNull::GetPlanRunState () 338 { 339 // Not sure what to return here. This is a dead thread. 340 #ifdef LLDB_CONFIGURATION_DEBUG 341 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 342 __PRETTY_FUNCTION__, 343 m_thread.GetID(), 344 m_thread.GetProtocolID()); 345 #else 346 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 347 if (log) 348 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 349 __PRETTY_FUNCTION__, 350 m_thread.GetID(), 351 m_thread.GetProtocolID()); 352 #endif 353 return eStateRunning; 354 } 355