summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/lldb/source/Target/StackFrameList.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/StackFrameList.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/StackFrameList.cpp')
-rw-r--r--contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp1521
1 files changed, 715 insertions, 806 deletions
diff --git a/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp b/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp
index 8304caf..146b2b0 100644
--- a/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp
+++ b/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp
@@ -12,11 +12,11 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Target/StackFrameList.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Log.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Core/SourceManager.h"
+#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
@@ -36,908 +36,817 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// StackFrameList constructor
//----------------------------------------------------------------------
-StackFrameList::StackFrameList(Thread &thread, const lldb::StackFrameListSP &prev_frames_sp, bool show_inline_frames)
- : m_thread(thread),
- m_prev_frames_sp(prev_frames_sp),
- m_mutex(),
- m_frames(),
- m_selected_frame_idx(0),
- m_concrete_frames_fetched(0),
+StackFrameList::StackFrameList(Thread &thread,
+ const lldb::StackFrameListSP &prev_frames_sp,
+ bool show_inline_frames)
+ : m_thread(thread), m_prev_frames_sp(prev_frames_sp), m_mutex(), m_frames(),
+ m_selected_frame_idx(0), m_concrete_frames_fetched(0),
m_current_inlined_depth(UINT32_MAX),
m_current_inlined_pc(LLDB_INVALID_ADDRESS),
- m_show_inlined_frames(show_inline_frames)
-{
- if (prev_frames_sp)
- {
- m_current_inlined_depth = prev_frames_sp->m_current_inlined_depth;
- m_current_inlined_pc = prev_frames_sp->m_current_inlined_pc;
- }
+ m_show_inlined_frames(show_inline_frames) {
+ if (prev_frames_sp) {
+ m_current_inlined_depth = prev_frames_sp->m_current_inlined_depth;
+ m_current_inlined_pc = prev_frames_sp->m_current_inlined_pc;
+ }
}
-StackFrameList::~StackFrameList()
-{
- // Call clear since this takes a lock and clears the stack frame list
- // in case another thread is currently using this stack frame list
- Clear();
+StackFrameList::~StackFrameList() {
+ // Call clear since this takes a lock and clears the stack frame list
+ // in case another thread is currently using this stack frame list
+ Clear();
}
-void
-StackFrameList::CalculateCurrentInlinedDepth()
-{
- uint32_t cur_inlined_depth = GetCurrentInlinedDepth();
- if (cur_inlined_depth == UINT32_MAX)
- {
- ResetCurrentInlinedDepth();
- }
+void StackFrameList::CalculateCurrentInlinedDepth() {
+ uint32_t cur_inlined_depth = GetCurrentInlinedDepth();
+ if (cur_inlined_depth == UINT32_MAX) {
+ ResetCurrentInlinedDepth();
+ }
}
-uint32_t
-StackFrameList::GetCurrentInlinedDepth ()
-{
- if (m_show_inlined_frames && m_current_inlined_pc != LLDB_INVALID_ADDRESS)
- {
- lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC();
- if (cur_pc != m_current_inlined_pc)
- {
- m_current_inlined_pc = LLDB_INVALID_ADDRESS;
- m_current_inlined_depth = UINT32_MAX;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log && log->GetVerbose())
- log->Printf ("GetCurrentInlinedDepth: invalidating current inlined depth.\n");
- }
- return m_current_inlined_depth;
- }
- else
- {
- return UINT32_MAX;
+uint32_t StackFrameList::GetCurrentInlinedDepth() {
+ if (m_show_inlined_frames && m_current_inlined_pc != LLDB_INVALID_ADDRESS) {
+ lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC();
+ if (cur_pc != m_current_inlined_pc) {
+ m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+ m_current_inlined_depth = UINT32_MAX;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log && log->GetVerbose())
+ log->Printf(
+ "GetCurrentInlinedDepth: invalidating current inlined depth.\n");
}
+ return m_current_inlined_depth;
+ } else {
+ return UINT32_MAX;
+ }
}
-void
-StackFrameList::ResetCurrentInlinedDepth ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (m_show_inlined_frames)
- {
- GetFramesUpTo(0);
- if (m_frames.empty())
- return;
- if (!m_frames[0]->IsInlined())
- {
- m_current_inlined_depth = UINT32_MAX;
- m_current_inlined_pc = LLDB_INVALID_ADDRESS;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log && log->GetVerbose())
- log->Printf ("ResetCurrentInlinedDepth: Invalidating current inlined depth.\n");
- }
- else
- {
- // We only need to do something special about inlined blocks when we
- // are at the beginning of an inlined function:
- // FIXME: We probably also have to do something special if the PC is at the END
- // of an inlined function, which coincides with the end of either its containing
- // function or another inlined function.
-
- lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
- Block *block_ptr = m_frames[0]->GetFrameBlock();
- if (block_ptr)
- {
- Address pc_as_address;
- pc_as_address.SetLoadAddress(curr_pc, &(m_thread.GetProcess()->GetTarget()));
- AddressRange containing_range;
- if (block_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
- {
- if (pc_as_address == containing_range.GetBaseAddress())
- {
- // If we got here because of a breakpoint hit, then set the inlined depth depending on where
- // the breakpoint was set.
- // If we got here because of a crash, then set the inlined depth to the deepest most block.
- // Otherwise, we stopped here naturally as the result of a step, so set ourselves in the
- // containing frame of the whole set of nested inlines, so the user can then "virtually"
- // step into the frames one by one, or next over the whole mess.
- // Note: We don't have to handle being somewhere in the middle of the stack here, since
- // ResetCurrentInlinedDepth doesn't get called if there is a valid inlined depth set.
- StopInfoSP stop_info_sp = m_thread.GetStopInfo();
- if (stop_info_sp)
- {
- switch (stop_info_sp->GetStopReason())
- {
- case eStopReasonWatchpoint:
- case eStopReasonException:
- case eStopReasonExec:
- case eStopReasonSignal:
- // In all these cases we want to stop in the deepest most frame.
- m_current_inlined_pc = curr_pc;
- m_current_inlined_depth = 0;
- break;
- case eStopReasonBreakpoint:
- {
- // FIXME: Figure out what this break point is doing, and set the inline depth
- // appropriately. Be careful to take into account breakpoints that implement
- // step over prologue, since that should do the default calculation.
- // For now, if the breakpoints corresponding to this hit are all internal,
- // I set the stop location to the top of the inlined stack, since that will make
- // things like stepping over prologues work right. But if there are any non-internal
- // breakpoints I do to the bottom of the stack, since that was the old behavior.
- uint32_t bp_site_id = stop_info_sp->GetValue();
- BreakpointSiteSP bp_site_sp(m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id));
- bool all_internal = true;
- if (bp_site_sp)
- {
- uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
- for (uint32_t i = 0; i < num_owners; i++)
- {
- Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
- if (!bp_ref.IsInternal())
- {
- all_internal = false;
- }
- }
- }
- if (!all_internal)
- {
- m_current_inlined_pc = curr_pc;
- m_current_inlined_depth = 0;
- break;
- }
- }
- LLVM_FALLTHROUGH;
- default:
- {
- // Otherwise, we should set ourselves at the container of the inlining, so that the
- // user can descend into them.
- // So first we check whether we have more than one inlined block sharing this PC:
- int num_inlined_functions = 0;
-
- for (Block *container_ptr = block_ptr->GetInlinedParent();
- container_ptr != nullptr;
- container_ptr = container_ptr->GetInlinedParent())
- {
- if (!container_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
- break;
- if (pc_as_address != containing_range.GetBaseAddress())
- break;
-
- num_inlined_functions++;
- }
- m_current_inlined_pc = curr_pc;
- m_current_inlined_depth = num_inlined_functions + 1;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log && log->GetVerbose())
- log->Printf ("ResetCurrentInlinedDepth: setting inlined depth: %d 0x%" PRIx64 ".\n", m_current_inlined_depth, curr_pc);
-
- }
- break;
- }
- }
+void StackFrameList::ResetCurrentInlinedDepth() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ if (m_show_inlined_frames) {
+ GetFramesUpTo(0);
+ if (m_frames.empty())
+ return;
+ if (!m_frames[0]->IsInlined()) {
+ m_current_inlined_depth = UINT32_MAX;
+ m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log && log->GetVerbose())
+ log->Printf(
+ "ResetCurrentInlinedDepth: Invalidating current inlined depth.\n");
+ } else {
+ // We only need to do something special about inlined blocks when we
+ // are at the beginning of an inlined function:
+ // FIXME: We probably also have to do something special if the PC is at
+ // the END
+ // of an inlined function, which coincides with the end of either its
+ // containing
+ // function or another inlined function.
+
+ lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
+ Block *block_ptr = m_frames[0]->GetFrameBlock();
+ if (block_ptr) {
+ Address pc_as_address;
+ pc_as_address.SetLoadAddress(curr_pc,
+ &(m_thread.GetProcess()->GetTarget()));
+ AddressRange containing_range;
+ if (block_ptr->GetRangeContainingAddress(pc_as_address,
+ containing_range)) {
+ if (pc_as_address == containing_range.GetBaseAddress()) {
+ // If we got here because of a breakpoint hit, then set the inlined
+ // depth depending on where
+ // the breakpoint was set.
+ // If we got here because of a crash, then set the inlined depth to
+ // the deepest most block.
+ // Otherwise, we stopped here naturally as the result of a step, so
+ // set ourselves in the
+ // containing frame of the whole set of nested inlines, so the user
+ // can then "virtually"
+ // step into the frames one by one, or next over the whole mess.
+ // Note: We don't have to handle being somewhere in the middle of
+ // the stack here, since
+ // ResetCurrentInlinedDepth doesn't get called if there is a valid
+ // inlined depth set.
+ StopInfoSP stop_info_sp = m_thread.GetStopInfo();
+ if (stop_info_sp) {
+ switch (stop_info_sp->GetStopReason()) {
+ case eStopReasonWatchpoint:
+ case eStopReasonException:
+ case eStopReasonExec:
+ case eStopReasonSignal:
+ // In all these cases we want to stop in the deepest most frame.
+ m_current_inlined_pc = curr_pc;
+ m_current_inlined_depth = 0;
+ break;
+ case eStopReasonBreakpoint: {
+ // FIXME: Figure out what this break point is doing, and set the
+ // inline depth
+ // appropriately. Be careful to take into account breakpoints
+ // that implement
+ // step over prologue, since that should do the default
+ // calculation.
+ // For now, if the breakpoints corresponding to this hit are all
+ // internal,
+ // I set the stop location to the top of the inlined stack,
+ // since that will make
+ // things like stepping over prologues work right. But if there
+ // are any non-internal
+ // breakpoints I do to the bottom of the stack, since that was
+ // the old behavior.
+ uint32_t bp_site_id = stop_info_sp->GetValue();
+ BreakpointSiteSP bp_site_sp(
+ m_thread.GetProcess()->GetBreakpointSiteList().FindByID(
+ bp_site_id));
+ bool all_internal = true;
+ if (bp_site_sp) {
+ uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
+ for (uint32_t i = 0; i < num_owners; i++) {
+ Breakpoint &bp_ref =
+ bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+ if (!bp_ref.IsInternal()) {
+ all_internal = false;
}
+ }
+ }
+ if (!all_internal) {
+ m_current_inlined_pc = curr_pc;
+ m_current_inlined_depth = 0;
+ break;
+ }
+ }
+ LLVM_FALLTHROUGH;
+ default: {
+ // Otherwise, we should set ourselves at the container of the
+ // inlining, so that the
+ // user can descend into them.
+ // So first we check whether we have more than one inlined block
+ // sharing this PC:
+ int num_inlined_functions = 0;
+
+ for (Block *container_ptr = block_ptr->GetInlinedParent();
+ container_ptr != nullptr;
+ container_ptr = container_ptr->GetInlinedParent()) {
+ if (!container_ptr->GetRangeContainingAddress(
+ pc_as_address, containing_range))
+ break;
+ if (pc_as_address != containing_range.GetBaseAddress())
+ break;
+
+ num_inlined_functions++;
}
+ m_current_inlined_pc = curr_pc;
+ m_current_inlined_depth = num_inlined_functions + 1;
+ Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log && log->GetVerbose())
+ log->Printf("ResetCurrentInlinedDepth: setting inlined "
+ "depth: %d 0x%" PRIx64 ".\n",
+ m_current_inlined_depth, curr_pc);
+
+ } break;
+ }
}
+ }
}
+ }
}
+ }
}
-bool
-StackFrameList::DecrementCurrentInlinedDepth ()
-{
- if (m_show_inlined_frames)
- {
- uint32_t current_inlined_depth = GetCurrentInlinedDepth();
- if (current_inlined_depth != UINT32_MAX)
- {
- if (current_inlined_depth > 0)
- {
- m_current_inlined_depth--;
- return true;
- }
- }
+bool StackFrameList::DecrementCurrentInlinedDepth() {
+ if (m_show_inlined_frames) {
+ uint32_t current_inlined_depth = GetCurrentInlinedDepth();
+ if (current_inlined_depth != UINT32_MAX) {
+ if (current_inlined_depth > 0) {
+ m_current_inlined_depth--;
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-void
-StackFrameList::SetCurrentInlinedDepth (uint32_t new_depth)
-{
- m_current_inlined_depth = new_depth;
- if (new_depth == UINT32_MAX)
- m_current_inlined_pc = LLDB_INVALID_ADDRESS;
- else
- m_current_inlined_pc = m_thread.GetRegisterContext()->GetPC();
+void StackFrameList::SetCurrentInlinedDepth(uint32_t new_depth) {
+ m_current_inlined_depth = new_depth;
+ if (new_depth == UINT32_MAX)
+ m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+ else
+ m_current_inlined_pc = m_thread.GetRegisterContext()->GetPC();
}
-void
-StackFrameList::GetFramesUpTo(uint32_t end_idx)
-{
- // this makes sure we do not fetch frames for an invalid thread
- if (!m_thread.IsValid())
- return;
-
- // We've already gotten more frames than asked for, or we've already finished unwinding, return.
- if (m_frames.size() > end_idx || GetAllFramesFetched())
- return;
-
- Unwind *unwinder = m_thread.GetUnwinder ();
-
- if (m_show_inlined_frames)
- {
-#if defined (DEBUG_STACK_FRAMES)
- StreamFile s(stdout, false);
+void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
+ // this makes sure we do not fetch frames for an invalid thread
+ if (!m_thread.IsValid())
+ return;
+
+ // We've already gotten more frames than asked for, or we've already finished
+ // unwinding, return.
+ if (m_frames.size() > end_idx || GetAllFramesFetched())
+ return;
+
+ Unwind *unwinder = m_thread.GetUnwinder();
+
+ if (m_show_inlined_frames) {
+#if defined(DEBUG_STACK_FRAMES)
+ StreamFile s(stdout, false);
#endif
- // If we are hiding some frames from the outside world, we need to add those onto the total count of
- // frames to fetch. However, we don't need to do that if end_idx is 0 since in that case we always
- // get the first concrete frame and all the inlined frames below it... And of course, if end_idx is
- // UINT32_MAX that means get all, so just do that...
-
- uint32_t inlined_depth = 0;
- if (end_idx > 0 && end_idx != UINT32_MAX)
- {
- inlined_depth = GetCurrentInlinedDepth();
- if (inlined_depth != UINT32_MAX)
- {
- if (end_idx > 0)
- end_idx += inlined_depth;
+ // If we are hiding some frames from the outside world, we need to add those
+ // onto the total count of
+ // frames to fetch. However, we don't need to do that if end_idx is 0 since
+ // in that case we always
+ // get the first concrete frame and all the inlined frames below it... And
+ // of course, if end_idx is
+ // UINT32_MAX that means get all, so just do that...
+
+ uint32_t inlined_depth = 0;
+ if (end_idx > 0 && end_idx != UINT32_MAX) {
+ inlined_depth = GetCurrentInlinedDepth();
+ if (inlined_depth != UINT32_MAX) {
+ if (end_idx > 0)
+ end_idx += inlined_depth;
+ }
+ }
+
+ StackFrameSP unwind_frame_sp;
+ do {
+ uint32_t idx = m_concrete_frames_fetched++;
+ lldb::addr_t pc = LLDB_INVALID_ADDRESS;
+ lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
+ if (idx == 0) {
+ // We might have already created frame zero, only create it
+ // if we need to
+ if (m_frames.empty()) {
+ RegisterContextSP reg_ctx_sp(m_thread.GetRegisterContext());
+
+ if (reg_ctx_sp) {
+ const bool success =
+ unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
+ // There shouldn't be any way not to get the frame info for frame 0.
+ // But if the unwinder can't make one, lets make one by hand with
+ // the
+ // SP as the CFA and see if that gets any further.
+ if (!success) {
+ cfa = reg_ctx_sp->GetSP();
+ pc = reg_ctx_sp->GetPC();
}
+
+ unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(),
+ m_frames.size(), idx,
+ reg_ctx_sp, cfa, pc, nullptr));
+ m_frames.push_back(unwind_frame_sp);
+ }
+ } else {
+ unwind_frame_sp = m_frames.front();
+ cfa = unwind_frame_sp->m_id.GetCallFrameAddress();
}
-
- StackFrameSP unwind_frame_sp;
- do
- {
- uint32_t idx = m_concrete_frames_fetched++;
- lldb::addr_t pc = LLDB_INVALID_ADDRESS;
- lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
- if (idx == 0)
- {
- // We might have already created frame zero, only create it
- // if we need to
- if (m_frames.empty())
- {
- RegisterContextSP reg_ctx_sp (m_thread.GetRegisterContext());
-
- if (reg_ctx_sp)
- {
- const bool success = unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
- // There shouldn't be any way not to get the frame info for frame 0.
- // But if the unwinder can't make one, lets make one by hand with the
- // SP as the CFA and see if that gets any further.
- if (!success)
- {
- cfa = reg_ctx_sp->GetSP();
- pc = reg_ctx_sp->GetPC();
- }
-
- unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(),
- m_frames.size(),
- idx,
- reg_ctx_sp,
- cfa,
- pc,
- nullptr));
- m_frames.push_back (unwind_frame_sp);
- }
- }
- else
- {
- unwind_frame_sp = m_frames.front();
- cfa = unwind_frame_sp->m_id.GetCallFrameAddress();
- }
- }
- else
- {
- const bool success = unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
- if (!success)
- {
- // We've gotten to the end of the stack.
- SetAllFramesFetched();
- break;
- }
- const bool cfa_is_valid = true;
- const bool stop_id_is_valid = false;
- const bool is_history_frame = false;
- unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid, pc,
- 0, stop_id_is_valid, is_history_frame, nullptr));
- m_frames.push_back (unwind_frame_sp);
- }
-
- assert(unwind_frame_sp);
- SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock | eSymbolContextFunction);
- Block *unwind_block = unwind_sc.block;
- if (unwind_block)
- {
- Address curr_frame_address (unwind_frame_sp->GetFrameCodeAddress());
- TargetSP target_sp = m_thread.CalculateTarget();
- // Be sure to adjust the frame address to match the address
- // that was used to lookup the symbol context above. If we are
- // in the first concrete frame, then we lookup using the current
- // address, else we decrement the address by one to get the correct
- // location.
- if (idx > 0)
- {
- if (curr_frame_address.GetOffset() == 0)
- {
- // If curr_frame_address points to the first address in a section then after
- // adjustment it will point to an other section. In that case resolve the
- // address again to the correct section plus offset form.
- addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress(target_sp.get(), eAddressClassCode);
- curr_frame_address.SetOpcodeLoadAddress(load_addr - 1, target_sp.get(), eAddressClassCode);
- }
- else
- {
- curr_frame_address.Slide(-1);
- }
- }
-
- SymbolContext next_frame_sc;
- Address next_frame_address;
-
- while (unwind_sc.GetParentOfInlinedScope(curr_frame_address, next_frame_sc, next_frame_address))
- {
- next_frame_sc.line_entry.ApplyFileMappings(target_sp);
- StackFrameSP frame_sp(new StackFrame(m_thread.shared_from_this(),
- m_frames.size(),
- idx,
- unwind_frame_sp->GetRegisterContextSP (),
- cfa,
- next_frame_address,
- &next_frame_sc));
-
- m_frames.push_back (frame_sp);
- unwind_sc = next_frame_sc;
- curr_frame_address = next_frame_address;
- }
- }
- } while (m_frames.size() - 1 < end_idx);
-
- // Don't try to merge till you've calculated all the frames in this stack.
- if (GetAllFramesFetched() && m_prev_frames_sp)
- {
- StackFrameList *prev_frames = m_prev_frames_sp.get();
- StackFrameList *curr_frames = this;
-
- //curr_frames->m_current_inlined_depth = prev_frames->m_current_inlined_depth;
- //curr_frames->m_current_inlined_pc = prev_frames->m_current_inlined_pc;
- //printf ("GetFramesUpTo: Copying current inlined depth: %d 0x%" PRIx64 ".\n", curr_frames->m_current_inlined_depth, curr_frames->m_current_inlined_pc);
-
-#if defined (DEBUG_STACK_FRAMES)
- s.PutCString("\nprev_frames:\n");
- prev_frames->Dump (&s);
- s.PutCString("\ncurr_frames:\n");
- curr_frames->Dump (&s);
- s.EOL();
+ } else {
+ const bool success =
+ unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
+ if (!success) {
+ // We've gotten to the end of the stack.
+ SetAllFramesFetched();
+ break;
+ }
+ const bool cfa_is_valid = true;
+ const bool stop_id_is_valid = false;
+ const bool is_history_frame = false;
+ unwind_frame_sp.reset(new StackFrame(
+ m_thread.shared_from_this(), m_frames.size(), idx, cfa,
+ cfa_is_valid, pc, 0, stop_id_is_valid, is_history_frame, nullptr));
+ m_frames.push_back(unwind_frame_sp);
+ }
+
+ assert(unwind_frame_sp);
+ SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext(
+ eSymbolContextBlock | eSymbolContextFunction);
+ Block *unwind_block = unwind_sc.block;
+ if (unwind_block) {
+ Address curr_frame_address(unwind_frame_sp->GetFrameCodeAddress());
+ TargetSP target_sp = m_thread.CalculateTarget();
+ // Be sure to adjust the frame address to match the address
+ // that was used to lookup the symbol context above. If we are
+ // in the first concrete frame, then we lookup using the current
+ // address, else we decrement the address by one to get the correct
+ // location.
+ if (idx > 0) {
+ if (curr_frame_address.GetOffset() == 0) {
+ // If curr_frame_address points to the first address in a section
+ // then after
+ // adjustment it will point to an other section. In that case
+ // resolve the
+ // address again to the correct section plus offset form.
+ addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress(
+ target_sp.get(), eAddressClassCode);
+ curr_frame_address.SetOpcodeLoadAddress(
+ load_addr - 1, target_sp.get(), eAddressClassCode);
+ } else {
+ curr_frame_address.Slide(-1);
+ }
+ }
+
+ SymbolContext next_frame_sc;
+ Address next_frame_address;
+
+ while (unwind_sc.GetParentOfInlinedScope(
+ curr_frame_address, next_frame_sc, next_frame_address)) {
+ next_frame_sc.line_entry.ApplyFileMappings(target_sp);
+ StackFrameSP frame_sp(
+ new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx,
+ unwind_frame_sp->GetRegisterContextSP(), cfa,
+ next_frame_address, &next_frame_sc));
+
+ m_frames.push_back(frame_sp);
+ unwind_sc = next_frame_sc;
+ curr_frame_address = next_frame_address;
+ }
+ }
+ } while (m_frames.size() - 1 < end_idx);
+
+ // Don't try to merge till you've calculated all the frames in this stack.
+ if (GetAllFramesFetched() && m_prev_frames_sp) {
+ StackFrameList *prev_frames = m_prev_frames_sp.get();
+ StackFrameList *curr_frames = this;
+
+// curr_frames->m_current_inlined_depth = prev_frames->m_current_inlined_depth;
+// curr_frames->m_current_inlined_pc = prev_frames->m_current_inlined_pc;
+// printf ("GetFramesUpTo: Copying current inlined depth: %d 0x%" PRIx64 ".\n",
+// curr_frames->m_current_inlined_depth, curr_frames->m_current_inlined_pc);
+
+#if defined(DEBUG_STACK_FRAMES)
+ s.PutCString("\nprev_frames:\n");
+ prev_frames->Dump(&s);
+ s.PutCString("\ncurr_frames:\n");
+ curr_frames->Dump(&s);
+ s.EOL();
#endif
- size_t curr_frame_num, prev_frame_num;
-
- for (curr_frame_num = curr_frames->m_frames.size(), prev_frame_num = prev_frames->m_frames.size();
- curr_frame_num > 0 && prev_frame_num > 0;
- --curr_frame_num, --prev_frame_num)
- {
- const size_t curr_frame_idx = curr_frame_num-1;
- const size_t prev_frame_idx = prev_frame_num-1;
- StackFrameSP curr_frame_sp (curr_frames->m_frames[curr_frame_idx]);
- StackFrameSP prev_frame_sp (prev_frames->m_frames[prev_frame_idx]);
-
-#if defined (DEBUG_STACK_FRAMES)
- s.Printf("\n\nCurr frame #%u ", curr_frame_idx);
- if (curr_frame_sp)
- curr_frame_sp->Dump (&s, true, false);
- else
- s.PutCString("NULL");
- s.Printf("\nPrev frame #%u ", prev_frame_idx);
- if (prev_frame_sp)
- prev_frame_sp->Dump (&s, true, false);
- else
- s.PutCString("NULL");
+ size_t curr_frame_num, prev_frame_num;
+
+ for (curr_frame_num = curr_frames->m_frames.size(),
+ prev_frame_num = prev_frames->m_frames.size();
+ curr_frame_num > 0 && prev_frame_num > 0;
+ --curr_frame_num, --prev_frame_num) {
+ const size_t curr_frame_idx = curr_frame_num - 1;
+ const size_t prev_frame_idx = prev_frame_num - 1;
+ StackFrameSP curr_frame_sp(curr_frames->m_frames[curr_frame_idx]);
+ StackFrameSP prev_frame_sp(prev_frames->m_frames[prev_frame_idx]);
+
+#if defined(DEBUG_STACK_FRAMES)
+ s.Printf("\n\nCurr frame #%u ", curr_frame_idx);
+ if (curr_frame_sp)
+ curr_frame_sp->Dump(&s, true, false);
+ else
+ s.PutCString("NULL");
+ s.Printf("\nPrev frame #%u ", prev_frame_idx);
+ if (prev_frame_sp)
+ prev_frame_sp->Dump(&s, true, false);
+ else
+ s.PutCString("NULL");
#endif
- StackFrame *curr_frame = curr_frame_sp.get();
- StackFrame *prev_frame = prev_frame_sp.get();
-
- if (curr_frame == nullptr || prev_frame == nullptr)
- break;
+ StackFrame *curr_frame = curr_frame_sp.get();
+ StackFrame *prev_frame = prev_frame_sp.get();
- // Check the stack ID to make sure they are equal
- if (curr_frame->GetStackID() != prev_frame->GetStackID())
- break;
+ if (curr_frame == nullptr || prev_frame == nullptr)
+ break;
- prev_frame->UpdatePreviousFrameFromCurrentFrame (*curr_frame);
- // Now copy the fixed up previous frame into the current frames
- // so the pointer doesn't change
- m_frames[curr_frame_idx] = prev_frame_sp;
- //curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame);
-
-#if defined (DEBUG_STACK_FRAMES)
- s.Printf("\n Copying previous frame to current frame");
-#endif
- }
- // We are done with the old stack frame list, we can release it now
- m_prev_frames_sp.reset();
- }
-
-#if defined (DEBUG_STACK_FRAMES)
- s.PutCString("\n\nNew frames:\n");
- Dump (&s);
- s.EOL();
+ // Check the stack ID to make sure they are equal
+ if (curr_frame->GetStackID() != prev_frame->GetStackID())
+ break;
+
+ prev_frame->UpdatePreviousFrameFromCurrentFrame(*curr_frame);
+ // Now copy the fixed up previous frame into the current frames
+ // so the pointer doesn't change
+ m_frames[curr_frame_idx] = prev_frame_sp;
+// curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame);
+
+#if defined(DEBUG_STACK_FRAMES)
+ s.Printf("\n Copying previous frame to current frame");
#endif
+ }
+ // We are done with the old stack frame list, we can release it now
+ m_prev_frames_sp.reset();
}
- else
- {
- if (end_idx < m_concrete_frames_fetched)
- return;
-
- if (unwinder)
- {
- uint32_t num_frames = unwinder->GetFramesUpTo(end_idx);
- if (num_frames <= end_idx + 1)
- {
- //Done unwinding.
- m_concrete_frames_fetched = UINT32_MAX;
- }
- m_frames.resize(num_frames);
- }
+
+#if defined(DEBUG_STACK_FRAMES)
+ s.PutCString("\n\nNew frames:\n");
+ Dump(&s);
+ s.EOL();
+#endif
+ } else {
+ if (end_idx < m_concrete_frames_fetched)
+ return;
+
+ if (unwinder) {
+ uint32_t num_frames = unwinder->GetFramesUpTo(end_idx);
+ if (num_frames <= end_idx + 1) {
+ // Done unwinding.
+ m_concrete_frames_fetched = UINT32_MAX;
+ }
+ m_frames.resize(num_frames);
}
+ }
}
-uint32_t
-StackFrameList::GetNumFrames (bool can_create)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
+uint32_t StackFrameList::GetNumFrames(bool can_create) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (can_create)
- GetFramesUpTo (UINT32_MAX);
+ if (can_create)
+ GetFramesUpTo(UINT32_MAX);
- uint32_t inlined_depth = GetCurrentInlinedDepth();
- if (inlined_depth == UINT32_MAX)
- return m_frames.size();
- else
- return m_frames.size() - inlined_depth;
+ uint32_t inlined_depth = GetCurrentInlinedDepth();
+ if (inlined_depth == UINT32_MAX)
+ return m_frames.size();
+ else
+ return m_frames.size() - inlined_depth;
}
-void
-StackFrameList::Dump (Stream *s)
-{
- if (s == nullptr)
- return;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- const_iterator pos, begin = m_frames.begin(), end = m_frames.end();
- for (pos = begin; pos != end; ++pos)
- {
- StackFrame *frame = (*pos).get();
- s->Printf("%p: ", static_cast<void*>(frame));
- if (frame)
- {
- frame->GetStackID().Dump (s);
- frame->DumpUsingSettingsFormat (s);
- }
- else
- s->Printf("frame #%u", (uint32_t)std::distance (begin, pos));
- s->EOL();
- }
+void StackFrameList::Dump(Stream *s) {
+ if (s == nullptr)
+ return;
+
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ const_iterator pos, begin = m_frames.begin(), end = m_frames.end();
+ for (pos = begin; pos != end; ++pos) {
+ StackFrame *frame = (*pos).get();
+ s->Printf("%p: ", static_cast<void *>(frame));
+ if (frame) {
+ frame->GetStackID().Dump(s);
+ frame->DumpUsingSettingsFormat(s);
+ } else
+ s->Printf("frame #%u", (uint32_t)std::distance(begin, pos));
s->EOL();
+ }
+ s->EOL();
}
-StackFrameSP
-StackFrameList::GetFrameAtIndex (uint32_t idx)
-{
- StackFrameSP frame_sp;
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- uint32_t original_idx = idx;
-
- uint32_t inlined_depth = GetCurrentInlinedDepth();
- if (inlined_depth != UINT32_MAX)
- idx += inlined_depth;
-
- if (idx < m_frames.size())
- frame_sp = m_frames[idx];
-
- if (frame_sp)
- return frame_sp;
-
- // GetFramesUpTo will fill m_frames with as many frames as you asked for,
- // if there are that many. If there weren't then you asked for too many
- // frames.
- GetFramesUpTo (idx);
- if (idx < m_frames.size())
- {
- if (m_show_inlined_frames)
- {
- // When inline frames are enabled we actually create all the frames in GetFramesUpTo.
- frame_sp = m_frames[idx];
- }
- else
- {
- Unwind *unwinder = m_thread.GetUnwinder ();
- if (unwinder)
- {
- addr_t pc, cfa;
- if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
- {
- const bool cfa_is_valid = true;
- const bool stop_id_is_valid = false;
- const bool is_history_frame = false;
- frame_sp.reset(new StackFrame(m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, 0,
- stop_id_is_valid, is_history_frame, nullptr));
-
- Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function;
- if (function)
- {
- // When we aren't showing inline functions we always use
- // the top most function block as the scope.
- frame_sp->SetSymbolContextScope (&function->GetBlock(false));
- }
- else
- {
- // Set the symbol scope from the symbol regardless if it is nullptr or valid.
- frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
- }
- SetFrameAtIndex(idx, frame_sp);
- }
- }
+StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) {
+ StackFrameSP frame_sp;
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ uint32_t original_idx = idx;
+
+ uint32_t inlined_depth = GetCurrentInlinedDepth();
+ if (inlined_depth != UINT32_MAX)
+ idx += inlined_depth;
+
+ if (idx < m_frames.size())
+ frame_sp = m_frames[idx];
+
+ if (frame_sp)
+ return frame_sp;
+
+ // GetFramesUpTo will fill m_frames with as many frames as you asked for,
+ // if there are that many. If there weren't then you asked for too many
+ // frames.
+ GetFramesUpTo(idx);
+ if (idx < m_frames.size()) {
+ if (m_show_inlined_frames) {
+ // When inline frames are enabled we actually create all the frames in
+ // GetFramesUpTo.
+ frame_sp = m_frames[idx];
+ } else {
+ Unwind *unwinder = m_thread.GetUnwinder();
+ if (unwinder) {
+ addr_t pc, cfa;
+ if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) {
+ const bool cfa_is_valid = true;
+ const bool stop_id_is_valid = false;
+ const bool is_history_frame = false;
+ frame_sp.reset(new StackFrame(
+ m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, 0,
+ stop_id_is_valid, is_history_frame, nullptr));
+
+ Function *function =
+ frame_sp->GetSymbolContext(eSymbolContextFunction).function;
+ if (function) {
+ // When we aren't showing inline functions we always use
+ // the top most function block as the scope.
+ frame_sp->SetSymbolContextScope(&function->GetBlock(false));
+ } else {
+ // Set the symbol scope from the symbol regardless if it is nullptr
+ // or valid.
+ frame_sp->SetSymbolContextScope(
+ frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol);
+ }
+ SetFrameAtIndex(idx, frame_sp);
}
+ }
}
- else if (original_idx == 0)
- {
- // There should ALWAYS be a frame at index 0. If something went wrong with the CurrentInlinedDepth such that
- // there weren't as many frames as we thought taking that into account, then reset the current inlined depth
- // and return the real zeroth frame.
- if (m_frames.empty())
- {
- // Why do we have a thread with zero frames, that should not ever happen...
- if (m_thread.IsValid())
- assert ("A valid thread has no frames.");
- }
- else
- {
- ResetCurrentInlinedDepth();
- frame_sp = m_frames[original_idx];
- }
+ } else if (original_idx == 0) {
+ // There should ALWAYS be a frame at index 0. If something went wrong with
+ // the CurrentInlinedDepth such that
+ // there weren't as many frames as we thought taking that into account, then
+ // reset the current inlined depth
+ // and return the real zeroth frame.
+ if (m_frames.empty()) {
+ // Why do we have a thread with zero frames, that should not ever
+ // happen...
+ assert(!m_thread.IsValid() && "A valid thread has no frames.");
+ } else {
+ ResetCurrentInlinedDepth();
+ frame_sp = m_frames[original_idx];
}
-
- return frame_sp;
+ }
+
+ return frame_sp;
}
StackFrameSP
-StackFrameList::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx)
-{
- // First try assuming the unwind index is the same as the frame index. The
- // unwind index is always greater than or equal to the frame index, so it
- // is a good place to start. If we have inlined frames we might have 5
- // concrete frames (frame unwind indexes go from 0-4), but we might have 15
- // frames after we make all the inlined frames. Most of the time the unwind
- // frame index (or the concrete frame index) is the same as the frame index.
- uint32_t frame_idx = unwind_idx;
- StackFrameSP frame_sp (GetFrameAtIndex (frame_idx));
- while (frame_sp)
- {
- if (frame_sp->GetFrameIndex() == unwind_idx)
- break;
- frame_sp = GetFrameAtIndex (++frame_idx);
- }
- return frame_sp;
+StackFrameList::GetFrameWithConcreteFrameIndex(uint32_t unwind_idx) {
+ // First try assuming the unwind index is the same as the frame index. The
+ // unwind index is always greater than or equal to the frame index, so it
+ // is a good place to start. If we have inlined frames we might have 5
+ // concrete frames (frame unwind indexes go from 0-4), but we might have 15
+ // frames after we make all the inlined frames. Most of the time the unwind
+ // frame index (or the concrete frame index) is the same as the frame index.
+ uint32_t frame_idx = unwind_idx;
+ StackFrameSP frame_sp(GetFrameAtIndex(frame_idx));
+ while (frame_sp) {
+ if (frame_sp->GetFrameIndex() == unwind_idx)
+ break;
+ frame_sp = GetFrameAtIndex(++frame_idx);
+ }
+ return frame_sp;
}
-static bool
-CompareStackID (const StackFrameSP &stack_sp, const StackID &stack_id)
-{
- return stack_sp->GetStackID() < stack_id;
+static bool CompareStackID(const StackFrameSP &stack_sp,
+ const StackID &stack_id) {
+ return stack_sp->GetStackID() < stack_id;
}
-StackFrameSP
-StackFrameList::GetFrameWithStackID (const StackID &stack_id)
-{
- StackFrameSP frame_sp;
-
- if (stack_id.IsValid())
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- uint32_t frame_idx = 0;
- // Do a binary search in case the stack frame is already in our cache
- collection::const_iterator begin = m_frames.begin();
- collection::const_iterator end = m_frames.end();
- if (begin != end)
- {
- collection::const_iterator pos = std::lower_bound (begin, end, stack_id, CompareStackID);
- if (pos != end)
- {
- if ((*pos)->GetStackID() == stack_id)
- return *pos;
- }
-
-// if (m_frames.back()->GetStackID() < stack_id)
-// frame_idx = m_frames.size();
- }
- do
- {
- frame_sp = GetFrameAtIndex (frame_idx);
- if (frame_sp && frame_sp->GetStackID() == stack_id)
- break;
- frame_idx++;
- }
- while (frame_sp);
+StackFrameSP StackFrameList::GetFrameWithStackID(const StackID &stack_id) {
+ StackFrameSP frame_sp;
+
+ if (stack_id.IsValid()) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ uint32_t frame_idx = 0;
+ // Do a binary search in case the stack frame is already in our cache
+ collection::const_iterator begin = m_frames.begin();
+ collection::const_iterator end = m_frames.end();
+ if (begin != end) {
+ collection::const_iterator pos =
+ std::lower_bound(begin, end, stack_id, CompareStackID);
+ if (pos != end) {
+ if ((*pos)->GetStackID() == stack_id)
+ return *pos;
+ }
+
+ // if (m_frames.back()->GetStackID() < stack_id)
+ // frame_idx = m_frames.size();
}
- return frame_sp;
+ do {
+ frame_sp = GetFrameAtIndex(frame_idx);
+ if (frame_sp && frame_sp->GetStackID() == stack_id)
+ break;
+ frame_idx++;
+ } while (frame_sp);
+ }
+ return frame_sp;
}
-bool
-StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
-{
- if (idx >= m_frames.size())
- m_frames.resize(idx + 1);
- // Make sure allocation succeeded by checking bounds again
- if (idx < m_frames.size())
- {
- m_frames[idx] = frame_sp;
- return true;
- }
- return false; // resize failed, out of memory?
+bool StackFrameList::SetFrameAtIndex(uint32_t idx, StackFrameSP &frame_sp) {
+ if (idx >= m_frames.size())
+ m_frames.resize(idx + 1);
+ // Make sure allocation succeeded by checking bounds again
+ if (idx < m_frames.size()) {
+ m_frames[idx] = frame_sp;
+ return true;
+ }
+ return false; // resize failed, out of memory?
}
-uint32_t
-StackFrameList::GetSelectedFrameIndex () const
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- return m_selected_frame_idx;
+uint32_t StackFrameList::GetSelectedFrameIndex() const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_selected_frame_idx;
}
-uint32_t
-StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- const_iterator pos;
- const_iterator begin = m_frames.begin();
- const_iterator end = m_frames.end();
- m_selected_frame_idx = 0;
- for (pos = begin; pos != end; ++pos)
- {
- if (pos->get() == frame)
- {
- m_selected_frame_idx = std::distance (begin, pos);
- uint32_t inlined_depth = GetCurrentInlinedDepth();
- if (inlined_depth != UINT32_MAX)
- m_selected_frame_idx -= inlined_depth;
- break;
- }
+uint32_t StackFrameList::SetSelectedFrame(lldb_private::StackFrame *frame) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ const_iterator pos;
+ const_iterator begin = m_frames.begin();
+ const_iterator end = m_frames.end();
+ m_selected_frame_idx = 0;
+ for (pos = begin; pos != end; ++pos) {
+ if (pos->get() == frame) {
+ m_selected_frame_idx = std::distance(begin, pos);
+ uint32_t inlined_depth = GetCurrentInlinedDepth();
+ if (inlined_depth != UINT32_MAX)
+ m_selected_frame_idx -= inlined_depth;
+ break;
}
- SetDefaultFileAndLineToSelectedFrame();
- return m_selected_frame_idx;
+ }
+ SetDefaultFileAndLineToSelectedFrame();
+ return m_selected_frame_idx;
}
// Mark a stack frame as the current frame using the frame index
-bool
-StackFrameList::SetSelectedFrameByIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- StackFrameSP frame_sp (GetFrameAtIndex (idx));
- if (frame_sp)
- {
- SetSelectedFrame(frame_sp.get());
- return true;
- }
- else
- return false;
+bool StackFrameList::SetSelectedFrameByIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ StackFrameSP frame_sp(GetFrameAtIndex(idx));
+ if (frame_sp) {
+ SetSelectedFrame(frame_sp.get());
+ return true;
+ } else
+ return false;
}
-void
-StackFrameList::SetDefaultFileAndLineToSelectedFrame()
-{
- if (m_thread.GetID() == m_thread.GetProcess()->GetThreadList().GetSelectedThread()->GetID())
- {
- StackFrameSP frame_sp (GetFrameAtIndex (GetSelectedFrameIndex()));
- if (frame_sp)
- {
- SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextLineEntry);
- if (sc.line_entry.file)
- m_thread.CalculateTarget()->GetSourceManager().SetDefaultFileAndLine (sc.line_entry.file,
- sc.line_entry.line);
- }
+void StackFrameList::SetDefaultFileAndLineToSelectedFrame() {
+ if (m_thread.GetID() ==
+ m_thread.GetProcess()->GetThreadList().GetSelectedThread()->GetID()) {
+ StackFrameSP frame_sp(GetFrameAtIndex(GetSelectedFrameIndex()));
+ if (frame_sp) {
+ SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextLineEntry);
+ if (sc.line_entry.file)
+ m_thread.CalculateTarget()->GetSourceManager().SetDefaultFileAndLine(
+ sc.line_entry.file, sc.line_entry.line);
}
+ }
}
// The thread has been run, reset the number stack frames to zero so we can
// determine how many frames we have lazily.
-void
-StackFrameList::Clear ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- m_frames.clear();
- m_concrete_frames_fetched = 0;
+void StackFrameList::Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_frames.clear();
+ m_concrete_frames_fetched = 0;
}
-void
-StackFrameList::InvalidateFrames (uint32_t start_idx)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (m_show_inlined_frames)
- {
- Clear();
- }
- else
- {
- const size_t num_frames = m_frames.size();
- while (start_idx < num_frames)
- {
- m_frames[start_idx].reset();
- ++start_idx;
- }
+void StackFrameList::InvalidateFrames(uint32_t start_idx) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (m_show_inlined_frames) {
+ Clear();
+ } else {
+ const size_t num_frames = m_frames.size();
+ while (start_idx < num_frames) {
+ m_frames[start_idx].reset();
+ ++start_idx;
}
+ }
}
-void
-StackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
-{
- std::unique_lock<std::recursive_mutex> current_lock, previous_lock;
- if (curr_ap)
- current_lock = std::unique_lock<std::recursive_mutex>(curr_ap->m_mutex);
- if (prev_sp)
- previous_lock = std::unique_lock<std::recursive_mutex>(prev_sp->m_mutex);
-
-#if defined (DEBUG_STACK_FRAMES)
- StreamFile s(stdout, false);
- s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n");
- if (prev_sp)
- prev_sp->Dump (&s);
- else
- s.PutCString ("NULL");
- s.PutCString("\nCurr:\n");
- if (curr_ap)
- curr_ap->Dump (&s);
- else
- s.PutCString ("NULL");
- s.EOL();
+void StackFrameList::Merge(std::unique_ptr<StackFrameList> &curr_ap,
+ lldb::StackFrameListSP &prev_sp) {
+ std::unique_lock<std::recursive_mutex> current_lock, previous_lock;
+ if (curr_ap)
+ current_lock = std::unique_lock<std::recursive_mutex>(curr_ap->m_mutex);
+ if (prev_sp)
+ previous_lock = std::unique_lock<std::recursive_mutex>(prev_sp->m_mutex);
+
+#if defined(DEBUG_STACK_FRAMES)
+ StreamFile s(stdout, false);
+ s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n");
+ if (prev_sp)
+ prev_sp->Dump(&s);
+ else
+ s.PutCString("NULL");
+ s.PutCString("\nCurr:\n");
+ if (curr_ap)
+ curr_ap->Dump(&s);
+ else
+ s.PutCString("NULL");
+ s.EOL();
#endif
- if (!curr_ap || curr_ap->GetNumFrames(false) == 0)
- {
-#if defined (DEBUG_STACK_FRAMES)
- s.PutCString("No current frames, leave previous frames alone...\n");
+ if (!curr_ap || curr_ap->GetNumFrames(false) == 0) {
+#if defined(DEBUG_STACK_FRAMES)
+ s.PutCString("No current frames, leave previous frames alone...\n");
#endif
- curr_ap.release();
- return;
- }
+ curr_ap.release();
+ return;
+ }
- if (!prev_sp || prev_sp->GetNumFrames(false) == 0)
- {
-#if defined (DEBUG_STACK_FRAMES)
- s.PutCString("No previous frames, so use current frames...\n");
+ if (!prev_sp || prev_sp->GetNumFrames(false) == 0) {
+#if defined(DEBUG_STACK_FRAMES)
+ s.PutCString("No previous frames, so use current frames...\n");
#endif
- // We either don't have any previous frames, or since we have more than
- // one current frames it means we have all the frames and can safely
- // replace our previous frames.
- prev_sp.reset (curr_ap.release());
- return;
- }
-
- const uint32_t num_curr_frames = curr_ap->GetNumFrames (false);
-
- if (num_curr_frames > 1)
- {
-#if defined (DEBUG_STACK_FRAMES)
- s.PutCString("We have more than one current frame, so use current frames...\n");
+ // We either don't have any previous frames, or since we have more than
+ // one current frames it means we have all the frames and can safely
+ // replace our previous frames.
+ prev_sp.reset(curr_ap.release());
+ return;
+ }
+
+ const uint32_t num_curr_frames = curr_ap->GetNumFrames(false);
+
+ if (num_curr_frames > 1) {
+#if defined(DEBUG_STACK_FRAMES)
+ s.PutCString(
+ "We have more than one current frame, so use current frames...\n");
#endif
- // We have more than one current frames it means we have all the frames
- // and can safely replace our previous frames.
- prev_sp.reset (curr_ap.release());
+ // We have more than one current frames it means we have all the frames
+ // and can safely replace our previous frames.
+ prev_sp.reset(curr_ap.release());
-#if defined (DEBUG_STACK_FRAMES)
- s.PutCString("\nMerged:\n");
- prev_sp->Dump (&s);
+#if defined(DEBUG_STACK_FRAMES)
+ s.PutCString("\nMerged:\n");
+ prev_sp->Dump(&s);
#endif
- return;
- }
+ return;
+ }
- StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex (0));
- StackFrameSP curr_frame_zero_sp(curr_ap->GetFrameAtIndex (0));
- StackID curr_stack_id (curr_frame_zero_sp->GetStackID());
- StackID prev_stack_id (prev_frame_zero_sp->GetStackID());
+ StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex(0));
+ StackFrameSP curr_frame_zero_sp(curr_ap->GetFrameAtIndex(0));
+ StackID curr_stack_id(curr_frame_zero_sp->GetStackID());
+ StackID prev_stack_id(prev_frame_zero_sp->GetStackID());
-#if defined (DEBUG_STACK_FRAMES)
- const uint32_t num_prev_frames = prev_sp->GetNumFrames (false);
- s.Printf("\n%u previous frames with one current frame\n", num_prev_frames);
+#if defined(DEBUG_STACK_FRAMES)
+ const uint32_t num_prev_frames = prev_sp->GetNumFrames(false);
+ s.Printf("\n%u previous frames with one current frame\n", num_prev_frames);
#endif
- // We have only a single current frame
- // Our previous stack frames only had a single frame as well...
- if (curr_stack_id == prev_stack_id)
- {
-#if defined (DEBUG_STACK_FRAMES)
- s.Printf("\nPrevious frame #0 is same as current frame #0, merge the cached data\n");
+ // We have only a single current frame
+ // Our previous stack frames only had a single frame as well...
+ if (curr_stack_id == prev_stack_id) {
+#if defined(DEBUG_STACK_FRAMES)
+ s.Printf("\nPrevious frame #0 is same as current frame #0, merge the "
+ "cached data\n");
#endif
- curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame (*prev_frame_zero_sp);
-// prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame (*curr_frame_zero_sp);
-// prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp);
- }
- else if (curr_stack_id < prev_stack_id)
- {
-#if defined (DEBUG_STACK_FRAMES)
- s.Printf("\nCurrent frame #0 has a stack ID that is less than the previous frame #0, insert current frame zero in front of previous\n");
+ curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame(
+ *prev_frame_zero_sp);
+ // prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame
+ // (*curr_frame_zero_sp);
+ // prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp);
+ } else if (curr_stack_id < prev_stack_id) {
+#if defined(DEBUG_STACK_FRAMES)
+ s.Printf("\nCurrent frame #0 has a stack ID that is less than the previous "
+ "frame #0, insert current frame zero in front of previous\n");
#endif
- prev_sp->m_frames.insert (prev_sp->m_frames.begin(), curr_frame_zero_sp);
- }
-
- curr_ap.release();
+ prev_sp->m_frames.insert(prev_sp->m_frames.begin(), curr_frame_zero_sp);
+ }
-#if defined (DEBUG_STACK_FRAMES)
- s.PutCString("\nMerged:\n");
- prev_sp->Dump (&s);
+ curr_ap.release();
+
+#if defined(DEBUG_STACK_FRAMES)
+ s.PutCString("\nMerged:\n");
+ prev_sp->Dump(&s);
#endif
}
lldb::StackFrameSP
-StackFrameList::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)
-{
- const_iterator pos;
- const_iterator begin = m_frames.begin();
- const_iterator end = m_frames.end();
- lldb::StackFrameSP ret_sp;
-
- for (pos = begin; pos != end; ++pos)
- {
- if (pos->get() == stack_frame_ptr)
- {
- ret_sp = (*pos);
- break;
- }
+StackFrameList::GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr) {
+ const_iterator pos;
+ const_iterator begin = m_frames.begin();
+ const_iterator end = m_frames.end();
+ lldb::StackFrameSP ret_sp;
+
+ for (pos = begin; pos != end; ++pos) {
+ if (pos->get() == stack_frame_ptr) {
+ ret_sp = (*pos);
+ break;
}
- return ret_sp;
+ }
+ return ret_sp;
}
-size_t
-StackFrameList::GetStatus (Stream& strm,
- uint32_t first_frame,
- uint32_t num_frames,
- bool show_frame_info,
- uint32_t num_frames_with_source,
- const char *selected_frame_marker)
-{
- size_t num_frames_displayed = 0;
-
- if (num_frames == 0)
- return 0;
-
- StackFrameSP frame_sp;
- uint32_t frame_idx = 0;
- uint32_t last_frame;
-
- // Don't let the last frame wrap around...
- if (num_frames == UINT32_MAX)
- last_frame = UINT32_MAX;
- else
- last_frame = first_frame + num_frames;
-
- StackFrameSP selected_frame_sp = m_thread.GetSelectedFrame();
- const char *unselected_marker = nullptr;
- std::string buffer;
- if (selected_frame_marker)
- {
- size_t len = strlen(selected_frame_marker);
- buffer.insert(buffer.begin(), len, ' ');
- unselected_marker = buffer.c_str();
+size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame,
+ uint32_t num_frames, bool show_frame_info,
+ uint32_t num_frames_with_source,
+ const char *selected_frame_marker) {
+ size_t num_frames_displayed = 0;
+
+ if (num_frames == 0)
+ return 0;
+
+ StackFrameSP frame_sp;
+ uint32_t frame_idx = 0;
+ uint32_t last_frame;
+
+ // Don't let the last frame wrap around...
+ if (num_frames == UINT32_MAX)
+ last_frame = UINT32_MAX;
+ else
+ last_frame = first_frame + num_frames;
+
+ StackFrameSP selected_frame_sp = m_thread.GetSelectedFrame();
+ const char *unselected_marker = nullptr;
+ std::string buffer;
+ if (selected_frame_marker) {
+ size_t len = strlen(selected_frame_marker);
+ buffer.insert(buffer.begin(), len, ' ');
+ unselected_marker = buffer.c_str();
+ }
+ const char *marker = nullptr;
+
+ for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx) {
+ frame_sp = GetFrameAtIndex(frame_idx);
+ if (!frame_sp)
+ break;
+
+ if (selected_frame_marker != nullptr) {
+ if (frame_sp == selected_frame_sp)
+ marker = selected_frame_marker;
+ else
+ marker = unselected_marker;
}
- const char *marker = nullptr;
-
- for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx)
- {
- frame_sp = GetFrameAtIndex(frame_idx);
- if (!frame_sp)
- break;
-
- if (selected_frame_marker != nullptr)
- {
- if (frame_sp == selected_frame_sp)
- marker = selected_frame_marker;
- else
- marker = unselected_marker;
- }
-
- if (!frame_sp->GetStatus (strm,
- show_frame_info,
- num_frames_with_source > (first_frame - frame_idx), marker))
- break;
- ++num_frames_displayed;
- }
-
- strm.IndentLess();
- return num_frames_displayed;
+
+ if (!frame_sp->GetStatus(strm, show_frame_info,
+ num_frames_with_source > (first_frame - frame_idx),
+ marker))
+ break;
+ ++num_frames_displayed;
+ }
+
+ strm.IndentLess();
+ return num_frames_displayed;
}
OpenPOWER on IntegriCloud