//===-- 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/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/Log.h"
#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/StopInfo.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_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;
    }
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
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();
    }
}

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 ()
{
    Mutex::Locker locker (m_mutex);

    if (m_show_inlined_frames)
    {        
        GetFramesUpTo(0);
        if (m_frames.size() == 0)
            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;
                                    }
                                }
                            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 != NULL;
                                              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;
            }
        }
    }
    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::GetFramesUpTo(uint32_t end_idx)
{
    // this makes sure we do not fetch frames for an invalid thread
    if (m_thread.IsValid() == false)
        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;
            }
        }
        
        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,
                                                               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 && 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, NULL));
                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());
                // 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.
                        TargetSP target = m_thread.CalculateTarget();
                        addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress(target.get(), eAddressClassCode);
                        curr_frame_address.SetOpcodeLoadAddress(load_addr - 1, target.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))
                {
                        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");
#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;

        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)
{
    Mutex::Locker locker (m_mutex);

    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;
}

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: ", 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;
    Mutex::Locker locker (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, 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);
                }
            }
        }
    }
    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.size() > 0)
        {
            ResetCurrentInlinedDepth();
            frame_sp = m_frames[original_idx];
        }
        else
        {
            // 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.");
            
        }
    }
    
    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;
}

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())
    {
        Mutex::Locker locker (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);
    }
    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);
            uint32_t inlined_depth = GetCurrentInlinedDepth();
            if (inlined_depth != UINT32_MAX)
                m_selected_frame_idx -= inlined_depth;
            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::unique_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
{
    Mutex::Locker curr_locker (curr_ap.get() ? &curr_ap->m_mutex : NULL);
    Mutex::Locker prev_locker (prev_sp.get() ? &prev_sp->m_mutex : 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,
                           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 = NULL;
    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 = NULL;
    
    for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx)
    {
        frame_sp = GetFrameAtIndex(frame_idx);
        if (frame_sp.get() == NULL)
            break;
        
        if (selected_frame_marker != NULL)
        {
            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;
}

