//===-- 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/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#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"
#include "lldb/Utility/Log.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(), AddressClass::eCode);
            curr_frame_address.SetOpcodeLoadAddress(
                load_addr - 1, target_sp.get(), AddressClass::eCode);
          } 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...
      assert(!m_thread.IsValid() && "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,
                                 bool show_unique,
                                 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),
                             show_unique, marker))
      break;
    ++num_frames_displayed;
  }

  strm.IndentLess();
  return num_frames_displayed;
}
