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"
14#include "lldb/Utility/Log.h"
15
16using namespace lldb;
17using namespace lldb_private;
18
19// ThreadPlanShouldStopHere constructor
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 =
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) {
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
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}
#define LLDB_LOGF(log,...)
Definition: Log.h:366
A section + offset based address range class.
Definition: AddressRange.h:25
bool ContainsFileAddress(const Address &so_addr) const
Check if a section offset address is contained in this range.
A section + offset based address class.
Definition: Address.h:62
bool Slide(int64_t offset)
Definition: Address.h:459
A class to manage flags.
Definition: Flags.h:22
bool Test(ValueType bit) const
Test a single flag bit.
Definition: Flags.h:96
This base class provides an interface to stack frames.
Definition: StackFrame.h:43
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
Definition: StackFrame.cpp:300
bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
An error handling class.
Definition: Status.h:44
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:34
Symbol * symbol
The Symbol for a given query.
LineEntry line_entry
The LineEntry for a given query.
bool ValueIsAddress() const
Definition: Symbol.cpp:165
lldb::addr_t GetByteSize() const
Definition: Symbol.cpp:468
Address GetAddress() const
Definition: Symbol.h:88
virtual lldb::ThreadPlanSP QueueStepOutFromHerePlan(Flags &flags, lldb::FrameComparison operation, Status &status)
ThreadPlanShouldStopHereCallbacks m_callbacks
void SetShouldStopHereCallbacks(const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton)
static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, Status &status, void *baton)
static lldb::ThreadPlanSP DefaultStepFromHereCallback(ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, Status &status, void *baton)
bool InvokeShouldStopHereCallback(lldb::FrameComparison operation, Status &status)
lldb::ThreadPlanSP CheckShouldStopHereAndQueueStepOut(lldb::FrameComparison operation, Status &status)
Thread & GetThread()
Returns the Thread that is using this thread plan.
Definition: ThreadPlan.cpp:42
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:408
virtual lldb::RegisterContextSP GetRegisterContext()=0
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:1291
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:1334
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:331
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
Definition: lldb-forward.h:449
FrameComparison
This is the return value for frame comparisons.
@ eFrameCompareSameParent
@ eFrameCompareOlder
@ eFrameCompareYounger
uint64_t addr_t
Definition: lldb-types.h:80
@ eOnlyDuringStepping
AddressRange range
The section offset address range for this line entry.
Definition: LineEntry.h:137
uint32_t line
The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line number information.
Definition: LineEntry.h:147