Home | History | Annotate | Download | only in Target
      1 //===-- ThreadPlanStepOverBreakpoint.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/ThreadPlanStepOverBreakpoint.h"
     11 
     12 // C Includes
     13 // C++ Includes
     14 // Other libraries and framework includes
     15 // Project includes
     16 #include "lldb/lldb-private-log.h"
     17 #include "lldb/Core/Log.h"
     18 #include "lldb/Core/Stream.h"
     19 #include "lldb/Target/Process.h"
     20 #include "lldb/Target/RegisterContext.h"
     21 
     22 using namespace lldb;
     23 using namespace lldb_private;
     24 
     25 //----------------------------------------------------------------------
     26 // ThreadPlanStepOverBreakpoint: Single steps over a breakpoint bp_site_sp at the pc.
     27 //----------------------------------------------------------------------
     28 
     29 ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint (Thread &thread) :
     30     ThreadPlan (ThreadPlan::eKindStepOverBreakpoint, "Step over breakpoint trap",
     31                 thread,
     32                 eVoteNo,
     33                 eVoteNoOpinion),  // We need to report the run since this happens
     34                             // first in the thread plan stack when stepping
     35                             // over a breakpoint
     36     m_breakpoint_addr (LLDB_INVALID_ADDRESS),
     37     m_auto_continue(false),
     38     m_reenabled_breakpoint_site (false)
     39 
     40 {
     41     m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC();
     42     m_breakpoint_site_id =  m_thread.GetProcess()->GetBreakpointSiteList().FindIDByAddress (m_breakpoint_addr);
     43 }
     44 
     45 ThreadPlanStepOverBreakpoint::~ThreadPlanStepOverBreakpoint ()
     46 {
     47 }
     48 
     49 void
     50 ThreadPlanStepOverBreakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
     51 {
     52     s->Printf("Single stepping past breakpoint site %" PRIu64 " at 0x%" PRIx64, m_breakpoint_site_id, (uint64_t)m_breakpoint_addr);
     53 }
     54 
     55 bool
     56 ThreadPlanStepOverBreakpoint::ValidatePlan (Stream *error)
     57 {
     58     return true;
     59 }
     60 
     61 bool
     62 ThreadPlanStepOverBreakpoint::DoPlanExplainsStop (Event *event_ptr)
     63 {
     64     StopInfoSP stop_info_sp = GetPrivateStopInfo ();
     65     if (stop_info_sp)
     66     {
     67         StopReason reason = stop_info_sp->GetStopReason();
     68         if (reason == eStopReasonTrace || reason == eStopReasonNone)
     69             return true;
     70         else
     71             return false;
     72     }
     73     return false;
     74 }
     75 
     76 bool
     77 ThreadPlanStepOverBreakpoint::ShouldStop (Event *event_ptr)
     78 {
     79     return false;
     80 }
     81 
     82 bool
     83 ThreadPlanStepOverBreakpoint::StopOthers ()
     84 {
     85     return true;
     86 }
     87 
     88 StateType
     89 ThreadPlanStepOverBreakpoint::GetPlanRunState ()
     90 {
     91     return eStateStepping;
     92 }
     93 
     94 bool
     95 ThreadPlanStepOverBreakpoint::DoWillResume (StateType resume_state, bool current_plan)
     96 {
     97     if (current_plan)
     98     {
     99         BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
    100         if (bp_site_sp  && bp_site_sp->IsEnabled())
    101             m_thread.GetProcess()->DisableBreakpointSite (bp_site_sp.get());
    102     }
    103     return true;
    104 }
    105 
    106 bool
    107 ThreadPlanStepOverBreakpoint::WillStop ()
    108 {
    109     ReenableBreakpointSite ();
    110     return true;
    111 }
    112 
    113 bool
    114 ThreadPlanStepOverBreakpoint::MischiefManaged ()
    115 {
    116     lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC();
    117 
    118     if (pc_addr == m_breakpoint_addr)
    119     {
    120         // If we are still at the PC of our breakpoint, then for some reason we didn't
    121         // get a chance to run.
    122         return false;
    123     }
    124     else
    125     {
    126         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    127         if (log)
    128             log->Printf("Completed step over breakpoint plan.");
    129         // Otherwise, re-enable the breakpoint we were stepping over, and we're done.
    130         ReenableBreakpointSite ();
    131         ThreadPlan::MischiefManaged ();
    132         return true;
    133     }
    134 }
    135 
    136 void
    137 ThreadPlanStepOverBreakpoint::ReenableBreakpointSite ()
    138 {
    139     if (!m_reenabled_breakpoint_site)
    140     {
    141         m_reenabled_breakpoint_site = true;
    142         BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
    143         if (bp_site_sp)
    144         {
    145             m_thread.GetProcess()->EnableBreakpointSite (bp_site_sp.get());
    146         }
    147     }
    148 }
    149 void
    150 ThreadPlanStepOverBreakpoint::ThreadDestroyed ()
    151 {
    152     ReenableBreakpointSite ();
    153 }
    154 
    155 void
    156 ThreadPlanStepOverBreakpoint::SetAutoContinue (bool do_it)
    157 {
    158     m_auto_continue = do_it;
    159 }
    160 
    161 bool
    162 ThreadPlanStepOverBreakpoint::ShouldAutoContinue (Event *event_ptr)
    163 {
    164     return m_auto_continue;
    165 }
    166