//===-- StackFrameList.cpp --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Target/StackFrameList.h"
#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(),
      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;
    }
}

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 ()
{
    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;
            }
        }
    }
    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())
        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,
                                                             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();
#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 == nullptr || prev_frame == nullptr)
                    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)
{
    std::lock_guard<std::recursive_mutex> guard(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 == 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);
                }
            }
        }
    }
    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];
        }
    }
    
    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())
    {
        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);
    }
    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
{
    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;
        }
    }
    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;
}

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::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();
#endif

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

    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");
#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 = 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;
        }
        
        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;
}
