1 //===-- ThreadPlanRunToAddress.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/ThreadPlanRunToAddress.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/Target.h" 20 #include "lldb/Target/Process.h" 21 #include "lldb/Target/Thread.h" 22 #include "lldb/Target/RegisterContext.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 //---------------------------------------------------------------------- 28 // ThreadPlanRunToAddress: Continue plan 29 //---------------------------------------------------------------------- 30 31 ThreadPlanRunToAddress::ThreadPlanRunToAddress 32 ( 33 Thread &thread, 34 Address &address, 35 bool stop_others 36 ) : 37 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to breakpoint plan", thread, eVoteNoOpinion, eVoteNoOpinion), 38 m_stop_others (stop_others), 39 m_address (LLDB_INVALID_ADDRESS), 40 m_break_id (LLDB_INVALID_BREAK_ID) 41 { 42 m_address = address.GetLoadAddress(&m_thread.GetProcess()); 43 SetInitialBreakpoint(); 44 } 45 46 ThreadPlanRunToAddress::ThreadPlanRunToAddress 47 ( 48 Thread &thread, 49 lldb::addr_t address, 50 bool stop_others 51 ) : 52 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to breakpoint plan", thread, eVoteNoOpinion, eVoteNoOpinion), 53 m_stop_others (stop_others), 54 m_address (address), 55 m_break_id (LLDB_INVALID_BREAK_ID) 56 { 57 SetInitialBreakpoint(); 58 } 59 60 void 61 ThreadPlanRunToAddress::SetInitialBreakpoint () 62 { 63 Breakpoint *breakpoint; 64 breakpoint = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_address, true).get(); 65 if (breakpoint != NULL) 66 { 67 m_break_id = breakpoint->GetID(); 68 breakpoint->SetThreadID(m_thread.GetID()); 69 } 70 } 71 72 ThreadPlanRunToAddress::~ThreadPlanRunToAddress () 73 { 74 if (m_break_id != LLDB_INVALID_BREAK_ID) 75 { 76 m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_id); 77 } 78 } 79 80 void 81 ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level) 82 { 83 if (level == lldb::eDescriptionLevelBrief) 84 { 85 s->Printf ("run to address: "); 86 s->Address (m_address, sizeof (addr_t)); 87 } 88 else 89 { 90 s->Printf ("Run to address: "); 91 s->Address(m_address, sizeof (addr_t)); 92 s->Printf (" using breakpoint: %d - ", m_break_id); 93 Breakpoint *breakpoint = m_thread.GetProcess().GetTarget().GetBreakpointByID (m_break_id).get(); 94 if (breakpoint) 95 breakpoint->Dump (s); 96 else 97 s->Printf ("but the breakpoint has been deleted."); 98 } 99 } 100 101 bool 102 ThreadPlanRunToAddress::ValidatePlan (Stream *error) 103 { 104 // If we couldn't set the breakpoint for some reason, then this won't 105 // work. 106 if(m_break_id == LLDB_INVALID_BREAK_ID) 107 return false; 108 else 109 return true; 110 } 111 112 bool 113 ThreadPlanRunToAddress::PlanExplainsStop () 114 { 115 return AtOurAddress(); 116 } 117 118 bool 119 ThreadPlanRunToAddress::ShouldStop (Event *event_ptr) 120 { 121 return false; 122 } 123 124 bool 125 ThreadPlanRunToAddress::StopOthers () 126 { 127 return m_stop_others; 128 } 129 130 void 131 ThreadPlanRunToAddress::SetStopOthers (bool new_value) 132 { 133 m_stop_others = new_value; 134 } 135 136 StateType 137 ThreadPlanRunToAddress::RunState () 138 { 139 return eStateRunning; 140 } 141 142 bool 143 ThreadPlanRunToAddress::WillStop () 144 { 145 return true; 146 } 147 148 bool 149 ThreadPlanRunToAddress::MischiefManaged () 150 { 151 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 152 153 if (AtOurAddress()) 154 { 155 // Remove the breakpoint 156 if (m_break_id != LLDB_INVALID_BREAK_ID) 157 { 158 m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_id); 159 m_break_id = LLDB_INVALID_BREAK_ID; 160 } 161 162 if (log) 163 log->Printf("Completed run to address plan."); 164 ThreadPlan::MischiefManaged (); 165 return true; 166 } 167 else 168 return false; 169 } 170 171 bool 172 ThreadPlanRunToAddress::AtOurAddress () 173 { 174 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC(); 175 return m_address == current_address; 176 } 177