forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			238 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			238 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- ThreadPlanBase.cpp --------------------------------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "lldb/Target/ThreadPlanBase.h"
 | |
| 
 | |
| // C Includes
 | |
| // C++ Includes
 | |
| // Other libraries and framework includes
 | |
| // Project includes
 | |
| //
 | |
| #include "lldb/Breakpoint/StoppointCallbackContext.h"
 | |
| #include "lldb/Breakpoint/BreakpointSite.h"
 | |
| #include "lldb/Breakpoint/BreakpointLocation.h"
 | |
| #include "lldb/Breakpoint/Breakpoint.h"
 | |
| #include "lldb/Core/Log.h"
 | |
| #include "lldb/Core/Stream.h"
 | |
| #include "lldb/Target/Process.h"
 | |
| #include "lldb/Target/RegisterContext.h"
 | |
| #include "lldb/Target/StopInfo.h"
 | |
| 
 | |
| using namespace lldb;
 | |
| using namespace lldb_private;
 | |
| 
 | |
| //----------------------------------------------------------------------
 | |
| // ThreadPlanBase: This one always stops, and never has anything particular
 | |
| // to do.
 | |
| // FIXME: The "signal handling" policies should probably go here.
 | |
| //----------------------------------------------------------------------
 | |
| 
 | |
| ThreadPlanBase::ThreadPlanBase (Thread &thread) :
 | |
|     ThreadPlan(ThreadPlan::eKindBase, "base plan", thread, eVoteYes, eVoteNoOpinion)
 | |
| {
 | |
|     // Set the tracer to a default tracer.
 | |
|     // FIXME: need to add a thread settings variable to pix various tracers...
 | |
| #define THREAD_PLAN_USE_ASSEMBLY_TRACER 1
 | |
| 
 | |
| #ifdef THREAD_PLAN_USE_ASSEMBLY_TRACER
 | |
|     ThreadPlanTracerSP new_tracer_sp (new ThreadPlanAssemblyTracer (m_thread));
 | |
| #else
 | |
|     ThreadPlanTracerSP new_tracer_sp (new ThreadPlanTracer (m_thread));
 | |
| #endif
 | |
|     new_tracer_sp->EnableTracing (m_thread.GetTraceEnabledState());
 | |
|     SetThreadPlanTracer(new_tracer_sp);
 | |
|     SetIsMasterPlan (true);
 | |
| }
 | |
| 
 | |
| ThreadPlanBase::~ThreadPlanBase ()
 | |
| {
 | |
| 
 | |
| }
 | |
| 
 | |
| void
 | |
| ThreadPlanBase::GetDescription (Stream *s, lldb::DescriptionLevel level)
 | |
| {
 | |
|     s->Printf ("Base thread plan.");
 | |
| }
 | |
| 
 | |
| bool
 | |
| ThreadPlanBase::ValidatePlan (Stream *error)
 | |
