summaryrefslogtreecommitdiff
path: root/lldb/source/Target/StackFrameList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/StackFrameList.cpp')
-rw-r--r--lldb/source/Target/StackFrameList.cpp627
1 files changed, 0 insertions, 627 deletions
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp
deleted file mode 100644
index 3c580bca0d41..000000000000
--- a/lldb/source/Target/StackFrameList.cpp
+++ /dev/null
@@ -1,627 +0,0 @@
-//===-- StackFrameList.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Target/StackFrameList.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/StreamFile.h"
-#include "lldb/Core/SourceManager.h"
-#include "lldb/Symbol/Block.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/Symbol.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/Unwind.h"
-
-//#define DEBUG_STACK_FRAMES 1
-
-using namespace lldb;
-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 (Mutex::eMutexTypeRecursive),
- m_frames (),
- m_selected_frame_idx (0),
- m_concrete_frames_fetched (0),
- m_show_inlined_frames (show_inline_frames)
-{
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-StackFrameList::~StackFrameList()
-{
-}
-
-void
-StackFrameList::GetFramesUpTo(uint32_t end_idx)
-{
- // 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
-
- StackFrameSP unwind_frame_sp;
- do
- {
- uint32_t idx = m_concrete_frames_fetched++;
- lldb::addr_t pc;
- lldb::addr_t cfa;
- if (idx == 0)
- {
- // We might have already created frame zero, only create it
- // if we need to
- if (m_frames.empty())
- {
- m_thread.GetRegisterContext();
- assert (m_thread.m_reg_context_sp.get());
-
- const bool success = 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 = m_thread.GetRegisterContext()->GetSP();
- pc = m_thread.GetRegisterContext()->GetPC();
- }
-
- unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(),
- m_frames.size(),
- idx,
- m_thread.m_reg_context_sp,
- cfa,
- pc,
- NULL));
- 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->GetFrameInfoAtIndex(idx, cfa, pc);
- if (!success)
- {
- // We've gotten to the end of the stack.
- SetAllFramesFetched();
- break;
- }
- unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(), m_frames.size(), idx, cfa, pc, NULL));
- m_frames.push_back (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());
- // 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)
- 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))
- {
- 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;
-
-#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");
-#endif
-
- StackFrame *curr_frame = curr_frame_sp.get();
- StackFrame *prev_frame = prev_frame_sp.get();
-
- if (curr_frame == NULL || prev_frame == NULL)
- break;
-
- // 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();
- }
-
-#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;
-
- 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)
-{
- Mutex::Locker locker (m_mutex);
-
- if (can_create)
- GetFramesUpTo (UINT32_MAX);
- return m_frames.size();
-}
-
-void
-StackFrameList::Dump (Stream *s)
-{
- if (s == NULL)
- return;
- Mutex::Locker locker (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: ", 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;
- Mutex::Locker locker (m_mutex);
- 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))
- {
- frame_sp.reset (new StackFrame (m_thread.shared_from_this(), idx, idx, cfa, pc, NULL));
-
- 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 NULL or valid.
- frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
- }
- SetFrameAtIndex(idx, 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;
-}
-
-StackFrameSP
-StackFrameList::GetFrameWithStackID (const StackID &stack_id)
-{
- uint32_t frame_idx = 0;
- StackFrameSP 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?
-}
-
-uint32_t
-StackFrameList::GetSelectedFrameIndex () const
-{
- Mutex::Locker locker (m_mutex);
- return m_selected_frame_idx;
-}
-
-
-uint32_t
-StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame)
-{
- Mutex::Locker locker (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);
- break;
- }
- }
- SetDefaultFileAndLineToSelectedFrame();
- return m_selected_frame_idx;
-}
-
-// Mark a stack frame as the current frame using the frame index
-bool
-StackFrameList::SetSelectedFrameByIndex (uint32_t idx)
-{
- Mutex::Locker locker (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);
- }
- }
-}
-
-// 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 ()
-{
- Mutex::Locker locker (m_mutex);
- m_frames.clear();
- m_concrete_frames_fetched = 0;
-}
-
-void
-StackFrameList::InvalidateFrames (uint32_t start_idx)
-{
- Mutex::Locker locker (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::auto_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
-{
- Mutex::Locker curr_locker (curr_ap.get() ? curr_ap->m_mutex.GetMutex() : NULL);
- Mutex::Locker prev_locker (prev_sp.get() ? prev_sp->m_mutex.GetMutex() : NULL);
-
-#if defined (DEBUG_STACK_FRAMES)
- StreamFile s(stdout, false);
- s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n");
- if (prev_sp.get())
- prev_sp->Dump (&s);
- else
- s.PutCString ("NULL");
- s.PutCString("\nCurr:\n");
- if (curr_ap.get())
- curr_ap->Dump (&s);
- else
- s.PutCString ("NULL");
- s.EOL();
-#endif
-
- if (curr_ap.get() == NULL || 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;
- }
-
- if (prev_sp.get() == NULL || 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");
-#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());
-
-#if defined (DEBUG_STACK_FRAMES)
- s.PutCString("\nMerged:\n");
- prev_sp->Dump (&s);
-#endif
- 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());
-
-#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");
-#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");
-#endif
- prev_sp->m_frames.insert (prev_sp->m_frames.begin(), curr_frame_zero_sp);
- }
-
- 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;
- }
- }
- 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,
- uint32_t source_lines_before,
- uint32_t source_lines_after)
-{
- 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;
-
- for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx)
- {
- frame_sp = GetFrameAtIndex(frame_idx);
- if (frame_sp.get() == NULL)
- break;
-
- if (!frame_sp->GetStatus (strm,
- show_frame_info,
- num_frames_with_source > first_frame - frame_idx,
- source_lines_before,
- source_lines_after))
- break;
- ++num_frames_displayed;
- }
-
- strm.IndentLess();
- return num_frames_displayed;
-}
-