diff options
author | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
commit | 60b571e49a90d38697b3aca23020d9da42fc7d7f (patch) | |
tree | 99351324c24d6cb146b6285b6caffa4d26fce188 /contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp | |
parent | bea1b22c7a9bce1dfdd73e6e5b65bc4752215180 (diff) | |
download | FreeBSD-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.cpp | 1521 |
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; } |