| {
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool
 | |
| ThreadPlanBase::DoPlanExplainsStop (Event *event_ptr)
 | |
| {
 | |
|     // The base plan should defer to its tracer, since by default it
 | |
|     // always handles the stop.
 | |
|     if (TracerExplainsStop())
 | |
|         return false;
 | |
|     else
 | |
|         return true;
 | |
| }
 | |
| 
 | |
| Vote
 | |
| ThreadPlanBase::ShouldReportStop(Event *event_ptr)
 | |
| {
 | |
|     StopInfoSP stop_info_sp = m_thread.GetStopInfo ();
 | |
|     if (stop_info_sp)
 | |
|     {
 | |
|         bool should_notify = stop_info_sp->ShouldNotify(event_ptr);
 | |
|         if (should_notify)
 | |
|             return eVoteYes;
 | |
|         else
 | |
|             return eVoteNoOpinion;
 | |
|     }
 | |
|     else
 | |
|         return eVoteNoOpinion;
 | |
| }
 | |
| 
 | |
| bool
 | |
| ThreadPlanBase::ShouldStop (Event *event_ptr)
 | |
| {
 | |
|     m_stop_vote = eVoteYes;
 | |
|     m_run_vote = eVoteYes;
 | |
| 
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 | |
| 
 | |
|     StopInfoSP stop_info_sp = GetPrivateStopInfo ();
 | |
|     if (stop_info_sp)
 | |
|     {
 | |
|         StopReason reason = stop_info_sp->GetStopReason ();
 | |
|         switch (reason)
 | |
|         {
 | |
|         case eStopReasonInvalid:
 | |
|         case eStopReasonNone:
 | |
|             // This 
 | |
|             m_run_vote = eVoteNoOpinion;
 | |
|             m_stop_vote = eVoteNo;
 | |
|             return false;
 | |
| 
 | |
|         case eStopReasonBreakpoint:
 | |
|         case eStopReasonWatchpoint:
 | |
|             if (stop_info_sp->ShouldStopSynchronous(event_ptr))
 | |
|             {
 | |
|                 // If we are going to stop for a breakpoint, then unship the other plans
 | |
|                 // at this point.  Don't force the discard, however, so Master plans can stay
 | |
|                 // in place if they want to.
 | |
|                 if (log)
 | |
|                     log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (breakpoint hit.)", m_thread.GetID());
 | |
|                 m_thread.DiscardThreadPlans(false);
 | |
|                 return true;
 | |
|             }
 | |
|             // If we aren't going to stop at this breakpoint, and it is internal, 
 | |
|             // don't report this stop or the subsequent running event.  
 | |
|             // Otherwise we will post the stopped & running, but the stopped event will get marked
 | |
|             // with "restarted" so the UI will know to wait and expect the consequent "running".
 | |
|             if (stop_info_sp->ShouldNotify (event_ptr))
 | |
|             {
 | |
|                 m_stop_vote = eVoteYes;
 | |
|                 m_run_vote = eVoteYes;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 m_stop_vote = eVoteNo;
 | |
|                 m_run_vote = eVoteNo;
 | |
|             }
 | |
|             return false;
 | |
| 
 | |
|             // TODO: the break below was missing, was this intentional??? If so
 | |
|             // please mention it
 | |
|             break;
 | |
| 
 | |
|         case eStopReasonException:
 | |
|             // If we crashed, discard thread plans and stop.  Don't force the discard, however,
 | |
|             // since on rerun the target may clean up this exception and continue normally from there.
 | |
|                 if (log)
 | |
|                     log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (exception: %s)", m_thread.GetID(), stop_info_sp->GetDescription());
 | |
|             m_thread.DiscardThreadPlans(false);
 | |
|             return true;
 | |
| 
 | |
|         case eStopReasonExec:
 | |
|             // If we crashed, discard thread plans and stop.  Don't force the discard, however,
 | |
|             // since on rerun the target may clean up this exception and continue normally from there.
 | |
|             if (log)
 | |
|                 log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (exec.)", m_thread.GetID());
 | |
|             m_thread.DiscardThreadPlans(false);
 | |
|             return true;
 | |
| 
 | |
|         case eStopReasonThreadExiting:
 | |
|         case eStopReasonSignal:
 | |
|             if (stop_info_sp->ShouldStop(event_ptr))
 | |
|             {
 | |
|                 if (log)
 | |
|                     log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (signal: %s)", m_thread.GetID(), stop_info_sp->GetDescription());
 | |
|                 m_thread.DiscardThreadPlans(false);
 | |
|                 return true;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 // We're not going to stop, but while we are here, let's figure out
 | |
|                 // whether to report this.
 | |
|                  if (stop_info_sp->ShouldNotify(event_ptr))
 | |
|                     m_stop_vote = eVoteYes;
 | |
|                 else
 | |
|                     m_stop_vote = eVoteNo;
 | |
|             }
 | |
|             return false;
 | |
|             
 | |
|         default:
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         m_run_vote = eVoteNoOpinion;
 | |
|         m_stop_vote = eVoteNo;
 | |
|     }
 | |
| 
 | |
|     // If there's no explicit reason to stop, then we will continue.
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| ThreadPlanBase::StopOthers ()
 | |
| {
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| StateType
 | |
| ThreadPlanBase::GetPlanRunState ()
 | |
| {
 | |
|     return eStateRunning;
 | |
| }
 | |
| 
 | |
| bool
 | |
| ThreadPlanBase::WillStop ()
 | |
| {
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool 
 | |
| ThreadPlanBase::DoWillResume (lldb::StateType resume_state, bool current_plan)
 | |
| {
 | |
|     // Reset these to the default values so we don't set them wrong, then not get asked
 | |
|     // for a while, then return the wrong answer.
 | |
|     m_run_vote = eVoteNoOpinion;
 | |
|     m_stop_vote = eVoteNo;
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| 
 | |
| // The base plan is never done.
 | |
| bool
 | |
| ThreadPlanBase::MischiefManaged ()
 | |
| {
 | |
|     // The base plan is never done.
 | |
|     return false;
 | |
| }
 | |
| 
 |