003 File Manager
Current Path:
/usr/src/contrib/llvm-project/lldb/source/Target
usr
/
src
/
contrib
/
llvm-project
/
lldb
/
source
/
Target
/
📁
..
📄
ABI.cpp
(9.36 KB)
📄
AssertFrameRecognizer.cpp
(5.4 KB)
📄
ExecutionContext.cpp
(18.19 KB)
📄
InstrumentationRuntime.cpp
(2.38 KB)
📄
InstrumentationRuntimeStopInfo.cpp
(1.2 KB)
📄
JITLoader.cpp
(1.07 KB)
📄
JITLoaderList.cpp
(1.94 KB)
📄
Language.cpp
(12.97 KB)
📄
LanguageRuntime.cpp
(9.71 KB)
📄
Memory.cpp
(15.12 KB)
📄
MemoryHistory.cpp
(943 B)
📄
MemoryRegionInfo.cpp
(1.55 KB)
📄
ModuleCache.cpp
(11.87 KB)
📄
OperatingSystem.cpp
(1.74 KB)
📄
PathMappingList.cpp
(9.73 KB)
📄
Platform.cpp
(66.82 KB)
📄
Process.cpp
(221.69 KB)
📄
Queue.cpp
(2.52 KB)
📄
QueueItem.cpp
(3 KB)
📄
QueueList.cpp
(1.68 KB)
📄
RegisterContext.cpp
(15.76 KB)
📄
RegisterContextUnwind.cpp
(86.86 KB)
📄
RegisterNumber.cpp
(3.34 KB)
📄
RemoteAwarePlatform.cpp
(16.06 KB)
📄
SectionLoadHistory.cpp
(6.39 KB)
📄
SectionLoadList.cpp
(9.57 KB)
📄
StackFrame.cpp
(70.8 KB)
📄
StackFrameList.cpp
(34.82 KB)
📄
StackFrameRecognizer.cpp
(7.27 KB)
📄
StackID.cpp
(3.39 KB)
📄
StopInfo.cpp
(44.17 KB)
📄
StructuredDataPlugin.cpp
(2.35 KB)
📄
SystemRuntime.cpp
(1.54 KB)
📄
Target.cpp
(146.79 KB)
📄
TargetList.cpp
(22.59 KB)
📄
TargetProperties.td
(15.71 KB)
📄
Thread.cpp
(70.22 KB)
📄
ThreadCollection.cpp
(2.18 KB)
📄
ThreadList.cpp
(24.9 KB)
📄
ThreadPlan.cpp
(9.54 KB)
📄
ThreadPlanBase.cpp
(6.32 KB)
📄
ThreadPlanCallFunction.cpp
(16.54 KB)
📄
ThreadPlanCallFunctionUsingABI.cpp
(2.35 KB)
📄
ThreadPlanCallOnFunctionExit.cpp
(3.3 KB)
📄
ThreadPlanCallUserExpression.cpp
(3.77 KB)
📄
ThreadPlanPython.cpp
(5.94 KB)
📄
ThreadPlanRunToAddress.cpp
(6.53 KB)
📄
ThreadPlanShouldStopHere.cpp
(5.82 KB)
📄
ThreadPlanStack.cpp
(14.76 KB)
📄
ThreadPlanStepInRange.cpp
(18.45 KB)
📄
ThreadPlanStepInstruction.cpp
(8.78 KB)
📄
ThreadPlanStepOut.cpp
(18.25 KB)
📄
ThreadPlanStepOverBreakpoint.cpp
(6.63 KB)
📄
ThreadPlanStepOverRange.cpp
(16.61 KB)
📄
ThreadPlanStepRange.cpp
(18.23 KB)
📄
ThreadPlanStepThrough.cpp
(8.79 KB)
📄
ThreadPlanStepUntil.cpp
(11.14 KB)
📄
ThreadPlanTracer.cpp
(7.78 KB)
📄
ThreadSpec.cpp
(4.46 KB)
📄
UnixSignals.cpp
(11.04 KB)
📄
UnwindAssembly.cpp
(1.09 KB)
📄
UnwindLLDB.cpp
(19.02 KB)
Editing: ThreadPlanStepUntil.cpp
//===-- ThreadPlanStepUntil.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "lldb/Target/ThreadPlanStepUntil.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Symbol/SymbolContextScope.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; // ThreadPlanStepUntil: Run until we reach a given line number or step out of // the current frame ThreadPlanStepUntil::ThreadPlanStepUntil(Thread &thread, lldb::addr_t *address_list, size_t num_addresses, bool stop_others, uint32_t frame_idx) : ThreadPlan(ThreadPlan::eKindStepUntil, "Step until", thread, eVoteNoOpinion, eVoteNoOpinion), m_step_from_insn(LLDB_INVALID_ADDRESS), m_return_bp_id(LLDB_INVALID_BREAK_ID), m_return_addr(LLDB_INVALID_ADDRESS), m_stepped_out(false), m_should_stop(false), m_ran_analyze(false), m_explains_stop(false), m_until_points(), m_stop_others(stop_others) { // Stash away our "until" addresses: TargetSP target_sp(thread.CalculateTarget()); StackFrameSP frame_sp(thread.GetStackFrameAtIndex(frame_idx)); if (frame_sp) { m_step_from_insn = frame_sp->GetStackID().GetPC(); // Find the return address and set a breakpoint there: // FIXME - can we do this more securely if we know first_insn? StackFrameSP return_frame_sp(thread.GetStackFrameAtIndex(frame_idx + 1)); if (return_frame_sp) { // TODO: add inline functionality m_return_addr = return_frame_sp->GetStackID().GetPC(); Breakpoint *return_bp = target_sp->CreateBreakpoint(m_return_addr, true, false).get(); if (return_bp != nullptr) { if (return_bp->IsHardware() && !return_bp->HasResolvedLocations()) m_could_not_resolve_hw_bp = true; return_bp->SetThreadID(m_tid); m_return_bp_id = return_bp->GetID(); return_bp->SetBreakpointKind("until-return-backstop"); } } m_stack_id = frame_sp->GetStackID(); // Now set breakpoints on all our return addresses: for (size_t i = 0; i < num_addresses; i++) { Breakpoint *until_bp = target_sp->CreateBreakpoint(address_list[i], true, false).get(); if (until_bp != nullptr) { until_bp->SetThreadID(m_tid); m_until_points[address_list[i]] = until_bp->GetID(); until_bp->SetBreakpointKind("until-target"); } else { m_until_points[address_list[i]] = LLDB_INVALID_BREAK_ID; } } } } ThreadPlanStepUntil::~ThreadPlanStepUntil() { Clear(); } void ThreadPlanStepUntil::Clear() { Target &target = GetTarget(); if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { target.RemoveBreakpointByID(m_return_bp_id); m_return_bp_id = LLDB_INVALID_BREAK_ID; } until_collection::iterator pos, end = m_until_points.end(); for (pos = m_until_points.begin(); pos != end; pos++) { target.RemoveBreakpointByID((*pos).second); } m_until_points.clear(); m_could_not_resolve_hw_bp = false; } void ThreadPlanStepUntil::GetDescription(Stream *s, lldb::DescriptionLevel level) { if (level == lldb::eDescriptionLevelBrief) { s->Printf("step until"); if (m_stepped_out) s->Printf(" - stepped out"); } else { if (m_until_points.size() == 1) s->Printf("Stepping from address 0x%" PRIx64 " until we reach 0x%" PRIx64 " using breakpoint %d", (uint64_t)m_step_from_insn, (uint64_t)(*m_until_points.begin()).first, (*m_until_points.begin()).second); else { until_collection::iterator pos, end = m_until_points.end(); s->Printf("Stepping from address 0x%" PRIx64 " until we reach one of:", (uint64_t)m_step_from_insn); for (pos = m_until_points.begin(); pos != end; pos++) { s->Printf("\n\t0x%" PRIx64 " (bp: %d)", (uint64_t)(*pos).first, (*pos).second); } } s->Printf(" stepped out address is 0x%" PRIx64 ".", (uint64_t)m_return_addr); } } bool ThreadPlanStepUntil::ValidatePlan(Stream *error) { if (m_could_not_resolve_hw_bp) { if (error) error->PutCString( "Could not create hardware breakpoint for thread plan."); return false; } else if (m_return_bp_id == LLDB_INVALID_BREAK_ID) { if (error) error->PutCString("Could not create return breakpoint."); return false; } else { until_collection::iterator pos, end = m_until_points.end(); for (pos = m_until_points.begin(); pos != end; pos++) { if (!LLDB_BREAK_ID_IS_VALID((*pos).second)) return false; } return true; } } void ThreadPlanStepUntil::AnalyzeStop() { if (m_ran_analyze) return; StopInfoSP stop_info_sp = GetPrivateStopInfo(); m_should_stop = true; m_explains_stop = false; if (stop_info_sp) { StopReason reason = stop_info_sp->GetStopReason(); if (reason == eStopReasonBreakpoint) { // If this is OUR breakpoint, we're fine, otherwise we don't know why // this happened... BreakpointSiteSP this_site = m_process.GetBreakpointSiteList().FindByID(stop_info_sp->GetValue()); if (!this_site) { m_explains_stop = false; return; } if (this_site->IsBreakpointAtThisSite(m_return_bp_id)) { // If we are at our "step out" breakpoint, and the stack depth has // shrunk, then this is indeed our stop. If the stack depth has grown, // then we've hit our step out breakpoint recursively. If we are the // only breakpoint at that location, then we do explain the stop, and // we'll just continue. If there was another breakpoint here, then we // don't explain the stop, but we won't mark ourselves Completed, // because maybe that breakpoint will continue, and then we'll finish // the "until". bool done; StackID cur_frame_zero_id; done = (m_stack_id < cur_frame_zero_id); if (done) { m_stepped_out = true; SetPlanComplete(); } else m_should_stop = false; if (this_site->GetNumberOfOwners() == 1) m_explains_stop = true; else m_explains_stop = false; return; } else { // Check if we've hit one of our "until" breakpoints. until_collection::iterator pos, end = m_until_points.end(); for (pos = m_until_points.begin(); pos != end; pos++) { if (this_site->IsBreakpointAtThisSite((*pos).second)) { // If we're at the right stack depth, then we're done. Thread &thread = GetThread(); bool done; StackID frame_zero_id = thread.GetStackFrameAtIndex(0)->GetStackID(); if (frame_zero_id == m_stack_id) done = true; else if (frame_zero_id < m_stack_id) done = false; else { StackFrameSP older_frame_sp = thread.GetStackFrameAtIndex(1); // But if we can't even unwind one frame we should just get out // of here & stop... if (older_frame_sp) { const SymbolContext &older_context = older_frame_sp->GetSymbolContext(eSymbolContextEverything); SymbolContext stack_context; m_stack_id.GetSymbolContextScope()->CalculateSymbolContext( &stack_context); done = (older_context == stack_context); } else done = false; } if (done) SetPlanComplete(); else m_should_stop = false; // Otherwise we've hit this breakpoint recursively. If we're the // only breakpoint here, then we do explain the stop, and we'll // continue. If not then we should let higher plans handle this // stop. if (this_site->GetNumberOfOwners() == 1) m_explains_stop = true; else { m_should_stop = true; m_explains_stop = false; } return; } } } // If we get here we haven't hit any of our breakpoints, so let the // higher plans take care of the stop. m_explains_stop = false; return; } else if (IsUsuallyUnexplainedStopReason(reason)) { m_explains_stop = false; } else { m_explains_stop = true; } } } bool ThreadPlanStepUntil::DoPlanExplainsStop(Event *event_ptr) { // We don't explain signals or breakpoints (breakpoints that handle stepping // in or out will be handled by a child plan. AnalyzeStop(); return m_explains_stop; } bool ThreadPlanStepUntil::ShouldStop(Event *event_ptr) { // If we've told our self in ExplainsStop that we plan to continue, then do // so here. Otherwise, as long as this thread has stopped for a reason, we // will stop. StopInfoSP stop_info_sp = GetPrivateStopInfo(); if (!stop_info_sp || stop_info_sp->GetStopReason() == eStopReasonNone) return false; AnalyzeStop(); return m_should_stop; } bool ThreadPlanStepUntil::StopOthers() { return m_stop_others; } StateType ThreadPlanStepUntil::GetPlanRunState() { return eStateRunning; } bool ThreadPlanStepUntil::DoWillResume(StateType resume_state, bool current_plan) { if (current_plan) { Target &target = GetTarget(); Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get(); if (return_bp != nullptr) return_bp->SetEnabled(true); until_collection::iterator pos, end = m_until_points.end(); for (pos = m_until_points.begin(); pos != end; pos++) { Breakpoint *until_bp = target.GetBreakpointByID((*pos).second).get(); if (until_bp != nullptr) until_bp->SetEnabled(true); } } m_should_stop = true; m_ran_analyze = false; m_explains_stop = false; return true; } bool ThreadPlanStepUntil::WillStop() { Target &target = GetTarget(); Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get(); if (return_bp != nullptr) return_bp->SetEnabled(false); until_collection::iterator pos, end = m_until_points.end(); for (pos = m_until_points.begin(); pos != end; pos++) { Breakpoint *until_bp = target.GetBreakpointByID((*pos).second).get(); if (until_bp != nullptr) until_bp->SetEnabled(false); } return true; } bool ThreadPlanStepUntil::MischiefManaged() { // I'm letting "PlanExplainsStop" do all the work, and just reporting that // here. bool done = false; if (IsPlanComplete()) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); LLDB_LOGF(log, "Completed step until plan."); Clear(); done = true; } if (done) ThreadPlan::MischiefManaged(); return done; }
Upload File
Create Folder