1254721Semaste//===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "lldb/Target/ThreadPlan.h" 13254721Semaste 14254721Semaste// C Includes 15254721Semaste// C++ Includes 16254721Semaste// Other libraries and framework includes 17254721Semaste// Project includes 18254721Semaste#include "lldb/Core/Debugger.h" 19254721Semaste#include "lldb/Core/Log.h" 20254721Semaste#include "lldb/Core/State.h" 21254721Semaste#include "lldb/Target/RegisterContext.h" 22254721Semaste#include "lldb/Target/Thread.h" 23254721Semaste#include "lldb/Target/Process.h" 24254721Semaste#include "lldb/Target/Target.h" 25254721Semaste 26254721Semasteusing namespace lldb; 27254721Semasteusing namespace lldb_private; 28254721Semaste 29254721Semaste//---------------------------------------------------------------------- 30254721Semaste// ThreadPlan constructor 31254721Semaste//---------------------------------------------------------------------- 32254721SemasteThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) : 33254721Semaste m_thread (thread), 34254721Semaste m_stop_vote (stop_vote), 35254721Semaste m_run_vote (run_vote), 36254721Semaste m_kind (kind), 37254721Semaste m_name (name), 38254721Semaste m_plan_complete_mutex (Mutex::eMutexTypeRecursive), 39254721Semaste m_cached_plan_explains_stop (eLazyBoolCalculate), 40254721Semaste m_plan_complete (false), 41254721Semaste m_plan_private (false), 42254721Semaste m_okay_to_discard (true), 43254721Semaste m_is_master_plan (false), 44254721Semaste m_plan_succeeded(true) 45254721Semaste{ 46254721Semaste SetID (GetNextID()); 47254721Semaste} 48254721Semaste 49254721Semaste//---------------------------------------------------------------------- 50254721Semaste// Destructor 51254721Semaste//---------------------------------------------------------------------- 52254721SemasteThreadPlan::~ThreadPlan() 53254721Semaste{ 54254721Semaste} 55254721Semaste 56254721Semastebool 57254721SemasteThreadPlan::PlanExplainsStop (Event *event_ptr) 58254721Semaste{ 59254721Semaste if (m_cached_plan_explains_stop == eLazyBoolCalculate) 60254721Semaste { 61254721Semaste bool actual_value = DoPlanExplainsStop(event_ptr); 62254721Semaste m_cached_plan_explains_stop = actual_value ? eLazyBoolYes : eLazyBoolNo; 63254721Semaste return actual_value; 64254721Semaste } 65254721Semaste else 66254721Semaste { 67254721Semaste return m_cached_plan_explains_stop == eLazyBoolYes; 68254721Semaste } 69254721Semaste} 70254721Semaste 71254721Semastebool 72254721SemasteThreadPlan::IsPlanComplete () 73254721Semaste{ 74254721Semaste Mutex::Locker locker(m_plan_complete_mutex); 75254721Semaste return m_plan_complete; 76254721Semaste} 77254721Semaste 78254721Semastevoid 79254721SemasteThreadPlan::SetPlanComplete (bool success) 80254721Semaste{ 81254721Semaste Mutex::Locker locker(m_plan_complete_mutex); 82254721Semaste m_plan_complete = true; 83254721Semaste m_plan_succeeded = success; 84254721Semaste} 85254721Semaste 86254721Semastebool 87254721SemasteThreadPlan::MischiefManaged () 88254721Semaste{ 89254721Semaste Mutex::Locker locker(m_plan_complete_mutex); 90254721Semaste // Mark the plan is complete, but don't override the success flag. 91254721Semaste m_plan_complete = true; 92254721Semaste return true; 93254721Semaste} 94254721Semaste 95254721SemasteVote 96254721SemasteThreadPlan::ShouldReportStop (Event *event_ptr) 97254721Semaste{ 98254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 99254721Semaste 100254721Semaste if (m_stop_vote == eVoteNoOpinion) 101254721Semaste { 102254721Semaste ThreadPlan *prev_plan = GetPreviousPlan (); 103254721Semaste if (prev_plan) 104254721Semaste { 105254721Semaste Vote prev_vote = prev_plan->ShouldReportStop (event_ptr); 106254721Semaste if (log) 107254721Semaste log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", 108254721Semaste GetVoteAsCString (prev_vote)); 109254721Semaste return prev_vote; 110254721Semaste } 111254721Semaste } 112254721Semaste if (log) 113254721Semaste log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote)); 114254721Semaste return m_stop_vote; 115254721Semaste} 116254721Semaste 117254721SemasteVote 118254721SemasteThreadPlan::ShouldReportRun (Event *event_ptr) 119254721Semaste{ 120254721Semaste if (m_run_vote == eVoteNoOpinion) 121254721Semaste { 122254721Semaste ThreadPlan *prev_plan = GetPreviousPlan (); 123254721Semaste if (prev_plan) 124254721Semaste return prev_plan->ShouldReportRun (event_ptr); 125254721Semaste } 126254721Semaste return m_run_vote; 127254721Semaste} 128254721Semaste 129254721Semastebool 130254721SemasteThreadPlan::StopOthers () 131254721Semaste{ 132254721Semaste ThreadPlan *prev_plan; 133254721Semaste prev_plan = GetPreviousPlan (); 134254721Semaste if (prev_plan == NULL) 135254721Semaste return false; 136254721Semaste else 137254721Semaste return prev_plan->StopOthers(); 138254721Semaste} 139254721Semaste 140254721Semastevoid 141254721SemasteThreadPlan::SetStopOthers (bool new_value) 142254721Semaste{ 143254721Semaste // SetStopOthers doesn't work up the hierarchy. You have to set the 144254721Semaste // explicit ThreadPlan you want to affect. 145254721Semaste} 146254721Semaste 147254721Semastebool 148254721SemasteThreadPlan::WillResume (StateType resume_state, bool current_plan) 149254721Semaste{ 150254721Semaste m_cached_plan_explains_stop = eLazyBoolCalculate; 151254721Semaste 152254721Semaste if (current_plan) 153254721Semaste { 154254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 155254721Semaste 156254721Semaste if (log) 157254721Semaste { 158254721Semaste RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 159254721Semaste addr_t pc = reg_ctx->GetPC(); 160254721Semaste addr_t sp = reg_ctx->GetSP(); 161254721Semaste addr_t fp = reg_ctx->GetFP(); 162254721Semaste 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 ", " 163254721Semaste "plan = '%s', state = %s, stop others = %d", 164254721Semaste __FUNCTION__, 165254721Semaste m_thread.GetIndexID(), 166254721Semaste &m_thread, 167254721Semaste m_thread.GetID(), 168254721Semaste (uint64_t)pc, 169254721Semaste (uint64_t)sp, 170254721Semaste (uint64_t)fp, 171254721Semaste m_name.c_str(), 172254721Semaste StateAsCString(resume_state), 173254721Semaste StopOthers()); 174254721Semaste } 175254721Semaste } 176254721Semaste return DoWillResume (resume_state, current_plan); 177254721Semaste} 178254721Semaste 179254721Semastelldb::user_id_t 180254721SemasteThreadPlan::GetNextID() 181254721Semaste{ 182254721Semaste static uint32_t g_nextPlanID = 0; 183254721Semaste return ++g_nextPlanID; 184254721Semaste} 185254721Semaste 186254721Semastevoid 187254721SemasteThreadPlan::DidPush() 188254721Semaste{ 189254721Semaste} 190254721Semaste 191254721Semastevoid 192254721SemasteThreadPlan::WillPop() 193254721Semaste{ 194254721Semaste} 195254721Semaste 196254721Semastebool 197254721SemasteThreadPlan::OkayToDiscard() 198254721Semaste{ 199254721Semaste if (!IsMasterPlan()) 200254721Semaste return true; 201254721Semaste else 202254721Semaste return m_okay_to_discard; 203254721Semaste} 204254721Semaste 205254721Semastelldb::StateType 206254721SemasteThreadPlan::RunState () 207254721Semaste{ 208254721Semaste if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled()) 209254721Semaste return eStateStepping; 210254721Semaste else 211254721Semaste return GetPlanRunState(); 212254721Semaste} 213254721Semaste 214254721Semaste//---------------------------------------------------------------------- 215254721Semaste// ThreadPlanNull 216254721Semaste//---------------------------------------------------------------------- 217254721Semaste 218254721SemasteThreadPlanNull::ThreadPlanNull (Thread &thread) : 219254721Semaste ThreadPlan (ThreadPlan::eKindNull, 220254721Semaste "Null Thread Plan", 221254721Semaste thread, 222254721Semaste eVoteNoOpinion, 223254721Semaste eVoteNoOpinion) 224254721Semaste{ 225254721Semaste} 226254721Semaste 227254721SemasteThreadPlanNull::~ThreadPlanNull () 228254721Semaste{ 229254721Semaste} 230254721Semaste 231254721Semastevoid 232254721SemasteThreadPlanNull::GetDescription (Stream *s, 233254721Semaste lldb::DescriptionLevel level) 234254721Semaste{ 235254721Semaste s->PutCString("Null thread plan - thread has been destroyed."); 236254721Semaste} 237254721Semaste 238254721Semastebool 239254721SemasteThreadPlanNull::ValidatePlan (Stream *error) 240254721Semaste{ 241254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 242254721Semaste fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 243254721Semaste __PRETTY_FUNCTION__, 244254721Semaste m_thread.GetID(), 245254721Semaste m_thread.GetProtocolID()); 246254721Semaste#else 247254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 248254721Semaste if (log) 249254721Semaste log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 250254721Semaste __PRETTY_FUNCTION__, 251254721Semaste m_thread.GetID(), 252254721Semaste m_thread.GetProtocolID()); 253254721Semaste#endif 254254721Semaste return true; 255254721Semaste} 256254721Semaste 257254721Semastebool 258254721SemasteThreadPlanNull::ShouldStop (Event *event_ptr) 259254721Semaste{ 260254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 261254721Semaste fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 262254721Semaste __PRETTY_FUNCTION__, 263254721Semaste m_thread.GetID(), 264254721Semaste m_thread.GetProtocolID()); 265254721Semaste#else 266254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 267254721Semaste if (log) 268254721Semaste log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 269254721Semaste __PRETTY_FUNCTION__, 270254721Semaste m_thread.GetID(), 271254721Semaste m_thread.GetProtocolID()); 272254721Semaste#endif 273254721Semaste return true; 274254721Semaste} 275254721Semaste 276254721Semastebool 277254721SemasteThreadPlanNull::WillStop () 278254721Semaste{ 279254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 280254721Semaste fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 281254721Semaste __PRETTY_FUNCTION__, 282254721Semaste m_thread.GetID(), 283254721Semaste m_thread.GetProtocolID()); 284254721Semaste#else 285254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 286254721Semaste if (log) 287254721Semaste log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 288254721Semaste __PRETTY_FUNCTION__, 289254721Semaste m_thread.GetID(), 290254721Semaste m_thread.GetProtocolID()); 291254721Semaste#endif 292254721Semaste return true; 293254721Semaste} 294254721Semaste 295254721Semastebool 296254721SemasteThreadPlanNull::DoPlanExplainsStop (Event *event_ptr) 297254721Semaste{ 298254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 299254721Semaste fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 300254721Semaste __PRETTY_FUNCTION__, 301254721Semaste m_thread.GetID(), 302254721Semaste m_thread.GetProtocolID()); 303254721Semaste#else 304254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 305254721Semaste if (log) 306254721Semaste log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 307254721Semaste __PRETTY_FUNCTION__, 308254721Semaste m_thread.GetID(), 309254721Semaste m_thread.GetProtocolID()); 310254721Semaste#endif 311254721Semaste return true; 312254721Semaste} 313254721Semaste 314254721Semaste// The null plan is never done. 315254721Semastebool 316254721SemasteThreadPlanNull::MischiefManaged () 317254721Semaste{ 318254721Semaste // The null plan is never done. 319254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 320254721Semaste fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 321254721Semaste __PRETTY_FUNCTION__, 322254721Semaste m_thread.GetID(), 323254721Semaste m_thread.GetProtocolID()); 324254721Semaste#else 325254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 326254721Semaste if (log) 327254721Semaste log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 328254721Semaste __PRETTY_FUNCTION__, 329254721Semaste m_thread.GetID(), 330254721Semaste m_thread.GetProtocolID()); 331254721Semaste#endif 332254721Semaste return false; 333254721Semaste} 334254721Semaste 335254721Semastelldb::StateType 336254721SemasteThreadPlanNull::GetPlanRunState () 337254721Semaste{ 338254721Semaste // Not sure what to return here. This is a dead thread. 339254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 340254721Semaste fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 341254721Semaste __PRETTY_FUNCTION__, 342254721Semaste m_thread.GetID(), 343254721Semaste m_thread.GetProtocolID()); 344254721Semaste#else 345254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 346254721Semaste if (log) 347254721Semaste log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", 348254721Semaste __PRETTY_FUNCTION__, 349254721Semaste m_thread.GetID(), 350254721Semaste m_thread.GetProtocolID()); 351254721Semaste#endif 352254721Semaste return eStateRunning; 353254721Semaste} 354