summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2012-02-29 03:40:22 +0000
committerJim Ingham <jingham@apple.com>2012-02-29 03:40:22 +0000
commitb0c72a5f584de8334f0af10e48ba687fc6e8ae70 (patch)
tree981c2805d85d318478a95bd27c4f54b8e4666a5a /lldb/source/Plugins/Process
parent7bc0ec3aad663a2c81fddf9da38dba46bba6be19 (diff)
downloadbcm5719-llvm-b0c72a5f584de8334f0af10e48ba687fc6e8ae70.tar.gz
bcm5719-llvm-b0c72a5f584de8334f0af10e48ba687fc6e8ae70.zip
Make the StackFrameList::GetFrameAtIndex only fetch as many stack frames as needed to
get the frame requested. <rdar://problem/10943135> llvm-svn: 151705
Diffstat (limited to 'lldb/source/Plugins/Process')
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp43
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.h5
2 files changed, 34 insertions, 14 deletions
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 2633542f4e1..b993c95325c 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -25,14 +25,15 @@ using namespace lldb_private;
UnwindLLDB::UnwindLLDB (Thread &thread) :
Unwind (thread),
- m_frames()
+ m_frames(),
+ m_unwind_complete(false)
{
}
uint32_t
UnwindLLDB::DoGetFrameCount()
{
- if (m_frames.empty())
+ if (!m_unwind_complete)
{
//#define DEBUG_FRAME_SPEED 1
#if DEBUG_FRAME_SPEED
@@ -68,6 +69,9 @@ UnwindLLDB::DoGetFrameCount()
bool
UnwindLLDB::AddFirstFrame ()
{
+ if (m_frames.size() > 0)
+ return true;
+
// First, set up the 0th (initial) frame
CursorSP first_cursor_sp(new Cursor ());
RegisterContextLLDBSP reg_ctx_sp (new RegisterContextLLDB (m_thread,
@@ -75,28 +79,35 @@ UnwindLLDB::AddFirstFrame ()
first_cursor_sp->sctx,
0, *this));
if (reg_ctx_sp.get() == NULL)
- return false;
+ goto unwind_done;
if (!reg_ctx_sp->IsValid())
- return false;
+ goto unwind_done;
if (!reg_ctx_sp->GetCFA (first_cursor_sp->cfa))
- return false;
+ goto unwind_done;
if (!reg_ctx_sp->ReadPC (first_cursor_sp->start_pc))
- return false;
+ goto unwind_done;
// Everything checks out, so release the auto pointer value and let the
// cursor own it in its shared pointer
first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
m_frames.push_back (first_cursor_sp);
return true;
+unwind_done:
+ m_unwind_complete = true;
+ return false;
}
// For adding a non-zero stack frame to m_frames.
bool
UnwindLLDB::AddOneMoreFrame (ABI *abi)
{
+ // If we've already gotten to the end of the stack, don't bother to try again...
+ if (m_unwind_complete)
+ return false;
+
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
CursorSP cursor_sp(new Cursor ());
@@ -111,7 +122,7 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
cur_idx,
*this));
if (reg_ctx_sp.get() == NULL)
- return false;
+ goto unwind_done;
if (!reg_ctx_sp->IsValid())
{
@@ -120,7 +131,7 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk",
cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
- return false;
+ goto unwind_done;
}
if (!reg_ctx_sp->GetCFA (cursor_sp->cfa))
{
@@ -129,7 +140,7 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
- return false;
+ goto unwind_done;
}
if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa))
{
@@ -138,7 +149,7 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
- return false;
+ goto unwind_done;
}
if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc))
{
@@ -147,7 +158,7 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
- return false;
+ goto unwind_done;
}
if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc))
{
@@ -156,26 +167,30 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
- return false;
+ goto unwind_done;
}
if (!m_frames.empty())
{
if (m_frames.back()->start_pc == cursor_sp->start_pc)
{
if (m_frames.back()->cfa == cursor_sp->cfa)
- return false; // Infinite loop where the current cursor is the same as the previous one...
+ goto unwind_done; // Infinite loop where the current cursor is the same as the previous one...
else if (abi->StackUsesFrames())
{
// We might have a CFA that is not using the frame pointer and
// we want to validate that the frame pointer is valid.
if (reg_ctx_sp->GetFP() == 0)
- return false;
+ goto unwind_done;
}
}
}
cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
m_frames.push_back (cursor_sp);
return true;
+
+unwind_done:
+ m_unwind_complete = true;
+ return false;
}
bool
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
index b9352b61b8b..ff4030f6364 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -56,6 +56,7 @@ protected:
DoClear()
{
m_frames.clear();
+ m_unwind_complete = false;
}
virtual uint32_t
@@ -98,6 +99,10 @@ private:
typedef SHARED_PTR(Cursor) CursorSP;
std::vector<CursorSP> m_frames;
+ bool m_unwind_complete; // If this is true, we've enumerated all the frames in the stack, and m_frames.size() is the
+ // number of frames, etc. Otherwise we've only gone as far as directly asked, and m_frames.size()
+ // is how far we've currently gone.
+
bool AddOneMoreFrame (ABI *abi);
bool AddFirstFrame ();
OpenPOWER on IntegriCloud