LLDB  mainline
ThreadPlanShouldStopHere.cpp
Go to the documentation of this file.
1 //===-- ThreadPlanShouldStopHere.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 #include "lldb/Symbol/Symbol.h"
12 #include "lldb/Target/Thread.h"
13 #include "lldb/Utility/LLDBLog.h"
14 #include "lldb/Utility/Log.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 
19 // ThreadPlanShouldStopHere constructor
20 ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner)
21  : m_callbacks(), m_baton(nullptr), m_owner(owner),
22  m_flags(ThreadPlanShouldStopHere::eNone) {
27 }
28 
30  ThreadPlan *owner, const ThreadPlanShouldStopHereCallbacks *callbacks,
31  void *baton)
32  : m_callbacks(), m_baton(), m_owner(owner),
33  m_flags(ThreadPlanShouldStopHere::eNone) {
34  SetShouldStopHereCallbacks(callbacks, baton);
35 }
36 
38 
40  FrameComparison operation, Status &status) {
41  bool should_stop_here = true;
43  should_stop_here = m_callbacks.should_stop_here_callback(
44  m_owner, m_flags, operation, status, m_baton);
45  Log *log = GetLog(LLDBLog::Step);
46  if (log) {
47  lldb::addr_t current_addr =
48  m_owner->GetThread().GetRegisterContext()->GetPC(0);
49 
50  LLDB_LOGF(log, "ShouldStopHere callback returned %u from 0x%" PRIx64 ".",
51  should_stop_here, current_addr);
52  }
53  }
54 
55  return should_stop_here;
56 }
57 
59  ThreadPlan *current_plan, Flags &flags, FrameComparison operation,
60  Status &status, void *baton) {
61  bool should_stop_here = true;
62  StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
63  if (!frame)
64  return true;
65 
66  Log *log = GetLog(LLDBLog::Step);
67 
68  if ((operation == eFrameCompareOlder && flags.Test(eStepOutAvoidNoDebug)) ||
69  (operation == eFrameCompareYounger && flags.Test(eStepInAvoidNoDebug)) ||
70  (operation == eFrameCompareSameParent &&
71  flags.Test(eStepInAvoidNoDebug))) {
72  if (!frame->HasDebugInformation()) {
73  LLDB_LOGF(log, "Stepping out of frame with no debug info");
74 
75  should_stop_here = false;
76  }
77  }
78 
79  // Always avoid code with line number 0.
80  // FIXME: At present the ShouldStop and the StepFromHere calculate this
81  // independently. If this ever
82  // becomes expensive (this one isn't) we can try to have this set a state
83  // that the StepFromHere can use.
84  if (frame) {
85  SymbolContext sc;
86  sc = frame->GetSymbolContext(eSymbolContextLineEntry);
87  if (sc.line_entry.line == 0)
88  should_stop_here = false;
89  }
90 
91  return should_stop_here;
92 }
93 
95  ThreadPlan *current_plan, Flags &flags, FrameComparison operation,
96  Status &status, void *baton) {
97  const bool stop_others = false;
98  const size_t frame_index = 0;
99  ThreadPlanSP return_plan_sp;
100  // If we are stepping through code at line number 0, then we need to step
101  // over this range. Otherwise we will step out.
102  Log *log = GetLog(LLDBLog::Step);
103 
104  StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
105  if (!frame)
106  return return_plan_sp;
107  SymbolContext sc;
108  sc = frame->GetSymbolContext(eSymbolContextLineEntry | eSymbolContextSymbol);
109 
110  if (sc.line_entry.line == 0) {
111  AddressRange range = sc.line_entry.range;
112 
113  // If the whole function is marked line 0 just step out, that's easier &
114  // faster than continuing to step through it.
115  bool just_step_out = false;
116  if (sc.symbol && sc.symbol->ValueIsAddress()) {
117  Address symbol_end = sc.symbol->GetAddress();
118  symbol_end.Slide(sc.symbol->GetByteSize() - 1);
119  if (range.ContainsFileAddress(sc.symbol->GetAddress()) &&
120  range.ContainsFileAddress(symbol_end)) {
121  LLDB_LOGF(log, "Stopped in a function with only line 0 lines, just "
122  "stepping out.");
123  just_step_out = true;
124  }
125  }
126  if (!just_step_out) {
127  LLDB_LOGF(log, "ThreadPlanShouldStopHere::DefaultStepFromHereCallback "
128  "Queueing StepInRange plan to step through line 0 code.");
129 
130  return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepInRange(
131  false, range, sc, nullptr, eOnlyDuringStepping, status,
133  }
134  }
135 
136  if (!return_plan_sp)
137  return_plan_sp =
139  false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion,
140  frame_index, status, true);
141  return return_plan_sp;
142 }
143 
145  lldb_private::Flags &flags, lldb::FrameComparison operation,
146  Status &status) {
147  ThreadPlanSP return_plan_sp;
149  return_plan_sp = m_callbacks.step_from_here_callback(
150  m_owner, flags, operation, status, m_baton);
151  }
152  return return_plan_sp;
153 }
154 
156  lldb::FrameComparison operation, Status &status) {
157  if (!InvokeShouldStopHereCallback(operation, status))
158  return QueueStepOutFromHerePlan(m_flags, operation, status);
159  else
160  return ThreadPlanSP();
161 }
lldb_private::ThreadPlanShouldStopHere::eStepOutAvoidNoDebug
@ eStepOutAvoidNoDebug
Definition: ThreadPlanShouldStopHere.h:62
lldb_private::ThreadPlan::GetThread
Thread & GetThread()
Returns the Thread that is using this thread plan.
Definition: ThreadPlan.cpp:42
lldb::FrameComparison
FrameComparison
This is the return value for frame comparisons.
Definition: lldb-enumerations.h:878
lldb_private::Symbol::ValueIsAddress
bool ValueIsAddress() const
Definition: Symbol.cpp:117
lldb_private::ThreadPlanShouldStopHere::DefaultShouldStopHereCallback
static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, Status &status, void *baton)
Definition: ThreadPlanShouldStopHere.cpp:58
lldb_private::ThreadPlanShouldStopHere::m_flags
lldb_private::Flags m_flags
Definition: ThreadPlanShouldStopHere.h:130
lldb_private::Thread::QueueThreadPlanForStepOutNoShouldStop
virtual lldb::ThreadPlanSP QueueThreadPlanForStepOutNoShouldStop(bool abort_other_plans, SymbolContext *addr_context, bool first_insn, bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote, uint32_t frame_idx, Status &status, bool continue_to_next_branch=false)
Queue the plan used to step out of the function at the current PC of a thread.
Definition: Thread.cpp:1338
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:344
lldb_private::ThreadPlanShouldStopHere::m_owner
ThreadPlan * m_owner
Definition: ThreadPlanShouldStopHere.h:129
lldb_private::Flags
Definition: Flags.h:22
lldb_private::Flags::Test
bool Test(ValueType bit) const
Test a single flag bit.
Definition: Flags.h:96
lldb_private::eVoteNoOpinion
@ eVoteNoOpinion
Definition: lldb-private-enumerations.h:59
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb_private::StackFrame::HasDebugInformation
bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
Definition: StackFrame.cpp:1153
lldb_private::SymbolContext::symbol
Symbol * symbol
The Symbol for a given query.
Definition: SymbolContext.h:323
lldb_private::ThreadPlan
Definition: ThreadPlan.h:287
lldb_private::eVoteNo
@ eVoteNo
Definition: lldb-private-enumerations.h:59
Log.h
lldb_private::ThreadPlanShouldStopHere::eStepInAvoidNoDebug
@ eStepInAvoidNoDebug
Definition: ThreadPlanShouldStopHere.h:61
lldb::eFrameCompareSameParent
@ eFrameCompareSameParent
Definition: lldb-enumerations.h:882
lldb_private::AddressRange
Definition: AddressRange.h:25
lldb_private::Thread::QueueThreadPlanForStepInRange
virtual lldb::ThreadPlanSP QueueThreadPlanForStepInRange(bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, const char *step_in_target, lldb::RunMode stop_other_threads, Status &status, LazyBool step_in_avoids_code_without_debug_info=eLazyBoolCalculate, LazyBool step_out_avoids_code_without_debug_info=eLazyBoolCalculate)
Queues the plan used to step through an address range, stepping into functions.
Definition: Thread.cpp:1295
lldb_private::ThreadPlanShouldStopHere::QueueStepOutFromHerePlan
virtual lldb::ThreadPlanSP QueueStepOutFromHerePlan(Flags &flags, lldb::FrameComparison operation, Status &status)
Definition: ThreadPlanShouldStopHere.cpp:144
lldb::eFrameCompareYounger
@ eFrameCompareYounger
Definition: lldb-enumerations.h:883
lldb_private::ThreadPlanShouldStopHere
Definition: ThreadPlanShouldStopHere.h:34
Thread.h
lldb_private::ThreadPlanShouldStopHere::ThreadPlanShouldStopHere
ThreadPlanShouldStopHere(ThreadPlan *owner)
Definition: ThreadPlanShouldStopHere.cpp:20
lldb_private::LLDBLog::Step
@ Step
lldb_private::ThreadPlanShouldStopHere::ThreadPlanShouldStopHereCallbacks::should_stop_here_callback
ThreadPlanShouldStopHereCallback should_stop_here_callback
Definition: ThreadPlanShouldStopHere.h:54
lldb_private::ThreadPlanShouldStopHere::DefaultStepFromHereCallback
static lldb::ThreadPlanSP DefaultStepFromHereCallback(ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, Status &status, void *baton)
Definition: ThreadPlanShouldStopHere.cpp:94
lldb_private::LineEntry::line
uint32_t line
The source line number, or zero if there is no line number information.
Definition: LineEntry.h:143
lldb_private::AddressRange::ContainsFileAddress
bool ContainsFileAddress(const Address &so_addr) const
Check if a section offset address is contained in this range.
Definition: AddressRange.cpp:62
lldb_private::ThreadPlanShouldStopHere::~ThreadPlanShouldStopHere
virtual ~ThreadPlanShouldStopHere()
lldb_private::ThreadPlanShouldStopHere::ThreadPlanShouldStopHereCallbacks
Definition: ThreadPlanShouldStopHere.h:36
Symbol.h
lldb_private::Status
Definition: Status.h:44
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
lldb_private::Address
Definition: Address.h:59
lldb::eOnlyDuringStepping
@ eOnlyDuringStepping
Definition: lldb-enumerations.h:136
lldb_private::ThreadPlanShouldStopHere::ThreadPlanShouldStopHereCallbacks::step_from_here_callback
ThreadPlanStepFromHereCallback step_from_here_callback
Definition: ThreadPlanShouldStopHere.h:55
lldb_private::Symbol::GetByteSize
lldb::addr_t GetByteSize() const
Definition: Symbol.cpp:414
lldb_private::LineEntry::range
AddressRange range
The section offset address range for this line entry.
Definition: LineEntry.h:139
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::ThreadPlanShouldStopHere::m_baton
void * m_baton
Definition: ThreadPlanShouldStopHere.h:128
lldb_private::ThreadPlanShouldStopHere::InvokeShouldStopHereCallback
bool InvokeShouldStopHereCallback(lldb::FrameComparison operation, Status &status)
Definition: ThreadPlanShouldStopHere.cpp:39
lldb_private::eLazyBoolCalculate
@ eLazyBoolCalculate
Definition: lldb-private-enumerations.h:115
lldb_private::ThreadPlanShouldStopHere::SetShouldStopHereCallbacks
void SetShouldStopHereCallbacks(const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton)
Definition: ThreadPlanShouldStopHere.h:79
lldb_private::ThreadPlanShouldStopHere::m_callbacks
ThreadPlanShouldStopHereCallbacks m_callbacks
Definition: ThreadPlanShouldStopHere.h:127
lldb_private::Log
Definition: Log.h:115
lldb_private::Thread::GetStackFrameAtIndex
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:399
lldb_private::SymbolContext::line_entry
LineEntry line_entry
The LineEntry for a given query.
Definition: SymbolContext.h:322
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:309
lldb_private::StackFrame
Definition: StackFrame.h:40
lldb_private::Address::Slide
bool Slide(int64_t offset)
Definition: Address.h:449
lldb
Definition: SBAddress.h:15
RegisterContext.h
lldb_private::ThreadPlanShouldStopHere::CheckShouldStopHereAndQueueStepOut
lldb::ThreadPlanSP CheckShouldStopHereAndQueueStepOut(lldb::FrameComparison operation, Status &status)
Definition: ThreadPlanShouldStopHere.cpp:155
lldb_private::StackFrame::GetSymbolContext
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
Definition: StackFrame.cpp:300
LLDBLog.h
lldb::eFrameCompareOlder
@ eFrameCompareOlder
Definition: lldb-enumerations.h:884
ThreadPlanShouldStopHere.h
lldb_private::Symbol::GetAddress
Address GetAddress() const
Definition: Symbol.h:73