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