LLDB  mainline
ThreadPlanRunToAddress.cpp
Go to the documentation of this file.
1 //===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "lldb/Target/Process.h"
12 #include "lldb/Target/Target.h"
13 #include "lldb/Target/Thread.h"
14 #include "lldb/Utility/Log.h"
15 #include "lldb/Utility/Stream.h"
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 // ThreadPlanRunToAddress: Continue plan
21 
22 ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, Address &address,
23  bool stop_others)
24  : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
26  m_stop_others(stop_others), m_addresses(), m_break_ids() {
27  m_addresses.push_back(
30 }
31 
33  lldb::addr_t address,
34  bool stop_others)
35  : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
37  m_stop_others(stop_others), m_addresses(), m_break_ids() {
38  m_addresses.push_back(
39  m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
41 }
42 
44  Thread &thread, const std::vector<lldb::addr_t> &addresses,
45  bool stop_others)
46  : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
48  m_stop_others(stop_others), m_addresses(addresses), m_break_ids() {
49  // Convert all addresses into opcode addresses to make sure we set
50  // breakpoints at the correct address.
51  Target &target = thread.GetProcess()->GetTarget();
52  std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
53  for (pos = m_addresses.begin(); pos != end; ++pos)
54  *pos = target.GetOpcodeLoadAddress(*pos);
55 
57 }
58 
60  size_t num_addresses = m_addresses.size();
61  m_break_ids.resize(num_addresses);
62 
63  for (size_t i = 0; i < num_addresses; i++) {
64  Breakpoint *breakpoint;
65  breakpoint = m_thread.CalculateTarget()
66  ->CreateBreakpoint(m_addresses[i], true, false)
67  .get();
68  if (breakpoint != nullptr) {
69  if (breakpoint->IsHardware() && !breakpoint->HasResolvedLocations())
71  m_break_ids[i] = breakpoint->GetID();
72  breakpoint->SetThreadID(m_thread.GetID());
73  breakpoint->SetBreakpointKind("run-to-address");
74  }
75  }
76 }
77 
79  size_t num_break_ids = m_break_ids.size();
80  for (size_t i = 0; i < num_break_ids; i++) {
81  m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]);
82  }
84 }
85 
87  lldb::DescriptionLevel level) {
88  size_t num_addresses = m_addresses.size();
89 
90  if (level == lldb::eDescriptionLevelBrief) {
91  if (num_addresses == 0) {
92  s->Printf("run to address with no addresses given.");
93  return;
94  } else if (num_addresses == 1)
95  s->Printf("run to address: ");
96  else
97  s->Printf("run to addresses: ");
98 
99  for (size_t i = 0; i < num_addresses; i++) {
100  s->Address(m_addresses[i], sizeof(addr_t));
101  s->Printf(" ");
102  }
103  } else {
104  if (num_addresses == 0) {
105  s->Printf("run to address with no addresses given.");
106  return;
107  } else if (num_addresses == 1)
108  s->Printf("Run to address: ");
109  else {
110  s->Printf("Run to addresses: ");
111  }
112 
113  for (size_t i = 0; i < num_addresses; i++) {
114  if (num_addresses > 1) {
115  s->Printf("\n");
116  s->Indent();
117  }
118 
119  s->Address(m_addresses[i], sizeof(addr_t));
120  s->Printf(" using breakpoint: %d - ", m_break_ids[i]);
121  Breakpoint *breakpoint =
122  m_thread.CalculateTarget()->GetBreakpointByID(m_break_ids[i]).get();
123  if (breakpoint)
124  breakpoint->Dump(s);
125  else
126  s->Printf("but the breakpoint has been deleted.");
127  }
128  }
129 }
130 
133  if (error)
134  error->Printf("Could not set hardware breakpoint(s)");
135  return false;
136  }
137 
138  // If we couldn't set the breakpoint for some reason, then this won't work.
139  bool all_bps_good = true;
140  size_t num_break_ids = m_break_ids.size();
141  for (size_t i = 0; i < num_break_ids; i++) {
142  if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) {
143  all_bps_good = false;
144  if (error) {
145  error->Printf("Could not set breakpoint for address: ");
146  error->Address(m_addresses[i], sizeof(addr_t));
147  error->Printf("\n");
148  }
149  }
150  }
151  return all_bps_good;
152 }
153 
155  return AtOurAddress();
156 }
157 
159  return AtOurAddress();
160 }
161 
162 bool ThreadPlanRunToAddress::StopOthers() { return m_stop_others; }
163 
165  m_stop_others = new_value;
166 }
167 
169 
170 bool ThreadPlanRunToAddress::WillStop() { return true; }
171 
174 
175  if (AtOurAddress()) {
176  // Remove the breakpoint
177  size_t num_break_ids = m_break_ids.size();
178 
179  for (size_t i = 0; i < num_break_ids; i++) {
180  if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) {
181  m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]);
182  m_break_ids[i] = LLDB_INVALID_BREAK_ID;
183  }
184  }
185  if (log)
186  log->Printf("Completed run to address plan.");
188  return true;
189  } else
190  return false;
191 }
192 
194  lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
195  bool found_it = false;
196  size_t num_addresses = m_addresses.size();
197  for (size_t i = 0; i < num_addresses; i++) {
198  if (m_addresses[i] == current_address) {
199  found_it = true;
200  break;
201  }
202  }
203  return found_it;
204 }
void Address(uint64_t addr, uint32_t addr_size, const char *prefix=nullptr, const char *suffix=nullptr)
Output an address value to this stream.
Definition: Stream.cpp:79
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
General Outline: A breakpoint has four main parts, a filter, a resolver, the list of breakpoint locat...
Definition: Breakpoint.h:78
void SetStopOthers(bool new_value) override
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:49
void SetBreakpointKind(const char *kind)
Set the "kind" description for a breakpoint.
Definition: Breakpoint.h:456
bool ValidatePlan(Stream *error) override
Returns whether this plan could be successfully created.
bool DoPlanExplainsStop(Event *event_ptr) override
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
lldb::TargetSP CalculateTarget() override
Definition: Thread.cpp:1584
lldb::break_id_t GetID() const
Definition: Stoppoint.cpp:22
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb::addr_t GetOpcodeLoadAddress(Target *target, AddressClass addr_class=AddressClass::eInvalid) const
Get the load address as an opcode load address.
Definition: Address.cpp:349
virtual bool MischiefManaged()
Definition: ThreadPlan.cpp:57
lldb::addr_t GetOpcodeLoadAddress(lldb::addr_t load_addr, AddressClass addr_class=AddressClass::eInvalid) const
Get load_addr as an opcode for this target.
Definition: Target.cpp:2469
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
bool IsHardware() const
Definition: Breakpoint.h:524
A section + offset based address class.
Definition: Address.h:80
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
bool HasResolvedLocations() const
Return whether this breakpoint has any resolved locations.
Definition: Breakpoint.cpp:849
bool ShouldStop(Event *event_ptr) override
uint64_t addr_t
Definition: lldb-types.h:83
Definition: SBAddress.h:15
void Dump(Stream *s) override
Standard "Dump" method. At present it does nothing.
Definition: Breakpoint.cpp:841
size_t Indent(const char *s=nullptr)
Indent the current line in the stream.
Definition: Stream.cpp:131
void SetThreadID(lldb::tid_t thread_id)
Set the valid thread to be checked when the breakpoint is hit.
Definition: Breakpoint.cpp:349
#define LLDB_INVALID_BREAK_ID
Definition: lldb-defines.h:49
void GetDescription(Stream *s, lldb::DescriptionLevel level) override
Print a description of this thread to the stream s.
ThreadPlanRunToAddress(Thread &thread, Address &address, bool stop_others)
#define LIBLLDB_LOG_STEP
Definition: Logging.h:21
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
Process or thread is running and can&#39;t be examined.