124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- StackFrameList.cpp --------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton#include "lldb/Target/StackFrameList.h"
11782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes
1664a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham#include "lldb/Breakpoint/BreakpointLocation.h"
1764a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham#include "lldb/Breakpoint/Breakpoint.h"
189b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham#include "lldb/Core/Log.h"
191d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton#include "lldb/Core/StreamFile.h"
20fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham#include "lldb/Core/SourceManager.h"
21782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton#include "lldb/Symbol/Block.h"
22782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton#include "lldb/Symbol/Function.h"
234fb08150367853dae24bb92904356788e919a72fGreg Clayton#include "lldb/Symbol/Symbol.h"
24fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham#include "lldb/Target/Process.h"
25782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton#include "lldb/Target/RegisterContext.h"
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/StackFrame.h"
270c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham#include "lldb/Target/StopInfo.h"
28fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham#include "lldb/Target/Target.h"
29782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton#include "lldb/Target/Thread.h"
30782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton#include "lldb/Target/Unwind.h"
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
321d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton//#define DEBUG_STACK_FRAMES 1
331d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// StackFrameList constructor
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
405205f0b6585a127acc6ed210021abb6091220a89Greg ClaytonStackFrameList::StackFrameList
415205f0b6585a127acc6ed210021abb6091220a89Greg Clayton(
425205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    Thread &thread,
435205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    const lldb::StackFrameListSP &prev_frames_sp,
445205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    bool show_inline_frames
455205f0b6585a127acc6ed210021abb6091220a89Greg Clayton) :
46782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    m_thread (thread),
475205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    m_prev_frames_sp (prev_frames_sp),
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_mutex (Mutex::eMutexTypeRecursive),
491d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    m_frames (),
50dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson    m_selected_frame_idx (0),
51bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    m_concrete_frames_fetched (0),
520c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    m_current_inlined_depth (UINT32_MAX),
530c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    m_current_inlined_pc (LLDB_INVALID_ADDRESS),
54dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson    m_show_inlined_frames (show_inline_frames)
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
560c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    if (prev_frames_sp)
570c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    {
580c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        m_current_inlined_depth = prev_frames_sp->m_current_inlined_depth;
590c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        m_current_inlined_pc =    prev_frames_sp->m_current_inlined_pc;
600c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    }
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Destructor
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerStackFrameList::~StackFrameList()
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
68226484d8533b19c9a63e5df20d30c37075e51f03Greg Clayton    // Call clear since this takes a lock and clears the stack frame list
69226484d8533b19c9a63e5df20d30c37075e51f03Greg Clayton    // in case another thread is currently using this stack frame list
70226484d8533b19c9a63e5df20d30c37075e51f03Greg Clayton    Clear();
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
73bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Inghamvoid
740c8fa2d7dd18ae1816c82846234c45f79142e3dfJim InghamStackFrameList::CalculateCurrentInlinedDepth()
750c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham{
760c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    uint32_t cur_inlined_depth = GetCurrentInlinedDepth();
770c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    if (cur_inlined_depth == UINT32_MAX)
780c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    {
790c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        ResetCurrentInlinedDepth();
800c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    }
810c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham}
820c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
830c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Inghamuint32_t
840c8fa2d7dd18ae1816c82846234c45f79142e3dfJim InghamStackFrameList::GetCurrentInlinedDepth ()
850c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham{
869b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham    if (m_show_inlined_frames && m_current_inlined_pc != LLDB_INVALID_ADDRESS)
870c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    {
880c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC();
890c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        if (cur_pc != m_current_inlined_pc)
900c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        {
910c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            m_current_inlined_pc = LLDB_INVALID_ADDRESS;
920c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            m_current_inlined_depth = UINT32_MAX;
93952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
949b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham            if (log && log->GetVerbose())
959b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham                log->Printf ("GetCurrentInlinedDepth: invalidating current inlined depth.\n");
960c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        }
970c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        return m_current_inlined_depth;
980c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    }
990c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    else
1000c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    {
1010c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        return UINT32_MAX;
1020c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    }
1030c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham}
1040c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
1050c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Inghamvoid
1060c8fa2d7dd18ae1816c82846234c45f79142e3dfJim InghamStackFrameList::ResetCurrentInlinedDepth ()
1070c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham{
1081cc0c05acc4e6f4e95f74c3e4eb1c8847bda4a76Jim Ingham    if (m_show_inlined_frames)
1090c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    {
1100c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        GetFramesUpTo(0);
1110c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        if (!m_frames[0]->IsInlined())
1120c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        {
1130c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            m_current_inlined_depth = UINT32_MAX;
1140c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            m_current_inlined_pc = LLDB_INVALID_ADDRESS;
115952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
1169b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham            if (log && log->GetVerbose())
1179b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham                log->Printf ("ResetCurrentInlinedDepth: Invalidating current inlined depth.\n");
1180c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        }
1190c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        else
1200c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        {
1210c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            // We only need to do something special about inlined blocks when we
1220c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            // are at the beginning of an inlined function:
1230c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            // FIXME: We probably also have to do something special if the PC is at the END
1240c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            // of an inlined function, which coincides with the end of either its containing
1250c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            // function or another inlined function.
1260c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
1270c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
1280c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            Block *block_ptr = m_frames[0]->GetFrameBlock();
1290c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            if (block_ptr)
1300c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            {
1310c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                Address pc_as_address;
1320c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                pc_as_address.SetLoadAddress(curr_pc, &(m_thread.GetProcess()->GetTarget()));
1330c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                AddressRange containing_range;
1340c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                if (block_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
1350c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                {
1360c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                    if (pc_as_address == containing_range.GetBaseAddress())
1370c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                    {
1380c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        // If we got here because of a breakpoint hit, then set the inlined depth depending on where
1390c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        // the breakpoint was set.
1400c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        // If we got here because of a crash, then set the inlined depth to the deepest most block.
1410c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        // Otherwise, we stopped here naturally as the result of a step, so set ourselves in the
1420c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        // containing frame of the whole set of nested inlines, so the user can then "virtually"
1430c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        // step into the frames one by one, or next over the whole mess.
1440c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        // Note: We don't have to handle being somewhere in the middle of the stack here, since
1450c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        // ResetCurrentInlinedDepth doesn't get called if there is a valid inlined depth set.
1460c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        StopInfoSP stop_info_sp = m_thread.GetStopInfo();
1470c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        if (stop_info_sp)
1480c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        {
1490c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                            switch (stop_info_sp->GetStopReason())
1500c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                            {
1510c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                            case eStopReasonWatchpoint:
1520c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                            case eStopReasonException:
1530bce9a22354df3f00e68ffd912119a0741753b7fGreg Clayton                            case eStopReasonExec:
1540c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                            case eStopReasonSignal:
1550c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                // In all these cases we want to stop in the deepest most frame.
1560c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                m_current_inlined_pc = curr_pc;
1570c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                m_current_inlined_depth = 0;
1580c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                break;
15974d08f1ea720cda87abcc09d6036785a96926ef3Jim Ingham                            case eStopReasonBreakpoint:
16074d08f1ea720cda87abcc09d6036785a96926ef3Jim Ingham                                {
16174d08f1ea720cda87abcc09d6036785a96926ef3Jim Ingham                                    // FIXME: Figure out what this break point is doing, and set the inline depth
16274d08f1ea720cda87abcc09d6036785a96926ef3Jim Ingham                                    // appropriately.  Be careful to take into account breakpoints that implement
16374d08f1ea720cda87abcc09d6036785a96926ef3Jim Ingham                                    // step over prologue, since that should do the default calculation.
16464a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    // For now, if the breakpoints corresponding to this hit are all internal,
16564a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    // I set the stop location to the top of the inlined stack, since that will make
16664a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    // things like stepping over prologues work right.  But if there are any non-internal
16764a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    // breakpoints I do to the bottom of the stack, since that was the old behavior.
16864a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    uint32_t bp_site_id = stop_info_sp->GetValue();
16964a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    BreakpointSiteSP bp_site_sp(m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id));
17064a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    bool all_internal = true;
17164a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    if (bp_site_sp)
17264a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    {
17364a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                        uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
17464a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                        for (uint32_t i = 0; i < num_owners; i++)
17564a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                        {
17664a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                            Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
17764a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                            if (!bp_ref.IsInternal())
17864a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                            {
17964a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                                all_internal = false;
18064a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                            }
18164a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                        }
18264a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    }
18364a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    if (!all_internal)
18464a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    {
18564a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                        m_current_inlined_pc = curr_pc;
18664a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                        m_current_inlined_depth = 0;
18764a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                        break;
18864a41e221e3a47799ff3ea5eddacb58e86d74be1Jim Ingham                                    }
18974d08f1ea720cda87abcc09d6036785a96926ef3Jim Ingham                                }
1900c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                            default:
1910c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                {
1920c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                    // Otherwise, we should set ourselves at the container of the inlining, so that the
1930c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                    // user can descend into them.
1940c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                    // So first we check whether we have more than one inlined block sharing this PC:
1950c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                    int num_inlined_functions = 0;
1960c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
1970c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                    for  (Block *container_ptr = block_ptr->GetInlinedParent();
1980c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                              container_ptr != NULL;
1990c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                              container_ptr = container_ptr->GetInlinedParent())
2000c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                    {
2010c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                        if (!container_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
2020c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                            break;
2030c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                        if (pc_as_address != containing_range.GetBaseAddress())
2040c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                            break;
2050c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
2060c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                        num_inlined_functions++;
2070c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                    }
2080c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                    m_current_inlined_pc = curr_pc;
2090c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                    m_current_inlined_depth = num_inlined_functions + 1;
210952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton                                    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2119b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham                                    if (log && log->GetVerbose())
2125f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                                        log->Printf ("ResetCurrentInlinedDepth: setting inlined depth: %d 0x%" PRIx64 ".\n", m_current_inlined_depth, curr_pc);
2130c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
2140c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                }
2150c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                                break;
2160c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                            }
2170c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                        }
2180c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                    }
2190c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                }
2200c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            }
2210c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        }
2220c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    }
2230c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham}
2240c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
2250c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Inghambool
2260c8fa2d7dd18ae1816c82846234c45f79142e3dfJim InghamStackFrameList::DecrementCurrentInlinedDepth ()
2270c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham{
2280c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    if (m_show_inlined_frames)
2290c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    {
2300c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        uint32_t current_inlined_depth = GetCurrentInlinedDepth();
2310c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        if (current_inlined_depth != UINT32_MAX)
2320c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        {
2330c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            if (current_inlined_depth > 0)
2341949b1e8eb944bcaf56fdbee52ed9b226b4bc8e5Jim Ingham            {
2350c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                m_current_inlined_depth--;
2361949b1e8eb944bcaf56fdbee52ed9b226b4bc8e5Jim Ingham                return true;
2371949b1e8eb944bcaf56fdbee52ed9b226b4bc8e5Jim Ingham            }
2380c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        }
2390c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    }
2400c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    return false;
2410c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham}
2420c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
2430c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Inghamvoid
2449b124c6bc79c0f650ac52d65d6366f45f30ee31dJim InghamStackFrameList::SetCurrentInlinedDepth (uint32_t new_depth)
2459b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham{
2469b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham    m_current_inlined_depth = new_depth;
2479b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham    if (new_depth == UINT32_MAX)
2489b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham        m_current_inlined_pc = LLDB_INVALID_ADDRESS;
2499b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham    else
2509b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham        m_current_inlined_pc = m_thread.GetRegisterContext()->GetPC();
2519b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham}
2529b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham
2539b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Inghamvoid
254bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim InghamStackFrameList::GetFramesUpTo(uint32_t end_idx)
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
25641b5bfe52dbe9dce14bc655d6d786c5c05f08018Enrico Granata    // this makes sure we do not fetch frames for an invalid thread
25741b5bfe52dbe9dce14bc655d6d786c5c05f08018Enrico Granata    if (m_thread.IsValid() == false)
25841b5bfe52dbe9dce14bc655d6d786c5c05f08018Enrico Granata        return;
25941b5bfe52dbe9dce14bc655d6d786c5c05f08018Enrico Granata
260bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    // We've already gotten more frames than asked for, or we've already finished unwinding, return.
261bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    if (m_frames.size() > end_idx || GetAllFramesFetched())
262bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        return;
263bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
264bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    Unwind *unwinder = m_thread.GetUnwinder ();
265782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton
266bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    if (m_show_inlined_frames)
267782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    {
2681d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton#if defined (DEBUG_STACK_FRAMES)
269bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        StreamFile s(stdout, false);
2701d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton#endif
2710c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        // If we are hiding some frames from the outside world, we need to add those onto the total count of
2720c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        // frames to fetch.  However, we don't need ot do that if end_idx is 0 since in that case we always
2739b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham        // get the first concrete frame and all the inlined frames below it...  And of course, if end_idx is
2749b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham        // UINT32_MAX that means get all, so just do that...
2750c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
2760c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        uint32_t inlined_depth = 0;
2779b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham        if (end_idx > 0 && end_idx != UINT32_MAX)
2780c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        {
2790c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            inlined_depth = GetCurrentInlinedDepth();
2800c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            if (inlined_depth != UINT32_MAX)
2810c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            {
2820c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                if (end_idx > 0)
2830c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                    end_idx += inlined_depth;
2840c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            }
2850c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        }
286bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
287bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        StackFrameSP unwind_frame_sp;
288bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        do
289bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        {
290bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            uint32_t idx = m_concrete_frames_fetched++;
291bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            lldb::addr_t pc;
292bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            lldb::addr_t cfa;
293bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            if (idx == 0)
294782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton            {
295bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // We might have already created frame zero, only create it
296bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // if we need to
297bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                if (m_frames.empty())
298782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton                {
2999acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                    RegisterContextSP reg_ctx_sp (m_thread.GetRegisterContext());
3009acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton
3019acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                    if (reg_ctx_sp)
3026252ea842062c39198558c949d5e09f10422683aJim Ingham                    {
3039acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton
3049acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                        const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
3059acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                        // There shouldn't be any way not to get the frame info for frame 0.
3069acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                        // But if the unwinder can't make one, lets make one by hand with the
3079acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                        // SP as the CFA and see if that gets any further.
3089acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                        if (!success)
3099acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                        {
3109acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                            cfa = reg_ctx_sp->GetSP();
3119acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                            pc = reg_ctx_sp->GetPC();
3129acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                        }
3139acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton
3149acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                        unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(),
3159acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                                                               m_frames.size(),
3169acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                                                               idx,
3179acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                                                               reg_ctx_sp,
3189acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                                                               cfa,
3199acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                                                               pc,
3209acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                                                               NULL));
3219acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton                        m_frames.push_back (unwind_frame_sp);
3226252ea842062c39198558c949d5e09f10422683aJim Ingham                    }
323782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton                }
324782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton                else
325782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton                {
326bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    unwind_frame_sp = m_frames.front();
327bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    cfa = unwind_frame_sp->m_id.GetCallFrameAddress();
328782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton                }
329bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            }
330bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            else
331bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            {
332bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
333bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                if (!success)
334782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton                {
335bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    // We've gotten to the end of the stack.
336bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    SetAllFramesFetched();
337bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    break;
338bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                }
339bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(), m_frames.size(), idx, cfa, pc, NULL));
340bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                m_frames.push_back (unwind_frame_sp);
341bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            }
342bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
343bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock | eSymbolContextFunction);
344bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            Block *unwind_block = unwind_sc.block;
345bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            if (unwind_block)
346bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            {
347bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                Address curr_frame_address (unwind_frame_sp->GetFrameCodeAddress());
348bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // Be sure to adjust the frame address to match the address
349bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // that was used to lookup the symbol context above. If we are
350bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // in the first concrete frame, then we lookup using the current
351bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // address, else we decrement the address by one to get the correct
352bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // location.
353bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                if (idx > 0)
354bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    curr_frame_address.Slide(-1);
3552f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton
356bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                SymbolContext next_frame_sc;
357bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                Address next_frame_address;
358bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
359bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                while (unwind_sc.GetParentOfInlinedScope(curr_frame_address, next_frame_sc, next_frame_address))
360bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                {
361bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                        StackFrameSP frame_sp(new StackFrame (m_thread.shared_from_this(),
362bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                                                              m_frames.size(),
363bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                                                              idx,
364bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                                                              unwind_frame_sp->GetRegisterContextSP (),
365bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                                                              cfa,
366bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                                                              next_frame_address,
367bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                                                              &next_frame_sc));
368bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
369bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                        m_frames.push_back (frame_sp);
370bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                        unwind_sc = next_frame_sc;
371bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                        curr_frame_address = next_frame_address;
3721d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton                }
3731d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton            }
374bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        } while (m_frames.size() - 1 < end_idx);
3755205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
376bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        // Don't try to merge till you've calculated all the frames in this stack.
377bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        if (GetAllFramesFetched() && m_prev_frames_sp)
378bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        {
379bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            StackFrameList *prev_frames = m_prev_frames_sp.get();
380bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            StackFrameList *curr_frames = this;
3811949b1e8eb944bcaf56fdbee52ed9b226b4bc8e5Jim Ingham
3829b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham            //curr_frames->m_current_inlined_depth = prev_frames->m_current_inlined_depth;
3839b124c6bc79c0f650ac52d65d6366f45f30ee31dJim Ingham            //curr_frames->m_current_inlined_pc = prev_frames->m_current_inlined_pc;
3845f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            //printf ("GetFramesUpTo: Copying current inlined depth: %d 0x%" PRIx64 ".\n", curr_frames->m_current_inlined_depth, curr_frames->m_current_inlined_pc);
3851d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton
3861d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton#if defined (DEBUG_STACK_FRAMES)
387bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            s.PutCString("\nprev_frames:\n");
388bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            prev_frames->Dump (&s);
389bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            s.PutCString("\ncurr_frames:\n");
390bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            curr_frames->Dump (&s);
391bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            s.EOL();
3921d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton#endif
393bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            size_t curr_frame_num, prev_frame_num;
394bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
395bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            for (curr_frame_num = curr_frames->m_frames.size(), prev_frame_num = prev_frames->m_frames.size();
396bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                 curr_frame_num > 0 && prev_frame_num > 0;
397bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                 --curr_frame_num, --prev_frame_num)
398bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            {
399bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                const size_t curr_frame_idx = curr_frame_num-1;
400bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                const size_t prev_frame_idx = prev_frame_num-1;
401bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                StackFrameSP curr_frame_sp (curr_frames->m_frames[curr_frame_idx]);
402bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                StackFrameSP prev_frame_sp (prev_frames->m_frames[prev_frame_idx]);
4031d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton
4041d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton#if defined (DEBUG_STACK_FRAMES)
405bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                s.Printf("\n\nCurr frame #%u ", curr_frame_idx);
406bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                if (curr_frame_sp)
407bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    curr_frame_sp->Dump (&s, true, false);
408bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                else
409bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    s.PutCString("NULL");
410bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                s.Printf("\nPrev frame #%u ", prev_frame_idx);
411bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                if (prev_frame_sp)
412bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    prev_frame_sp->Dump (&s, true, false);
413bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                else
414bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    s.PutCString("NULL");
4151d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton#endif
4161d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton
417bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                StackFrame *curr_frame = curr_frame_sp.get();
418bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                StackFrame *prev_frame = prev_frame_sp.get();
419bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
420bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                if (curr_frame == NULL || prev_frame == NULL)
421bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    break;
422bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
423bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // Check the stack ID to make sure they are equal
424bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                if (curr_frame->GetStackID() != prev_frame->GetStackID())
425bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                    break;
426bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
427bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                prev_frame->UpdatePreviousFrameFromCurrentFrame (*curr_frame);
428bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // Now copy the fixed up previous frame into the current frames
429bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                // so the pointer doesn't change
430bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                m_frames[curr_frame_idx] = prev_frame_sp;
431bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                //curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame);
432bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
4331d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton#if defined (DEBUG_STACK_FRAMES)
434bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham                s.Printf("\n    Copying previous frame to current frame");
4351d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton#endif
436782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton            }
437bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            // We are done with the old stack frame list, we can release it now
438bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            m_prev_frames_sp.reset();
439bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        }
440bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
441870a1cdb923ce708d474af357dd1fea3d063ab97Greg Clayton#if defined (DEBUG_STACK_FRAMES)
442bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            s.PutCString("\n\nNew frames:\n");
443bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            Dump (&s);
444bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            s.EOL();
445870a1cdb923ce708d474af357dd1fea3d063ab97Greg Clayton#endif
446bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    }
447bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    else
448bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    {
449bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        if (end_idx < m_concrete_frames_fetched)
450bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            return;
451bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
452bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        uint32_t num_frames = unwinder->GetFramesUpTo(end_idx);
453bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        if (num_frames <= end_idx + 1)
4541d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        {
455bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            //Done unwinding.
456bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham            m_concrete_frames_fetched = UINT32_MAX;
4571d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        }
458bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        m_frames.resize(num_frames);
459782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    }
460bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham}
461bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
462bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Inghamuint32_t
463bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim InghamStackFrameList::GetNumFrames (bool can_create)
464bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham{
465bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    Mutex::Locker locker (m_mutex);
466bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham
467bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    if (can_create)
468bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        GetFramesUpTo (UINT32_MAX);
4690c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
4700c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    uint32_t inlined_depth = GetCurrentInlinedDepth();
4710c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    if (inlined_depth == UINT32_MAX)
4720c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        return m_frames.size();
4730c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    else
4740c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        return m_frames.size() - inlined_depth;
47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4771d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Claytonvoid
4781d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg ClaytonStackFrameList::Dump (Stream *s)
47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4801d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    if (s == NULL)
4811d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        return;
4821d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    Mutex::Locker locker (m_mutex);
483782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton
4841d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    const_iterator pos, begin = m_frames.begin(), end = m_frames.end();
4851d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    for (pos = begin; pos != end; ++pos)
4861d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    {
4871d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        StackFrame *frame = (*pos).get();
4881d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        s->Printf("%p: ", frame);
4891d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        if (frame)
4904fb08150367853dae24bb92904356788e919a72fGreg Clayton        {
4914fb08150367853dae24bb92904356788e919a72fGreg Clayton            frame->GetStackID().Dump (s);
492a830adbcd63d1995a01e6e18da79893c1426ca43Greg Clayton            frame->DumpUsingSettingsFormat (s);
4934fb08150367853dae24bb92904356788e919a72fGreg Clayton        }
4941d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        else
4953e4238d47a6d1a3106f357d2e7b495870721c7aeGreg Clayton            s->Printf("frame #%u", (uint32_t)std::distance (begin, pos));
4961d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        s->EOL();
4971d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    }
4981d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    s->EOL();
49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerStackFrameSP
502782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg ClaytonStackFrameList::GetFrameAtIndex (uint32_t idx)
50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    StackFrameSP frame_sp;
5051d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    Mutex::Locker locker (m_mutex);
5064dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    uint32_t original_idx = idx;
5074dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham
5080c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    uint32_t inlined_depth = GetCurrentInlinedDepth();
5090c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    if (inlined_depth != UINT32_MAX)
5100c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        idx += inlined_depth;
5110c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
5121d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    if (idx < m_frames.size())
5131d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        frame_sp = m_frames[idx];
514782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton
5151d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    if (frame_sp)
5161d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        return frame_sp;
5171d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton
5184dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    // GetFramesUpTo will fill m_frames with as many frames as you asked for,
5194dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    // if there are that many.  If there weren't then you asked for too many
5204dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    // frames.
5214dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    GetFramesUpTo (idx);
5224dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    if (idx < m_frames.size())
5234dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    {
5244dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        if (m_show_inlined_frames)
525782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton        {
5264dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham            // When inline frames are enabled we actually create all the frames in GetFramesUpTo.
5274dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham            frame_sp = m_frames[idx];
5284dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        }
5294dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        else
5304dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        {
5314dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham            Unwind *unwinder = m_thread.GetUnwinder ();
5324dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham            if (unwinder)
5331d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton            {
5344dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                addr_t pc, cfa;
5354dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
5361d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton                {
5374dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                    frame_sp.reset (new StackFrame (m_thread.shared_from_this(), idx, idx, cfa, pc, NULL));
5384dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham
5394dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                    Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function;
5404dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                    if (function)
5414fb08150367853dae24bb92904356788e919a72fGreg Clayton                    {
5424dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                        // When we aren't showing inline functions we always use
5434dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                        // the top most function block as the scope.
5444dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                        frame_sp->SetSymbolContextScope (&function->GetBlock(false));
5454dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                    }
5464dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                    else
5474dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                    {
5484dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                        // Set the symbol scope from the symbol regardless if it is NULL or valid.
5494dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                        frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
5504fb08150367853dae24bb92904356788e919a72fGreg Clayton                    }
5514dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                    SetFrameAtIndex(idx, frame_sp);
5521d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton                }
5531d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton            }
554782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton        }
5554dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    }
5564dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    else if (original_idx == 0)
5574dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    {
5584dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        // There should ALWAYS be a frame at index 0.  If something went wrong with the CurrentInlinedDepth such that
5594dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        // there weren't as many frames as we thought taking that into account, then reset the current inlined depth
5604dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        // and return the real zeroth frame.
5614dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        if (m_frames.size() > 0)
5624dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        {
5634dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham            ResetCurrentInlinedDepth();
5644dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham            frame_sp = m_frames[original_idx];
5654dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        }
5664dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        else
5674dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        {
5684dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham            // Why do we have a thread with zero frames, that should not ever happen...
5694dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham            if (m_thread.IsValid())
5704dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham                assert ("A valid thread has no frames.");
5714dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham
5724dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham        }
5734dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham    }
5744dd7f537a66878101eb9c355e571af0c44ea5906Jim Ingham
57524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return frame_sp;
57624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
57724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
57808d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg ClaytonStackFrameSP
57908d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg ClaytonStackFrameList::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx)
58008d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton{
58108d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    // First try assuming the unwind index is the same as the frame index. The
58208d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    // unwind index is always greater than or equal to the frame index, so it
58308d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    // is a good place to start. If we have inlined frames we might have 5
58408d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    // concrete frames (frame unwind indexes go from 0-4), but we might have 15
58508d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    // frames after we make all the inlined frames. Most of the time the unwind
58608d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    // frame index (or the concrete frame index) is the same as the frame index.
58708d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    uint32_t frame_idx = unwind_idx;
58808d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    StackFrameSP frame_sp (GetFrameAtIndex (frame_idx));
58908d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    while (frame_sp)
59008d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    {
59108d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton        if (frame_sp->GetFrameIndex() == unwind_idx)
59208d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton            break;
59308d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton        frame_sp = GetFrameAtIndex (++frame_idx);
59408d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    }
59508d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    return frame_sp;
59608d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton}
59708d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton
598d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Claytonstatic bool
599d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg ClaytonCompareStackID (const StackFrameSP &stack_sp, const StackID &stack_id)
600d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton{
601d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton    return stack_sp->GetStackID() < stack_id;
602d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton}
603d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton
6045c4b1607e8783a3d3f1f28fa66fcaa89ac246bd1Jim InghamStackFrameSP
605b4d7fc0c466d446876e5f2d701f0e574dd0be8e7Greg ClaytonStackFrameList::GetFrameWithStackID (const StackID &stack_id)
6065c4b1607e8783a3d3f1f28fa66fcaa89ac246bd1Jim Ingham{
6075c4b1607e8783a3d3f1f28fa66fcaa89ac246bd1Jim Ingham    StackFrameSP frame_sp;
608d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton
609d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton    if (stack_id.IsValid())
6105c4b1607e8783a3d3f1f28fa66fcaa89ac246bd1Jim Ingham    {
611d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        Mutex::Locker locker (m_mutex);
612d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        uint32_t frame_idx = 0;
613d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        // Do a binary search in case the stack frame is already in our cache
614d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        collection::const_iterator begin = m_frames.begin();
615d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        collection::const_iterator end = m_frames.end();
616d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        if (begin != end)
617d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        {
618d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton            collection::const_iterator pos = std::lower_bound (begin, end, stack_id, CompareStackID);
619d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton            if (pos != end && (*pos)->GetStackID() == stack_id)
620d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton                return *pos;
621d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton
622d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton            if (m_frames.back()->GetStackID() < stack_id)
623d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton                frame_idx = m_frames.size();
624d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        }
625d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        do
626d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        {
627d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton            frame_sp = GetFrameAtIndex (frame_idx);
628d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton            if (frame_sp && frame_sp->GetStackID() == stack_id)
629d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton                break;
630d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton            frame_idx++;
631d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        }
632d1ddde0c443e67b37f9303b5bdff19aad9f54fdcGreg Clayton        while (frame_sp);
6335c4b1607e8783a3d3f1f28fa66fcaa89ac246bd1Jim Ingham    }
6345c4b1607e8783a3d3f1f28fa66fcaa89ac246bd1Jim Ingham    return frame_sp;
6355c4b1607e8783a3d3f1f28fa66fcaa89ac246bd1Jim Ingham}
63608d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton
637782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Claytonbool
6381d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg ClaytonStackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
639782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton{
6401d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    if (idx >= m_frames.size())
6411d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        m_frames.resize(idx + 1);
642782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    // Make sure allocation succeeded by checking bounds again
6431d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    if (idx < m_frames.size())
644782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    {
6451d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        m_frames[idx] = frame_sp;
64624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
64724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
64824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;   // resize failed, out of memory?
64924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
65024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
65124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
652c833295baeec641086f536e78050388af36784f8Jim InghamStackFrameList::GetSelectedFrameIndex () const
65324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
65424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex::Locker locker (m_mutex);
655c833295baeec641086f536e78050388af36784f8Jim Ingham    return m_selected_frame_idx;
65624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
65724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
65824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
65924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
660c833295baeec641086f536e78050388af36784f8Jim InghamStackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame)
66124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
66224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex::Locker locker (m_mutex);
663782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    const_iterator pos;
6641d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    const_iterator begin = m_frames.begin();
6651d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    const_iterator end = m_frames.end();
666fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham    m_selected_frame_idx = 0;
66724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos = begin; pos != end; ++pos)
66824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
66924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos->get() == frame)
67024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
671c833295baeec641086f536e78050388af36784f8Jim Ingham            m_selected_frame_idx = std::distance (begin, pos);
6720c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            uint32_t inlined_depth = GetCurrentInlinedDepth();
6730c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            if (inlined_depth != UINT32_MAX)
6740c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                m_selected_frame_idx -= inlined_depth;
675fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham            break;
67624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
67724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
678fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham    SetDefaultFileAndLineToSelectedFrame();
679c833295baeec641086f536e78050388af36784f8Jim Ingham    return m_selected_frame_idx;
68024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
68124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
68224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Mark a stack frame as the current frame using the frame index
683bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Inghambool
684c833295baeec641086f536e78050388af36784f8Jim InghamStackFrameList::SetSelectedFrameByIndex (uint32_t idx)
68524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
68624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex::Locker locker (m_mutex);
687bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    StackFrameSP frame_sp (GetFrameAtIndex (idx));
688bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    if (frame_sp)
689bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    {
690bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        SetSelectedFrame(frame_sp.get());
691bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        return true;
692bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    }
693bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    else
694bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham        return false;
695fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham}
696fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham
697fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Inghamvoid
698fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim InghamStackFrameList::SetDefaultFileAndLineToSelectedFrame()
699fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham{
700f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    if (m_thread.GetID() == m_thread.GetProcess()->GetThreadList().GetSelectedThread()->GetID())
701fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham    {
702840a992018e4bc55f18e5b68815600fa6870f8d9Greg Clayton        StackFrameSP frame_sp (GetFrameAtIndex (GetSelectedFrameIndex()));
703fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham        if (frame_sp)
704fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham        {
705840a992018e4bc55f18e5b68815600fa6870f8d9Greg Clayton            SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextLineEntry);
706fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham            if (sc.line_entry.file)
707f4124deeb9532044a38c0774ced872f2709347daGreg Clayton                m_thread.CalculateTarget()->GetSourceManager().SetDefaultFileAndLine (sc.line_entry.file,
708840a992018e4bc55f18e5b68815600fa6870f8d9Greg Clayton                                                                                            sc.line_entry.line);
709fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham        }
710fdf24efe672bf3fa041cdbebd2d7f406b11882bdJim Ingham    }
71124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
71224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
71324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The thread has been run, reset the number stack frames to zero so we can
71424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// determine how many frames we have lazily.
71524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
71624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerStackFrameList::Clear ()
71724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
71824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex::Locker locker (m_mutex);
7191d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton    m_frames.clear();
720bf97d74c0c3e9a0f7c89fe0cd4a059015ec482d5Jim Ingham    m_concrete_frames_fetched = 0;
72124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
72224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
72324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
72424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerStackFrameList::InvalidateFrames (uint32_t start_idx)
72524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
72624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex::Locker locker (m_mutex);
727782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    if (m_show_inlined_frames)
728782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    {
729782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton        Clear();
730782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    }
731782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton    else
73224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7331d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton        const size_t num_frames = m_frames.size();
734782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton        while (start_idx < num_frames)
735782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton        {
7361d66ef5d31a8326d5495f56b0cfbf2fd1bff67d8Greg Clayton            m_frames[start_idx].reset();
737782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton            ++start_idx;
738782b9ccd9f2b290585cd6bb4c1f0cc6cb7e22e15Greg Clayton        }
73924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
74024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7415205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
7425205f0b6585a127acc6ed210021abb6091220a89Greg Claytonvoid
743102b2c2681c9a830afe25bfea35557421905e42cGreg ClaytonStackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
7445205f0b6585a127acc6ed210021abb6091220a89Greg Clayton{
7451b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    Mutex::Locker curr_locker (curr_ap.get() ? &curr_ap->m_mutex : NULL);
7461b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    Mutex::Locker prev_locker (prev_sp.get() ? &prev_sp->m_mutex : NULL);
7475205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
7485205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#if defined (DEBUG_STACK_FRAMES)
7490a77f90197f2e115208c45c9e7f28ef745da9c95Johnny Chen    StreamFile s(stdout, false);
7505205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n");
7515205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    if (prev_sp.get())
7525205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        prev_sp->Dump (&s);
7535205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    else
7545205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        s.PutCString ("NULL");
7555205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    s.PutCString("\nCurr:\n");
7565205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    if (curr_ap.get())
7575205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        curr_ap->Dump (&s);
7585205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    else
7595205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        s.PutCString ("NULL");
7605205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    s.EOL();
7615205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#endif
7625205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
7635205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    if (curr_ap.get() == NULL || curr_ap->GetNumFrames (false) == 0)
7645205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    {
7655205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#if defined (DEBUG_STACK_FRAMES)
7665205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        s.PutCString("No current frames, leave previous frames alone...\n");
7675205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#endif
7685205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        curr_ap.release();
7695205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        return;
7705205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    }
7715205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
7725205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    if (prev_sp.get() == NULL || prev_sp->GetNumFrames (false) == 0)
7735205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    {
7745205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#if defined (DEBUG_STACK_FRAMES)
7755205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        s.PutCString("No previous frames, so use current frames...\n");
7765205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#endif
7775205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        // We either don't have any previous frames, or since we have more than
7785205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        // one current frames it means we have all the frames and can safely
7795205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        // replace our previous frames.
7805205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        prev_sp.reset (curr_ap.release());
7815205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        return;
7825205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    }
7835205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
7845205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    const uint32_t num_curr_frames = curr_ap->GetNumFrames (false);
7855205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
7865205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    if (num_curr_frames > 1)
7875205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    {
7885205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#if defined (DEBUG_STACK_FRAMES)
7895205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        s.PutCString("We have more than one current frame, so use current frames...\n");
7905205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#endif
7915205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        // We have more than one current frames it means we have all the frames
7925205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        // and can safely replace our previous frames.
7935205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        prev_sp.reset (curr_ap.release());
7945205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
7955205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#if defined (DEBUG_STACK_FRAMES)
7965205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        s.PutCString("\nMerged:\n");
7975205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        prev_sp->Dump (&s);
7985205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#endif
7995205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        return;
8005205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    }
8015205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
8025205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex (0));
8035205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    StackFrameSP curr_frame_zero_sp(curr_ap->GetFrameAtIndex (0));
8045205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    StackID curr_stack_id (curr_frame_zero_sp->GetStackID());
8055205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    StackID prev_stack_id (prev_frame_zero_sp->GetStackID());
8065205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
8075205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#if defined (DEBUG_STACK_FRAMES)
8080a77f90197f2e115208c45c9e7f28ef745da9c95Johnny Chen    const uint32_t num_prev_frames = prev_sp->GetNumFrames (false);
8095205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    s.Printf("\n%u previous frames with one current frame\n", num_prev_frames);
8105205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#endif
8115205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
8125205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    // We have only a single current frame
8135205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    // Our previous stack frames only had a single frame as well...
8145205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    if (curr_stack_id == prev_stack_id)
8155205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    {
8165205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#if defined (DEBUG_STACK_FRAMES)
8175205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        s.Printf("\nPrevious frame #0 is same as current frame #0, merge the cached data\n");
8185205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#endif
8195205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
8205205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame (*prev_frame_zero_sp);
8215205f0b6585a127acc6ed210021abb6091220a89Greg Clayton//        prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame (*curr_frame_zero_sp);
8225205f0b6585a127acc6ed210021abb6091220a89Greg Clayton//        prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp);
8235205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    }
8245205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    else if (curr_stack_id < prev_stack_id)
8255205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    {
8265205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#if defined (DEBUG_STACK_FRAMES)
8275205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        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");
8285205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#endif
8295205f0b6585a127acc6ed210021abb6091220a89Greg Clayton        prev_sp->m_frames.insert (prev_sp->m_frames.begin(), curr_frame_zero_sp);
8305205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    }
8315205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
8325205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    curr_ap.release();
8335205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
8345205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#if defined (DEBUG_STACK_FRAMES)
8355205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    s.PutCString("\nMerged:\n");
8365205f0b6585a127acc6ed210021abb6091220a89Greg Clayton    prev_sp->Dump (&s);
8375205f0b6585a127acc6ed210021abb6091220a89Greg Clayton#endif
8385205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
8395205f0b6585a127acc6ed210021abb6091220a89Greg Clayton
8405205f0b6585a127acc6ed210021abb6091220a89Greg Clayton}
841ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham
842ccd584dccb920cdb028de69950774c3bcdc025ecJim Inghamlldb::StackFrameSP
843ccd584dccb920cdb028de69950774c3bcdc025ecJim InghamStackFrameList::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)
844ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham{
845ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham    const_iterator pos;
846ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham    const_iterator begin = m_frames.begin();
847ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham    const_iterator end = m_frames.end();
848ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham    lldb::StackFrameSP ret_sp;
849ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham
850ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham    for (pos = begin; pos != end; ++pos)
851ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham    {
852ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham        if (pos->get() == stack_frame_ptr)
853ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham        {
854ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham            ret_sp = (*pos);
855ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham            break;
856ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham        }
857ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham    }
858ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham    return ret_sp;
859ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham}
860ccd584dccb920cdb028de69950774c3bcdc025ecJim Ingham
861abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Claytonsize_t
862abe0fed36d83e1c37af9dae90c2d25db742b4515Greg ClaytonStackFrameList::GetStatus (Stream& strm,
863abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton                           uint32_t first_frame,
864abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton                           uint32_t num_frames,
865abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton                           bool show_frame_info,
866a7d3dc75ec4f46033c3f991f11fb58a058091a85Greg Clayton                           uint32_t num_frames_with_source)
867abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton{
868abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    size_t num_frames_displayed = 0;
869abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton
870abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    if (num_frames == 0)
871abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton        return 0;
872abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton
873abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    StackFrameSP frame_sp;
874abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    uint32_t frame_idx = 0;
875abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    uint32_t last_frame;
876abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton
877abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    // Don't let the last frame wrap around...
878abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    if (num_frames == UINT32_MAX)
879abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton        last_frame = UINT32_MAX;
880abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    else
881abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton        last_frame = first_frame + num_frames;
882abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton
883abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx)
884abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    {
885abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton        frame_sp = GetFrameAtIndex(frame_idx);
886abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton        if (frame_sp.get() == NULL)
887abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton            break;
888abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton
889abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton        if (!frame_sp->GetStatus (strm,
890abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton                                  show_frame_info,
891a7d3dc75ec4f46033c3f991f11fb58a058091a85Greg Clayton                                  num_frames_with_source > (first_frame - frame_idx)))
892abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton            break;
893abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton        ++num_frames_displayed;
894abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    }
895abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton
896abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    strm.IndentLess();
897abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton    return num_frames_displayed;
898abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton}
899abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton
900