summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2017-04-02 17:24:58 +0000
committerdim <dim@FreeBSD.org>2017-04-02 17:24:58 +0000
commit60b571e49a90d38697b3aca23020d9da42fc7d7f (patch)
tree99351324c24d6cb146b6285b6caffa4d26fce188 /contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp
parentbea1b22c7a9bce1dfdd73e6e5b65bc4752215180 (diff)
downloadFreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.zip
FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.tar.gz
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release:
MFC r309142 (by emaste): Add WITH_LLD_AS_LD build knob If set it installs LLD as /usr/bin/ld. LLD (as of version 3.9) is not capable of linking the world and kernel, but can self-host and link many substantial applications. GNU ld continues to be used for the world and kernel build, regardless of how this knob is set. It is on by default for arm64, and off for all other CPU architectures. Sponsored by: The FreeBSD Foundation MFC r310840: Reapply 310775, now it also builds correctly if lldb is disabled: Move llvm-objdump from CLANG_EXTRAS to installed by default We currently install three tools from binutils 2.17.50: as, ld, and objdump. Work is underway to migrate to a permissively-licensed tool-chain, with one goal being the retirement of binutils 2.17.50. LLVM's llvm-objdump is intended to be compatible with GNU objdump although it is currently missing some options and may have formatting differences. Enable it by default for testing and further investigation. It may later be changed to install as /usr/bin/objdump, it becomes a fully viable replacement. Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D8879 MFC r312855 (by emaste): Rename LLD_AS_LD to LLD_IS_LD, for consistency with CLANG_IS_CC Reported by: Dan McGregor <dan.mcgregor usask.ca> MFC r313559 | glebius | 2017-02-10 18:34:48 +0100 (Fri, 10 Feb 2017) | 5 lines Don't check struct rtentry on FreeBSD, it is an internal kernel structure. On other systems it may be API structure for SIOCADDRT/SIOCDELRT. Reviewed by: emaste, dim MFC r314152 (by jkim): Remove an assembler flag, which is redundant since r309124. The upstream took care of it by introducing a macro NO_EXEC_STACK_DIRECTIVE. http://llvm.org/viewvc/llvm-project?rev=273500&view=rev Reviewed by: dim MFC r314564: Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 (branches/release_40 296509). The release will follow soon. Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11 support to build; see UPDATING for more information. Also note that as of 4.0.0, lld should be able to link the base system on amd64 and aarch64. See the WITH_LLD_IS_LLD setting in src.conf(5). Though please be aware that this is work in progress. Release notes for llvm, clang and lld will be available here: <http://releases.llvm.org/4.0.0/docs/ReleaseNotes.html> <http://releases.llvm.org/4.0.0/tools/clang/docs/ReleaseNotes.html> <http://releases.llvm.org/4.0.0/tools/lld/docs/ReleaseNotes.html> Thanks to Ed Maste, Jan Beich, Antoine Brodin and Eric Fiselier for their help. Relnotes: yes Exp-run: antoine PR: 215969, 216008 MFC r314708: For now, revert r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 This commit is the cause of excessive compile times on skein_block.c (and possibly other files) during kernel builds on amd64. We never saw the problematic behavior described in this upstream commit, so for now it is better to revert it. An upstream bug has been filed here: https://bugs.llvm.org/show_bug.cgi?id=32142 Reported by: mjg MFC r314795: Reapply r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 Pull in r296992 from upstream llvm trunk (by Sanjoy Das): [SCEV] Decrease the recursion threshold for CompareValueComplexity Fixes PR32142. r287232 accidentally increased the recursion threshold for CompareValueComplexity from 2 to 32. This change reverses that change by introducing a separate flag for CompareValueComplexity's threshold. The latter revision fixes the excessive compile times for skein_block.c. MFC r314907 | mmel | 2017-03-08 12:40:27 +0100 (Wed, 08 Mar 2017) | 7 lines Unbreak ARMv6 world. The new compiler_rt library imported with clang 4.0.0 have several fatal issues (non-functional __udivsi3 for example) with ARM specific instrict functions. As temporary workaround, until upstream solve these problems, disable all thumb[1][2] related feature. MFC r315016: Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release. We were already very close to the last release candidate, so this is a pretty minor update. Relnotes: yes MFC r316005: Revert r314907, and pull in r298713 from upstream compiler-rt trunk (by Weiming Zhao): builtins: Select correct code fragments when compiling for Thumb1/Thum2/ARM ISA. Summary: Value of __ARM_ARCH_ISA_THUMB isn't based on the actual compilation mode (-mthumb, -marm), it reflect's capability of given CPU. Due to this: - use __tbumb__ and __thumb2__ insteand of __ARM_ARCH_ISA_THUMB - use '.thumb' directive consistently in all affected files - decorate all thumb functions using DEFINE_COMPILERRT_THUMB_FUNCTION() --------- Note: This patch doesn't fix broken Thumb1 variant of __udivsi3 ! Reviewers: weimingz, rengolin, compnerd Subscribers: aemerson, dim Differential Revision: https://reviews.llvm.org/D30938 Discussed with: mmel
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp')
-rw-r--r--contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp893
1 files changed, 431 insertions, 462 deletions
diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp
index 3771e21..03f6679 100644
--- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp
+++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp
@@ -14,526 +14,495 @@
#include "lldb/Target/ThreadPlanStepInRange.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
-#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanStepOut.h"
#include "lldb/Target/ThreadPlanStepThrough.h"
-#include "lldb/Core/RegularExpression.h"
using namespace lldb;
using namespace lldb_private;
-uint32_t ThreadPlanStepInRange::s_default_flag_values = ThreadPlanShouldStopHere::eStepInAvoidNoDebug;
+uint32_t ThreadPlanStepInRange::s_default_flag_values =
+ ThreadPlanShouldStopHere::eStepInAvoidNoDebug;
//----------------------------------------------------------------------
-// ThreadPlanStepInRange: Step through a stack range, either stepping over or into
+// ThreadPlanStepInRange: Step through a stack range, either stepping over or
+// into
// based on the value of \a type.
//----------------------------------------------------------------------
-ThreadPlanStepInRange::ThreadPlanStepInRange
-(
- Thread &thread,
- const AddressRange &range,
- const SymbolContext &addr_context,
- lldb::RunMode stop_others,
+ThreadPlanStepInRange::ThreadPlanStepInRange(
+ Thread &thread, const AddressRange &range,
+ const SymbolContext &addr_context, lldb::RunMode stop_others,
LazyBool step_in_avoids_code_without_debug_info,
- LazyBool step_out_avoids_code_without_debug_info
-) :
- ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others),
- ThreadPlanShouldStopHere (this),
- m_step_past_prologue (true),
- m_virtual_step (false)
-{
- SetCallbacks();
- SetFlagsToDefault ();
- SetupAvoidNoDebug(step_in_avoids_code_without_debug_info, step_out_avoids_code_without_debug_info);
+ LazyBool step_out_avoids_code_without_debug_info)
+ : ThreadPlanStepRange(ThreadPlan::eKindStepInRange,
+ "Step Range stepping in", thread, range, addr_context,
+ stop_others),
+ ThreadPlanShouldStopHere(this), m_step_past_prologue(true),
+ m_virtual_step(false) {
+ SetCallbacks();
+ SetFlagsToDefault();
+ SetupAvoidNoDebug(step_in_avoids_code_without_debug_info,
+ step_out_avoids_code_without_debug_info);
}
-ThreadPlanStepInRange::ThreadPlanStepInRange
-(
- Thread &thread,
- const AddressRange &range,
- const SymbolContext &addr_context,
- const char *step_into_target,
- lldb::RunMode stop_others,
- LazyBool step_in_avoids_code_without_debug_info,
- LazyBool step_out_avoids_code_without_debug_info
-) :
- ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others),
- ThreadPlanShouldStopHere (this),
- m_step_past_prologue (true),
- m_virtual_step (false),
- m_step_into_target (step_into_target)
-{
- SetCallbacks();
- SetFlagsToDefault ();
- SetupAvoidNoDebug(step_in_avoids_code_without_debug_info, step_out_avoids_code_without_debug_info);
+ThreadPlanStepInRange::ThreadPlanStepInRange(
+ Thread &thread, const AddressRange &range,
+ const SymbolContext &addr_context, const char *step_into_target,
+ lldb::RunMode stop_others, LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info)
+ : ThreadPlanStepRange(ThreadPlan::eKindStepInRange,
+ "Step Range stepping in", thread, range, addr_context,
+ stop_others),
+ ThreadPlanShouldStopHere(this), m_step_past_prologue(true),
+ m_virtual_step(false), m_step_into_target(step_into_target) {
+ SetCallbacks();
+ SetFlagsToDefault();
+ SetupAvoidNoDebug(step_in_avoids_code_without_debug_info,
+ step_out_avoids_code_without_debug_info);
}
ThreadPlanStepInRange::~ThreadPlanStepInRange() = default;
-void
-ThreadPlanStepInRange::SetupAvoidNoDebug(LazyBool step_in_avoids_code_without_debug_info,
- LazyBool step_out_avoids_code_without_debug_info)
-{
- bool avoid_nodebug = true;
-
- switch (step_in_avoids_code_without_debug_info)
- {
- case eLazyBoolYes:
- avoid_nodebug = true;
- break;
- case eLazyBoolNo:
- avoid_nodebug = false;
- break;
- case eLazyBoolCalculate:
- avoid_nodebug = m_thread.GetStepInAvoidsNoDebug();
- break;
- }
- if (avoid_nodebug)
- GetFlags().Set (ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
- else
- GetFlags().Clear (ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
-
- switch (step_out_avoids_code_without_debug_info)
- {
- case eLazyBoolYes:
- avoid_nodebug = true;
- break;
- case eLazyBoolNo:
- avoid_nodebug = false;
- break;
- case eLazyBoolCalculate:
- avoid_nodebug = m_thread.GetStepOutAvoidsNoDebug();
- break;
- }
- if (avoid_nodebug)
- GetFlags().Set (ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
- else
- GetFlags().Clear (ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
+void ThreadPlanStepInRange::SetupAvoidNoDebug(
+ LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info) {
+ bool avoid_nodebug = true;
+
+ switch (step_in_avoids_code_without_debug_info) {
+ case eLazyBoolYes:
+ avoid_nodebug = true;
+ break;
+ case eLazyBoolNo:
+ avoid_nodebug = false;
+ break;
+ case eLazyBoolCalculate:
+ avoid_nodebug = m_thread.GetStepInAvoidsNoDebug();
+ break;
+ }
+ if (avoid_nodebug)
+ GetFlags().Set(ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
+ else
+ GetFlags().Clear(ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
+
+ switch (step_out_avoids_code_without_debug_info) {
+ case eLazyBoolYes:
+ avoid_nodebug = true;
+ break;
+ case eLazyBoolNo:
+ avoid_nodebug = false;
+ break;
+ case eLazyBoolCalculate:
+ avoid_nodebug = m_thread.GetStepOutAvoidsNoDebug();
+ break;
+ }
+ if (avoid_nodebug)
+ GetFlags().Set(ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
+ else
+ GetFlags().Clear(ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
}
-void
-ThreadPlanStepInRange::GetDescription (Stream *s, lldb::DescriptionLevel level)
-{
- if (level == lldb::eDescriptionLevelBrief)
- {
- s->Printf("step in");
- return;
- }
+void ThreadPlanStepInRange::GetDescription(Stream *s,
+ lldb::DescriptionLevel level) {
+ if (level == lldb::eDescriptionLevelBrief) {
+ s->Printf("step in");
+ return;
+ }
- s->Printf ("Stepping in");
- bool printed_line_info = false;
- if (m_addr_context.line_entry.IsValid())
- {
- s->Printf (" through line ");
- m_addr_context.line_entry.DumpStopContext (s, false);
- printed_line_info = true;
- }
+ s->Printf("Stepping in");
+ bool printed_line_info = false;
+ if (m_addr_context.line_entry.IsValid()) {
+ s->Printf(" through line ");
+ m_addr_context.line_entry.DumpStopContext(s, false);
+ printed_line_info = true;
+ }
- const char *step_into_target = m_step_into_target.AsCString();
- if (step_into_target && step_into_target[0] != '\0')
- s->Printf (" targeting %s", m_step_into_target.AsCString());
+ const char *step_into_target = m_step_into_target.AsCString();
+ if (step_into_target && step_into_target[0] != '\0')
+ s->Printf(" targeting %s", m_step_into_target.AsCString());
- if (!printed_line_info || level == eDescriptionLevelVerbose)
- {
- s->Printf (" using ranges:");
- DumpRanges(s);
- }
+ if (!printed_line_info || level == eDescriptionLevelVerbose) {
+ s->Printf(" using ranges:");
+ DumpRanges(s);
+ }
- s->PutChar('.');
+ s->PutChar('.');
}
-bool
-ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-
- if (log)
- {
- StreamString s;
- s.Address (m_thread.GetRegisterContext()->GetPC(),
- m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
- log->Printf("ThreadPlanStepInRange reached %s.", s.GetData());
- }
+bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (IsPlanComplete())
- return true;
-
- m_no_more_plans = false;
- if (m_sub_plan_sp && m_sub_plan_sp->IsPlanComplete())
- {
- if (!m_sub_plan_sp->PlanSucceeded())
- {
- SetPlanComplete();
- m_no_more_plans = true;
- return true;
- }
- else
- m_sub_plan_sp.reset();
+ if (log) {
+ StreamString s;
+ s.Address(
+ m_thread.GetRegisterContext()->GetPC(),
+ m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
+ log->Printf("ThreadPlanStepInRange reached %s.", s.GetData());
+ }
+
+ if (IsPlanComplete())
+ return true;
+
+ m_no_more_plans = false;
+ if (m_sub_plan_sp && m_sub_plan_sp->IsPlanComplete()) {
+ if (!m_sub_plan_sp->PlanSucceeded()) {
+ SetPlanComplete();
+ m_no_more_plans = true;
+ return true;
+ } else
+ m_sub_plan_sp.reset();
+ }
+
+ if (m_virtual_step) {
+ // If we've just completed a virtual step, all we need to do is check for a
+ // ShouldStopHere plan, and otherwise
+ // we're done.
+ // FIXME - This can be both a step in and a step out. Probably should
+ // record which in the m_virtual_step.
+ m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(eFrameCompareYounger);
+ } else {
+ // Stepping through should be done running other threads in general, since
+ // we're setting a breakpoint and
+ // continuing. So only stop others if we are explicitly told to do so.
+
+ bool stop_others = (m_stop_others == lldb::eOnlyThisThread);
+
+ FrameComparison frame_order = CompareCurrentFrameToStartFrame();
+
+ if (frame_order == eFrameCompareOlder ||
+ frame_order == eFrameCompareSameParent) {
+ // If we're in an older frame then we should stop.
+ //
+ // A caveat to this is if we think the frame is older but we're actually
+ // in a trampoline.
+ // I'm going to make the assumption that you wouldn't RETURN to a
+ // trampoline. So if we are
+ // in a trampoline we think the frame is older because the trampoline
+ // confused the backtracer.
+ m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false,
+ stop_others);
+ if (!m_sub_plan_sp) {
+ // Otherwise check the ShouldStopHere for step out:
+ m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order);
+ if (log)
+ log->Printf("ShouldStopHere says we should step out of this frame.");
+ } else if (log) {
+ log->Printf(
+ "Thought I stepped out, but in fact arrived at a trampoline.");
+ }
+ } else if (frame_order == eFrameCompareEqual && InSymbol()) {
+ // If we are not in a place we should step through, we're done.
+ // One tricky bit here is that some stubs don't push a frame, so we have
+ // to check
+ // both the case of a frame that is younger, or the same as this frame.
+ // However, if the frame is the same, and we are still in the symbol we
+ // started
+ // in, the we don't need to do this. This first check isn't strictly
+ // necessary,
+ // but it is more efficient.
+
+ // If we're still in the range, keep going, either by running to the next
+ // branch breakpoint, or by
+ // stepping.
+ if (InRange()) {
+ SetNextBranchBreakpoint();
+ return false;
+ }
+
+ SetPlanComplete();
+ m_no_more_plans = true;
+ return true;
}
-
- if (m_virtual_step)
- {
- // If we've just completed a virtual step, all we need to do is check for a ShouldStopHere plan, and otherwise
- // we're done.
- // FIXME - This can be both a step in and a step out. Probably should record which in the m_virtual_step.
- m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(eFrameCompareYounger);
+
+ // If we get to this point, we're not going to use a previously set "next
+ // branch" breakpoint, so delete it:
+ ClearNextBranchBreakpoint();
+
+ // We may have set the plan up above in the FrameIsOlder section:
+
+ if (!m_sub_plan_sp)
+ m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false,
+ stop_others);
+
+ if (log) {
+ if (m_sub_plan_sp)
+ log->Printf("Found a step through plan: %s", m_sub_plan_sp->GetName());
+ else
+ log->Printf("No step through plan found.");
}
- else
- {
- // Stepping through should be done running other threads in general, since we're setting a breakpoint and
- // continuing. So only stop others if we are explicitly told to do so.
-
- bool stop_others = (m_stop_others == lldb::eOnlyThisThread);
-
- FrameComparison frame_order = CompareCurrentFrameToStartFrame();
-
- if (frame_order == eFrameCompareOlder || frame_order == eFrameCompareSameParent)
- {
- // If we're in an older frame then we should stop.
- //
- // A caveat to this is if we think the frame is older but we're actually in a trampoline.
- // I'm going to make the assumption that you wouldn't RETURN to a trampoline. So if we are
- // in a trampoline we think the frame is older because the trampoline confused the backtracer.
- m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
- if (!m_sub_plan_sp)
- {
- // Otherwise check the ShouldStopHere for step out:
- m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order);
- if (log)
- log->Printf ("ShouldStopHere says we should step out of this frame.");
- }
- else if (log)
- {
- log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
- }
- }
- else if (frame_order == eFrameCompareEqual && InSymbol())
- {
- // If we are not in a place we should step through, we're done.
- // One tricky bit here is that some stubs don't push a frame, so we have to check
- // both the case of a frame that is younger, or the same as this frame.
- // However, if the frame is the same, and we are still in the symbol we started
- // in, the we don't need to do this. This first check isn't strictly necessary,
- // but it is more efficient.
-
- // If we're still in the range, keep going, either by running to the next branch breakpoint, or by
- // stepping.
- if (InRange())
- {
- SetNextBranchBreakpoint();
- return false;
- }
-
- SetPlanComplete();
- m_no_more_plans = true;
- return true;
- }
-
- // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
- ClearNextBranchBreakpoint();
-
- // We may have set the plan up above in the FrameIsOlder section:
-
- if (!m_sub_plan_sp)
- m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
-
- if (log)
- {
- if (m_sub_plan_sp)
- log->Printf ("Found a step through plan: %s", m_sub_plan_sp->GetName());
- else
- log->Printf ("No step through plan found.");
+
+ // If not, give the "should_stop" callback a chance to push a plan to get us
+ // out of here.
+ // But only do that if we actually have stepped in.
+ if (!m_sub_plan_sp && frame_order == eFrameCompareYounger)
+ m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order);
+
+ // If we've stepped in and we are going to stop here, check to see if we
+ // were asked to
+ // run past the prologue, and if so do that.
+
+ if (!m_sub_plan_sp && frame_order == eFrameCompareYounger &&
+ m_step_past_prologue) {
+ lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
+ if (curr_frame) {
+ size_t bytes_to_skip = 0;
+ lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
+ Address func_start_address;
+
+ SymbolContext sc = curr_frame->GetSymbolContext(eSymbolContextFunction |
+ eSymbolContextSymbol);
+
+ if (sc.function) {
+ func_start_address = sc.function->GetAddressRange().GetBaseAddress();
+ if (curr_addr ==
+ func_start_address.GetLoadAddress(
+ m_thread.CalculateTarget().get()))
+ bytes_to_skip = sc.function->GetPrologueByteSize();
+ } else if (sc.symbol) {
+ func_start_address = sc.symbol->GetAddress();
+ if (curr_addr ==
+ func_start_address.GetLoadAddress(
+ m_thread.CalculateTarget().get()))
+ bytes_to_skip = sc.symbol->GetPrologueByteSize();
}
-
- // If not, give the "should_stop" callback a chance to push a plan to get us out of here.
- // But only do that if we actually have stepped in.
- if (!m_sub_plan_sp && frame_order == eFrameCompareYounger)
- m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order);
-
- // If we've stepped in and we are going to stop here, check to see if we were asked to
- // run past the prologue, and if so do that.
-
- if (!m_sub_plan_sp && frame_order == eFrameCompareYounger && m_step_past_prologue)
- {
- lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
- if (curr_frame)
- {
- size_t bytes_to_skip = 0;
- lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
- Address func_start_address;
-
- SymbolContext sc = curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
-
- if (sc.function)
- {
- func_start_address = sc.function->GetAddressRange().GetBaseAddress();
- if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
- bytes_to_skip = sc.function->GetPrologueByteSize();
- }
- else if (sc.symbol)
- {
- func_start_address = sc.symbol->GetAddress();
- if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
- bytes_to_skip = sc.symbol->GetPrologueByteSize();
- }
-
- if (bytes_to_skip != 0)
- {
- func_start_address.Slide (bytes_to_skip);
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
- if (log)
- log->Printf ("Pushing past prologue ");
-
- m_sub_plan_sp = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
- }
- }
+
+ if (bytes_to_skip != 0) {
+ func_start_address.Slide(bytes_to_skip);
+ log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP);
+ if (log)
+ log->Printf("Pushing past prologue ");
+
+ m_sub_plan_sp = m_thread.QueueThreadPlanForRunToAddress(
+ false, func_start_address, true);
}
- }
-
- if (!m_sub_plan_sp)
- {
- m_no_more_plans = true;
- SetPlanComplete();
- return true;
- }
- else
- {
- m_no_more_plans = false;
- m_sub_plan_sp->SetPrivate(true);
- return false;
+ }
}
+ }
+
+ if (!m_sub_plan_sp) {
+ m_no_more_plans = true;
+ SetPlanComplete();
+ return true;
+ } else {
+ m_no_more_plans = false;
+ m_sub_plan_sp->SetPrivate(true);
+ return false;
+ }
}
-void
-ThreadPlanStepInRange::SetAvoidRegexp(const char *name)
-{
- if (!m_avoid_regexp_ap)
- m_avoid_regexp_ap.reset (new RegularExpression(name));
+void ThreadPlanStepInRange::SetAvoidRegexp(const char *name) {
+ auto name_ref = llvm::StringRef::withNullAsEmpty(name);
+ if (!m_avoid_regexp_ap)
+ m_avoid_regexp_ap.reset(new RegularExpression(name_ref));
- m_avoid_regexp_ap->Compile (name);
+ m_avoid_regexp_ap->Compile(name_ref);
}
-void
-ThreadPlanStepInRange::SetDefaultFlagValue (uint32_t new_value)
-{
- // TODO: Should we test this for sanity?
- ThreadPlanStepInRange::s_default_flag_values = new_value;
+void ThreadPlanStepInRange::SetDefaultFlagValue(uint32_t new_value) {
+ // TODO: Should we test this for sanity?
+ ThreadPlanStepInRange::s_default_flag_values = new_value;
}
-bool
-ThreadPlanStepInRange::FrameMatchesAvoidCriteria ()
-{
- StackFrame *frame = GetThread().GetStackFrameAtIndex(0).get();
-
- // Check the library list first, as that's cheapest:
- bool libraries_say_avoid = false;
-
- FileSpecList libraries_to_avoid (GetThread().GetLibrariesToAvoid());
- size_t num_libraries = libraries_to_avoid.GetSize();
- if (num_libraries > 0)
- {
- SymbolContext sc(frame->GetSymbolContext(eSymbolContextModule));
- FileSpec frame_library(sc.module_sp->GetFileSpec());
-
- if (frame_library)
- {
- for (size_t i = 0; i < num_libraries; i++)
- {
- const FileSpec &file_spec(libraries_to_avoid.GetFileSpecAtIndex(i));
- if (FileSpec::Equal (file_spec, frame_library, false))
- {
- libraries_say_avoid = true;
- break;
- }
- }
+bool ThreadPlanStepInRange::FrameMatchesAvoidCriteria() {
+ StackFrame *frame = GetThread().GetStackFrameAtIndex(0).get();
+
+ // Check the library list first, as that's cheapest:
+ bool libraries_say_avoid = false;
+
+ FileSpecList libraries_to_avoid(GetThread().GetLibrariesToAvoid());
+ size_t num_libraries = libraries_to_avoid.GetSize();
+ if (num_libraries > 0) {
+ SymbolContext sc(frame->GetSymbolContext(eSymbolContextModule));
+ FileSpec frame_library(sc.module_sp->GetFileSpec());
+
+ if (frame_library) {
+ for (size_t i = 0; i < num_libraries; i++) {
+ const FileSpec &file_spec(libraries_to_avoid.GetFileSpecAtIndex(i));
+ if (FileSpec::Equal(file_spec, frame_library, false)) {
+ libraries_say_avoid = true;
+ break;
}
+ }
}
- if (libraries_say_avoid)
- return true;
-
- const RegularExpression *avoid_regexp_to_use = m_avoid_regexp_ap.get();
- if (avoid_regexp_to_use == nullptr)
- avoid_regexp_to_use = GetThread().GetSymbolsToAvoidRegexp();
-
- if (avoid_regexp_to_use != nullptr)
- {
- SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock|eSymbolContextSymbol);
- if (sc.symbol != nullptr)
- {
- const char *frame_function_name = sc.GetFunctionName(Mangled::ePreferDemangledWithoutArguments).GetCString();
- if (frame_function_name)
- {
- size_t num_matches = 0;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log)
- num_matches = 1;
-
- RegularExpression::Match regex_match(num_matches);
-
- bool return_value = avoid_regexp_to_use->Execute(frame_function_name, &regex_match);
- if (return_value)
- {
- if (log)
- {
- std::string match;
- regex_match.GetMatchAtIndex(frame_function_name,0, match);
- log->Printf ("Stepping out of function \"%s\" because it matches the avoid regexp \"%s\" - match substring: \"%s\".",
- frame_function_name,
- avoid_regexp_to_use->GetText(),
- match.c_str());
- }
-
- }
- return return_value;
- }
+ }
+ if (libraries_say_avoid)
+ return true;
+
+ const RegularExpression *avoid_regexp_to_use = m_avoid_regexp_ap.get();
+ if (avoid_regexp_to_use == nullptr)
+ avoid_regexp_to_use = GetThread().GetSymbolsToAvoidRegexp();
+
+ if (avoid_regexp_to_use != nullptr) {
+ SymbolContext sc = frame->GetSymbolContext(
+ eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
+ if (sc.symbol != nullptr) {
+ const char *frame_function_name =
+ sc.GetFunctionName(Mangled::ePreferDemangledWithoutArguments)
+ .GetCString();
+ if (frame_function_name) {
+ size_t num_matches = 0;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log)
+ num_matches = 1;
+
+ RegularExpression::Match regex_match(num_matches);
+
+ bool return_value =
+ avoid_regexp_to_use->Execute(frame_function_name, &regex_match);
+ if (return_value) {
+ if (log) {
+ std::string match;
+ regex_match.GetMatchAtIndex(frame_function_name, 0, match);
+ log->Printf("Stepping out of function \"%s\" because it matches "
+ "the avoid regexp \"%s\" - match substring: \"%s\".",
+ frame_function_name,
+ avoid_regexp_to_use->GetText().str().c_str(),
+ match.c_str());
+ }
}
+ return return_value;
+ }
}
- return false;
+ }
+ return false;
}
-bool
-ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, FrameComparison operation, void *baton)
-{
- bool should_stop_here = true;
- StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-
- // First see if the ThreadPlanShouldStopHere default implementation thinks we should get out of here:
- should_stop_here = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback (current_plan, flags, operation, baton);
- if (!should_stop_here)
- return should_stop_here;
-
- if (should_stop_here && current_plan->GetKind() == eKindStepInRange && operation == eFrameCompareYounger)
- {
- ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
- if (step_in_range_plan->m_step_into_target)
- {
- SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock|eSymbolContextSymbol);
- if (sc.symbol != nullptr)
- {
- // First try an exact match, since that's cheap with ConstStrings. Then do a strstr compare.
- if (step_in_range_plan->m_step_into_target == sc.GetFunctionName())
- {
- should_stop_here = true;
- }
- else
- {
- const char *target_name = step_in_range_plan->m_step_into_target.AsCString();
- const char *function_name = sc.GetFunctionName().AsCString();
-
- if (function_name == nullptr)
- should_stop_here = false;
- else if (strstr(function_name, target_name) == nullptr)
- should_stop_here = false;
- }
- if (log && !should_stop_here)
- log->Printf("Stepping out of frame %s which did not match step into target %s.",
- sc.GetFunctionName().AsCString(),
- step_in_range_plan->m_step_into_target.AsCString());
- }
- }
-
- if (should_stop_here)
- {
- ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
- // Don't log the should_step_out here, it's easier to do it in FrameMatchesAvoidCriteria.
- should_stop_here = !step_in_range_plan->FrameMatchesAvoidCriteria ();
- }
- }
-
+bool ThreadPlanStepInRange::DefaultShouldStopHereCallback(
+ ThreadPlan *current_plan, Flags &flags, FrameComparison operation,
+ void *baton) {
+ bool should_stop_here = true;
+ StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+
+ // First see if the ThreadPlanShouldStopHere default implementation thinks we
+ // should get out of here:
+ should_stop_here = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
+ current_plan, flags, operation, baton);
+ if (!should_stop_here)
return should_stop_here;
-}
-bool
-ThreadPlanStepInRange::DoPlanExplainsStop (Event *event_ptr)
-{
- // We always explain a stop. Either we've just done a single step, in which
- // case we'll do our ordinary processing, or we stopped for some
- // reason that isn't handled by our sub-plans, in which case we want to just stop right
- // away.
- // In general, we don't want to mark the plan as complete for unexplained stops.
- // For instance, if you step in to some code with no debug info, so you step out
- // and in the course of that hit a breakpoint, then you want to stop & show the user
- // the breakpoint, but not unship the step in plan, since you still may want to complete that
- // plan when you continue. This is particularly true when doing "step in to target function."
- // stepping.
- //
- // The only variation is that if we are doing "step by running to next branch" in which case
- // if we hit our branch breakpoint we don't set the plan to complete.
-
- bool return_value = false;
-
- if (m_virtual_step)
- {
- return_value = true;
- }
- else
- {
- StopInfoSP stop_info_sp = GetPrivateStopInfo ();
- if (stop_info_sp)
- {
- StopReason reason = stop_info_sp->GetStopReason();
-
- if (reason == eStopReasonBreakpoint)
- {
- if (NextRangeBreakpointExplainsStop(stop_info_sp))
- {
- return_value = true;
- }
- }
- else if (IsUsuallyUnexplainedStopReason(reason))
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log)
- log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
- return_value = false;
- }
- else
- {
- return_value = true;
- }
+ if (should_stop_here && current_plan->GetKind() == eKindStepInRange &&
+ operation == eFrameCompareYounger) {
+ ThreadPlanStepInRange *step_in_range_plan =
+ static_cast<ThreadPlanStepInRange *>(current_plan);
+ if (step_in_range_plan->m_step_into_target) {
+ SymbolContext sc = frame->GetSymbolContext(
+ eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
+ if (sc.symbol != nullptr) {
+ // First try an exact match, since that's cheap with ConstStrings. Then
+ // do a strstr compare.
+ if (step_in_range_plan->m_step_into_target == sc.GetFunctionName()) {
+ should_stop_here = true;
+ } else {
+ const char *target_name =
+ step_in_range_plan->m_step_into_target.AsCString();
+ const char *function_name = sc.GetFunctionName().AsCString();
+
+ if (function_name == nullptr)
+ should_stop_here = false;
+ else if (strstr(function_name, target_name) == nullptr)
+ should_stop_here = false;
}
- else
- return_value = true;
+ if (log && !should_stop_here)
+ log->Printf("Stepping out of frame %s which did not match step into "
+ "target %s.",
+ sc.GetFunctionName().AsCString(),
+ step_in_range_plan->m_step_into_target.AsCString());
+ }
}
-
- return return_value;
+
+ if (should_stop_here) {
+ ThreadPlanStepInRange *step_in_range_plan =
+ static_cast<ThreadPlanStepInRange *>(current_plan);
+ // Don't log the should_step_out here, it's easier to do it in
+ // FrameMatchesAvoidCriteria.
+ should_stop_here = !step_in_range_plan->FrameMatchesAvoidCriteria();
+ }
+ }
+
+ return should_stop_here;
}
-bool
-ThreadPlanStepInRange::DoWillResume (lldb::StateType resume_state, bool current_plan)
-{
- m_virtual_step = false;
- if (resume_state == eStateStepping && current_plan)
- {
- // See if we are about to step over a virtual inlined call.
- bool step_without_resume = m_thread.DecrementCurrentInlinedDepth();
- if (step_without_resume)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log)
- log->Printf ("ThreadPlanStepInRange::DoWillResume: returning false, inline_depth: %d",
- m_thread.GetCurrentInlinedDepth());
- SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread));
-
- // FIXME: Maybe it would be better to create a InlineStep stop reason, but then
- // the whole rest of the world would have to handle that stop reason.
- m_virtual_step = true;
+bool ThreadPlanStepInRange::DoPlanExplainsStop(Event *event_ptr) {
+ // We always explain a stop. Either we've just done a single step, in which
+ // case we'll do our ordinary processing, or we stopped for some
+ // reason that isn't handled by our sub-plans, in which case we want to just
+ // stop right
+ // away.
+ // In general, we don't want to mark the plan as complete for unexplained
+ // stops.
+ // For instance, if you step in to some code with no debug info, so you step
+ // out
+ // and in the course of that hit a breakpoint, then you want to stop & show
+ // the user
+ // the breakpoint, but not unship the step in plan, since you still may want
+ // to complete that
+ // plan when you continue. This is particularly true when doing "step in to
+ // target function."
+ // stepping.
+ //
+ // The only variation is that if we are doing "step by running to next branch"
+ // in which case
+ // if we hit our branch breakpoint we don't set the plan to complete.
+
+ bool return_value = false;
+
+ if (m_virtual_step) {
+ return_value = true;
+ } else {
+ StopInfoSP stop_info_sp = GetPrivateStopInfo();
+ if (stop_info_sp) {
+ StopReason reason = stop_info_sp->GetStopReason();
+
+ if (reason == eStopReasonBreakpoint) {
+ if (NextRangeBreakpointExplainsStop(stop_info_sp)) {
+ return_value = true;
}
- return !step_without_resume;
- }
- return true;
+ } else if (IsUsuallyUnexplainedStopReason(reason)) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log)
+ log->PutCString("ThreadPlanStepInRange got asked if it explains the "
+ "stop for some reason other than step.");
+ return_value = false;
+ } else {
+ return_value = true;
+ }
+ } else
+ return_value = true;
+ }
+
+ return return_value;
}
-bool
-ThreadPlanStepInRange::IsVirtualStep()
-{
- return m_virtual_step;
+bool ThreadPlanStepInRange::DoWillResume(lldb::StateType resume_state,
+ bool current_plan) {
+ m_virtual_step = false;
+ if (resume_state == eStateStepping && current_plan) {
+ // See if we are about to step over a virtual inlined call.
+ bool step_without_resume = m_thread.DecrementCurrentInlinedDepth();
+ if (step_without_resume) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log)
+ log->Printf("ThreadPlanStepInRange::DoWillResume: returning false, "
+ "inline_depth: %d",
+ m_thread.GetCurrentInlinedDepth());
+ SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread));
+
+ // FIXME: Maybe it would be better to create a InlineStep stop reason, but
+ // then
+ // the whole rest of the world would have to handle that stop reason.
+ m_virtual_step = true;
+ }
+ return !step_without_resume;
+ }
+ return true;
}
+
+bool ThreadPlanStepInRange::IsVirtualStep() { return m_virtual_step; }
OpenPOWER on IntegriCloud