diff options
Diffstat (limited to 'lldb/source/Target/StackFrameList.cpp')
| -rw-r--r-- | lldb/source/Target/StackFrameList.cpp | 132 |
1 files changed, 118 insertions, 14 deletions
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp index 0b8b8bf3775f..d2c9c594b04c 100644 --- a/lldb/source/Target/StackFrameList.cpp +++ b/lldb/source/Target/StackFrameList.cpp @@ -30,9 +30,14 @@ using namespace lldb_private; //---------------------------------------------------------------------- // StackFrameList constructor //---------------------------------------------------------------------- -StackFrameList::StackFrameList(Thread &thread, StackFrameList *prev_frames, bool show_inline_frames) : +StackFrameList::StackFrameList +( + Thread &thread, + const lldb::StackFrameListSP &prev_frames_sp, + bool show_inline_frames +) : m_thread (thread), - m_prev_frames_ap (prev_frames), + m_prev_frames_sp (prev_frames_sp), m_show_inlined_frames (show_inline_frames), m_mutex (Mutex::eMutexTypeRecursive), m_frames (), @@ -49,11 +54,11 @@ StackFrameList::~StackFrameList() uint32_t -StackFrameList::GetNumFrames() +StackFrameList::GetNumFrames (bool can_create) { Mutex::Locker locker (m_mutex); - if (m_frames.size() <= 1) + if (can_create && m_frames.size() <= 1) { if (m_show_inlined_frames) { @@ -165,9 +170,10 @@ StackFrameList::GetNumFrames() } } } - StackFrameList *prev_frames = m_prev_frames_ap.get(); - if (prev_frames) + + if (m_prev_frames_sp) { + StackFrameList *prev_frames = m_prev_frames_sp.get(); StackFrameList *curr_frames = this; #if defined (DEBUG_STACK_FRAMES) @@ -189,17 +195,16 @@ StackFrameList::GetNumFrames() StackFrameSP prev_frame_sp (prev_frames->m_frames[prev_frame_idx]); #if defined (DEBUG_STACK_FRAMES) - s.Printf("\nCurrent frame #%u ", curr_frame_idx); + s.Printf("\n\nCurr frame #%u ", curr_frame_idx); if (curr_frame_sp) - curr_frame_sp->Dump (&s, true); + curr_frame_sp->Dump (&s, true, false); else s.PutCString("NULL"); - s.Printf("\nPrevious frame #%u ", prev_frame_idx); + s.Printf("\nPrev frame #%u ", prev_frame_idx); if (prev_frame_sp) - prev_frame_sp->Dump (&s, true); + prev_frame_sp->Dump (&s, true, false); else s.PutCString("NULL"); - s.EOL(); #endif StackFrame *curr_frame = curr_frame_sp.get(); @@ -223,8 +228,7 @@ StackFrameList::GetNumFrames() #endif } // We are done with the old stack frame list, we can release it now - m_prev_frames_ap.release(); - prev_frames = NULL; + m_prev_frames_sp.reset(); } #if defined (DEBUG_STACK_FRAMES) @@ -332,7 +336,6 @@ StackFrameList::GetFrameAtIndex (uint32_t idx) return frame_sp; } - bool StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) { @@ -409,3 +412,104 @@ StackFrameList::InvalidateFrames (uint32_t start_idx) } } } + +void +StackFrameList::Merge (std::auto_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp) +{ + Mutex::Locker curr_locker (curr_ap.get() ? curr_ap->m_mutex.GetMutex() : NULL); + Mutex::Locker prev_locker (prev_sp.get() ? prev_sp->m_mutex.GetMutex() : NULL); + +#if defined (DEBUG_STACK_FRAMES) + StreamFile s(stdout); + s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n"); + if (prev_sp.get()) + prev_sp->Dump (&s); + else + s.PutCString ("NULL"); + s.PutCString("\nCurr:\n"); + if (curr_ap.get()) + curr_ap->Dump (&s); + else + s.PutCString ("NULL"); + s.EOL(); +#endif + + if (curr_ap.get() == NULL || curr_ap->GetNumFrames (false) == 0) + { +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("No current frames, leave previous frames alone...\n"); +#endif + curr_ap.release(); + return; + } + + if (prev_sp.get() == NULL || prev_sp->GetNumFrames (false) == 0) + { +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("No previous frames, so use current frames...\n"); +#endif + // We either don't have any previous frames, or since we have more than + // one current frames it means we have all the frames and can safely + // replace our previous frames. + prev_sp.reset (curr_ap.release()); + return; + } + + const uint32_t num_curr_frames = curr_ap->GetNumFrames (false); + + if (num_curr_frames > 1) + { +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("We have more than one current frame, so use current frames...\n"); +#endif + // We have more than one current frames it means we have all the frames + // and can safely replace our previous frames. + prev_sp.reset (curr_ap.release()); + +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("\nMerged:\n"); + prev_sp->Dump (&s); +#endif + return; + } + + StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex (0)); + StackFrameSP curr_frame_zero_sp(curr_ap->GetFrameAtIndex (0)); + StackID curr_stack_id (curr_frame_zero_sp->GetStackID()); + StackID prev_stack_id (prev_frame_zero_sp->GetStackID()); + + //const uint32_t num_prev_frames = prev_sp->GetNumFrames (false); + +#if defined (DEBUG_STACK_FRAMES) + s.Printf("\n%u previous frames with one current frame\n", num_prev_frames); +#endif + + // We have only a single current frame + // Our previous stack frames only had a single frame as well... + if (curr_stack_id == prev_stack_id) + { +#if defined (DEBUG_STACK_FRAMES) + s.Printf("\nPrevious frame #0 is same as current frame #0, merge the cached data\n"); +#endif + + curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame (*prev_frame_zero_sp); +// prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame (*curr_frame_zero_sp); +// prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp); + } + else if (curr_stack_id < prev_stack_id) + { +#if defined (DEBUG_STACK_FRAMES) + s.Printf("\nCurrent frame #0 has a stack ID that is less than the previous frame #0, insert current frame zero in front of previous\n"); +#endif + prev_sp->m_frames.insert (prev_sp->m_frames.begin(), curr_frame_zero_sp); + } + + curr_ap.release(); + +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("\nMerged:\n"); + prev_sp->Dump (&s); +#endif + + +} |
