LLDB  mainline
ThreadPlanStepOverBreakpoint.cpp
Go to the documentation of this file.
1 //===-- ThreadPlanStepOverBreakpoint.cpp ----------------------------------===//
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 
11 #include "lldb/Target/Process.h"
13 #include "lldb/Utility/LLDBLog.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 // ThreadPlanStepOverBreakpoint: Single steps over a breakpoint bp_site_sp at
21 // the pc.
22 
23 ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint(Thread &thread)
24  : ThreadPlan(
25  ThreadPlan::eKindStepOverBreakpoint, "Step over breakpoint trap",
26  thread, eVoteNo,
27  eVoteNoOpinion), // We need to report the run since this happens
28  // first in the thread plan stack when stepping over
29  // a breakpoint
30  m_breakpoint_addr(LLDB_INVALID_ADDRESS),
31  m_auto_continue(false), m_reenabled_breakpoint_site(false)
32 
33 {
34  m_breakpoint_addr = thread.GetRegisterContext()->GetPC();
36  thread.GetProcess()->GetBreakpointSiteList().FindIDByAddress(
38 }
39 
41 
43  Stream *s, lldb::DescriptionLevel level) {
44  s->Printf("Single stepping past breakpoint site %" PRIu64 " at 0x%" PRIx64,
46 }
47 
49 
51  StopInfoSP stop_info_sp = GetPrivateStopInfo();
52  if (stop_info_sp) {
53  StopReason reason = stop_info_sp->GetStopReason();
54 
55  Log *log = GetLog(LLDBLog::Step);
56  LLDB_LOG(log, "Step over breakpoint stopped for reason: {0}.",
58 
59  switch (reason) {
60  case eStopReasonTrace:
61  case eStopReasonNone:
62  return true;
64  {
65  // It's a little surprising that we stop here for a breakpoint hit.
66  // However, when you single step ONTO a breakpoint we still want to call
67  // that a breakpoint hit, and trigger the actions, etc. Otherwise you
68  // would see the PC at the breakpoint without having triggered the
69  // actions, then you'd continue, the PC wouldn't change, and you'd see
70  // the breakpoint hit, which would be odd. So the lower levels fake
71  // "step onto breakpoint address" and return that as a breakpoint hit.
72  // So our trace step COULD appear as a breakpoint hit if the next
73  // instruction also contained a breakpoint. We don't want to handle
74  // that, since we really don't know what to do with breakpoint hits.
75  // But make sure we don't set ourselves to auto-continue or we'll wrench
76  // control away from the plans that can deal with this.
77  // Be careful, however, as we may have "seen a breakpoint under the PC
78  // because we stopped without changing the PC, in which case we do want
79  // to re-claim this stop so we'll try again.
80  lldb::addr_t pc_addr = GetThread().GetRegisterContext()->GetPC();
81 
82  if (pc_addr == m_breakpoint_addr) {
83  LLDB_LOGF(log,
84  "Got breakpoint stop reason but pc: 0x%" PRIx64
85  "hasn't changed.",
86  pc_addr);
87  return true;
88  }
89 
90  SetAutoContinue(false);
91  return false;
92  }
93  default:
94  return false;
95  }
96  }
97  return false;
98 }
99 
101  return !ShouldAutoContinue(event_ptr);
102 }
103 
105 
107  return eStateStepping;
108 }
109 
111  bool current_plan) {
112  if (current_plan) {
113  BreakpointSiteSP bp_site_sp(
115  if (bp_site_sp && bp_site_sp->IsEnabled()) {
116  m_process.DisableBreakpointSite(bp_site_sp.get());
118  }
119  }
120  return true;
121 }
122 
125  return true;
126 }
127 
129 
131  lldb::addr_t pc_addr = GetThread().GetRegisterContext()->GetPC();
132 
133  if (pc_addr == m_breakpoint_addr) {
134  // If we are still at the PC of our breakpoint, then for some reason we
135  // didn't get a chance to run.
136  return false;
137  } else {
138  Log *log = GetLog(LLDBLog::Step);
139  LLDB_LOGF(log, "Completed step over breakpoint plan.");
140  // Otherwise, re-enable the breakpoint we were stepping over, and we're
141  // done.
144  return true;
145  }
146 }
147 
151  BreakpointSiteSP bp_site_sp(
153  if (bp_site_sp) {
154  m_process.EnableBreakpointSite(bp_site_sp.get());
155  }
156  }
157 }
160 }
161 
163  m_auto_continue = do_it;
164 }
165 
167  return m_auto_continue;
168 }
169 
171  return GetThread().GetRegisterContext()->GetPC() != m_breakpoint_addr;
172 }
lldb_private::ThreadPlan::GetThread
Thread & GetThread()
Returns the Thread that is using this thread plan.
Definition: ThreadPlan.cpp:42
lldb_private::ThreadPlanStepOverBreakpoint::ReenableBreakpointSite
void ReenableBreakpointSite()
Definition: ThreadPlanStepOverBreakpoint.cpp:148
lldb_private::Event
Definition: Event.h:182
lldb_private::ThreadPlanStepOverBreakpoint::m_auto_continue
bool m_auto_continue
Definition: ThreadPlanStepOverBreakpoint.h:47
lldb_private::ThreadPlanStepOverBreakpoint::ThreadDestroyed
void ThreadDestroyed() override
Definition: ThreadPlanStepOverBreakpoint.cpp:158
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:343
lldb_private::Process::GetBreakpointSiteList
BreakpointSiteList & GetBreakpointSiteList()
Definition: Process.cpp:1561
lldb_private::ThreadPlanStepOverBreakpoint::IsPlanStale
bool IsPlanStale() override
Definition: ThreadPlanStepOverBreakpoint.cpp:170
lldb::StopReason
StopReason
Thread stop reasons.
Definition: lldb-enumerations.h:239
lldb_private::ThreadPlanStepOverBreakpoint::GetDescription
void GetDescription(Stream *s, lldb::DescriptionLevel level) override
Print a description of this thread to the stream s.
Definition: ThreadPlanStepOverBreakpoint.cpp:42
lldb_private::eVoteNoOpinion
@ eVoteNoOpinion
Definition: lldb-private-enumerations.h:59
lldb_private::Stream
Definition: Stream.h:28
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb::eStopReasonTrace
@ eStopReasonTrace
Definition: lldb-enumerations.h:242
Process.h
lldb_private::ThreadPlanStepOverBreakpoint::StopOthers
bool StopOthers() override
Definition: ThreadPlanStepOverBreakpoint.cpp:104
lldb_private::Thread::GetProcess
lldb::ProcessSP GetProcess() const
Definition: Thread.h:153
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::ThreadPlan
Definition: ThreadPlan.h:287
lldb_private::BreakpointSiteList::FindByAddress
lldb::BreakpointSiteSP FindByAddress(lldb::addr_t addr)
Returns a shared pointer to the breakpoint site at address addr.
Definition: BreakpointSiteList.cpp:132
lldb_private::eVoteNo
@ eVoteNo
Definition: lldb-private-enumerations.h:59
Log.h
lldb_private::ThreadPlan::MischiefManaged
virtual bool MischiefManaged()
Definition: ThreadPlan.cpp:72
lldb_private::Thread
Definition: Thread.h:61
lldb::eStopReasonNone
@ eStopReasonNone
Definition: lldb-enumerations.h:241
lldb_private::ThreadPlanStepOverBreakpoint::ShouldAutoContinue
bool ShouldAutoContinue(Event *event_ptr) override
Returns whether this thread plan overrides the ShouldStop of subsequently processed plans.
Definition: ThreadPlanStepOverBreakpoint.cpp:166
lldb_private::ThreadPlanStepOverBreakpoint::m_breakpoint_site_id
lldb::user_id_t m_breakpoint_site_id
Definition: ThreadPlanStepOverBreakpoint.h:46
lldb_private::ThreadPlanStepOverBreakpoint::DoWillResume
bool DoWillResume(lldb::StateType resume_state, bool current_plan) override
Definition: ThreadPlanStepOverBreakpoint.cpp:110
ThreadPlanStepOverBreakpoint.h
lldb_private::ThreadPlanStepOverBreakpoint::ValidatePlan
bool ValidatePlan(Stream *error) override
Returns whether this plan could be successfully created.
Definition: ThreadPlanStepOverBreakpoint.cpp:48
lldb_private::LLDBLog::Step
@ Step
lldb_private::ThreadPlanStepOverBreakpoint::m_breakpoint_addr
lldb::addr_t m_breakpoint_addr
Definition: ThreadPlanStepOverBreakpoint.h:45
lldb::eStateStepping
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
Definition: lldb-enumerations.h:86
lldb_private::ThreadPlanStepOverBreakpoint::DidPop
void DidPop() override
Definition: ThreadPlanStepOverBreakpoint.cpp:128
lldb_private::ThreadPlanStepOverBreakpoint::ShouldStop
bool ShouldStop(Event *event_ptr) override
Definition: ThreadPlanStepOverBreakpoint.cpp:100
lldb_private::ThreadPlanStepOverBreakpoint::GetPlanRunState
lldb::StateType GetPlanRunState() override
Definition: ThreadPlanStepOverBreakpoint.cpp:106
lldb_private::ThreadPlanStepOverBreakpoint::WillStop
bool WillStop() override
Definition: ThreadPlanStepOverBreakpoint.cpp:123
lldb_private::ThreadPlanStepOverBreakpoint::SetAutoContinue
void SetAutoContinue(bool do_it)
Definition: ThreadPlanStepOverBreakpoint.cpp:162
lldb_private::ThreadPlanStepOverBreakpoint::MischiefManaged
bool MischiefManaged() override
Definition: ThreadPlanStepOverBreakpoint.cpp:130
lldb_private::ThreadPlanStepOverBreakpoint::DoPlanExplainsStop
bool DoPlanExplainsStop(Event *event_ptr) override
Definition: ThreadPlanStepOverBreakpoint.cpp:50
lldb::eStopReasonBreakpoint
@ eStopReasonBreakpoint
Definition: lldb-enumerations.h:243
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
LLDB_LOG
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:336
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::ThreadPlanStepOverBreakpoint::m_reenabled_breakpoint_site
bool m_reenabled_breakpoint_site
Definition: ThreadPlanStepOverBreakpoint.h:48
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::Process::EnableBreakpointSite
virtual Status EnableBreakpointSite(BreakpointSite *bp_site)
Definition: Process.h:2006
lldb::StateType
StateType
Process and Thread States.
Definition: lldb-enumerations.h:73
Stream.h
lldb_private::Thread::StopReasonAsString
static std::string StopReasonAsString(lldb::StopReason reason)
Definition: Thread.cpp:1657
lldb_private::Log
Definition: Log.h:115
lldb_private::ThreadPlan::GetPrivateStopInfo
lldb::StopInfoSP GetPrivateStopInfo()
Definition: ThreadPlan.h:515
lldb_private::Thread::GetRegisterContext
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:308
lldb_private::ThreadPlan::m_process
Process & m_process
Definition: ThreadPlan.h:528
lldb
Definition: SBAddress.h:15
RegisterContext.h
LLDBLog.h
lldb::DescriptionLevel
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
Definition: lldb-enumerations.h:207
lldb_private::ThreadPlanStepOverBreakpoint::~ThreadPlanStepOverBreakpoint
~ThreadPlanStepOverBreakpoint() override
lldb_private::Process::DisableBreakpointSite
virtual Status DisableBreakpointSite(BreakpointSite *bp_site)
Definition: Process.h:2013