diff options
| author | Greg Clayton <gclayton@apple.com> | 2011-01-06 22:15:06 +0000 |
|---|---|---|
| committer | Greg Clayton <gclayton@apple.com> | 2011-01-06 22:15:06 +0000 |
| commit | 5ccbd294b25d2666c42b28c7031c8e0eff197f25 (patch) | |
| tree | 12e30d9acc1bdacd6c8d60f1e2bbb305c29683f3 /lldb/source/Target | |
| parent | 842a9bac486c5be187472044d2a8d7f93e140df3 (diff) | |
| download | bcm5719-llvm-5ccbd294b25d2666c42b28c7031c8e0eff197f25.tar.gz bcm5719-llvm-5ccbd294b25d2666c42b28c7031c8e0eff197f25.zip | |
Fixed issues with RegisterContext classes and the subclasses. There was
an issue with the way the UnwindLLDB was handing out RegisterContexts: it
was making shared pointers to register contexts and then handing out just
the pointers (which would get put into shared pointers in the thread and
stack frame classes) and cause double free issues. MallocScribble helped to
find these issues after I did some other cleanup. To help avoid any
RegisterContext issue in the future, all code that deals with them now
returns shared pointers to the register contexts so we don't end up with
multiple deletions. Also now that the RegisterContext class doesn't require
a stack frame, we patched a memory leak where a StackFrame object was being
created and leaked.
Made the RegisterContext class not have a pointer to a StackFrame object as
one register context class can be used for N inlined stack frames so there is
not a 1 - 1 mapping. Updates the ExecutionContextScope part of the
RegisterContext class to never return a stack frame to indicate this when it
is asked to recreate the execution context. Now register contexts point to the
concrete frame using a concrete frame index. Concrete frames are all of the
frames that are actually formed on the stack of a thread. These concrete frames
can be turned into one or more user visible frames due to inlining. Each
inlined stack frame has the exact same register context (shared via shared
pointers) as any parent inlined stack frames all the way up to the concrete
frame itself.
So now the stack frames and the register contexts should behave much better.
llvm-svn: 122976
Diffstat (limited to 'lldb/source/Target')
| -rw-r--r-- | lldb/source/Target/ExecutionContext.cpp | 4 | ||||
| -rw-r--r-- | lldb/source/Target/Process.cpp | 2 | ||||
| -rw-r--r-- | lldb/source/Target/RegisterContext.cpp | 34 | ||||
| -rw-r--r-- | lldb/source/Target/StackFrame.cpp | 16 | ||||
| -rw-r--r-- | lldb/source/Target/StackFrameList.cpp | 21 | ||||
| -rw-r--r-- | lldb/source/Target/Thread.cpp | 7 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadPlan.cpp | 2 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadPlanCallFunction.cpp | 4 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadPlanTracer.cpp | 45 |
9 files changed, 63 insertions, 72 deletions
diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp index d0bcdac8789..15b4dc8f9be 100644 --- a/lldb/source/Target/ExecutionContext.cpp +++ b/lldb/source/Target/ExecutionContext.cpp @@ -88,9 +88,9 @@ RegisterContext * ExecutionContext::GetRegisterContext () const { if (frame) - return frame->GetRegisterContext(); + return frame->GetRegisterContext().get(); else if (thread) - return thread->GetRegisterContext(); + return thread->GetRegisterContext().get(); return NULL; } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 4b0fd24864b..3ecbc3cac7b 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2545,7 +2545,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, } ts.Printf("<"); - RegisterContext *register_context = thread->GetRegisterContext(); + RegisterContext *register_context = thread->GetRegisterContext().get(); if (register_context) ts.Printf("[ip 0x%llx] ", register_context->GetPC()); diff --git a/lldb/source/Target/RegisterContext.cpp b/lldb/source/Target/RegisterContext.cpp index 1d405325833..1edaf4964d8 100644 --- a/lldb/source/Target/RegisterContext.cpp +++ b/lldb/source/Target/RegisterContext.cpp @@ -21,18 +21,9 @@ using namespace lldb; using namespace lldb_private; -//---------------------------------------------------------------------- -// RegisterContext constructors -//---------------------------------------------------------------------- -RegisterContext::RegisterContext (Thread &thread, StackFrame *frame) : - m_thread (thread), - m_frame (frame) -{ -} - -RegisterContext::RegisterContext (Thread &thread) : +RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) : m_thread (thread), - m_frame (NULL) + m_concrete_frame_idx (concrete_frame_idx) { } @@ -86,8 +77,9 @@ RegisterContext::SetPC(uint64_t pc) bool success = WriteRegisterFromUnsigned (reg, pc); if (success) { - if (m_frame) - m_frame->ChangePC(pc); + StackFrameSP frame_sp(m_thread.GetFrameWithConcreteFrameIndex (m_concrete_frame_idx)); + if (frame_sp) + frame_sp->ChangePC(pc); else m_thread.ClearStackFrames (); } @@ -207,12 +199,6 @@ RegisterContext::HardwareSingleStep (bool enable) return false; } -void -RegisterContext::SetStackFrame (StackFrame *frame) -{ - m_frame = frame; -} - Target * RegisterContext::CalculateTarget () { @@ -235,16 +221,16 @@ RegisterContext::CalculateThread () StackFrame * RegisterContext::CalculateStackFrame () { - return m_frame; + // Register contexts might belong to many frames if we have inlined + // functions inside a frame since all inlined functions share the + // same registers, so we can't definitively say which frame we come from... + return NULL; } void RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx) { - if (m_frame) - m_frame->CalculateExecutionContext (exe_ctx); - else - m_thread.CalculateExecutionContext (exe_ctx); + m_thread.CalculateExecutionContext (exe_ctx); } diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 812846f8143..5b1a57d564c 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -49,7 +49,7 @@ StackFrame::StackFrame const SymbolContext *sc_ptr ) : m_frame_index (frame_idx), - m_unwind_frame_index (unwind_frame_index), + m_concrete_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (), m_id (pc, cfa, NULL), @@ -79,7 +79,7 @@ StackFrame::StackFrame const SymbolContext *sc_ptr ) : m_frame_index (frame_idx), - m_unwind_frame_index (unwind_frame_index), + m_concrete_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), m_id (pc, cfa, NULL), @@ -115,7 +115,7 @@ StackFrame::StackFrame const SymbolContext *sc_ptr ) : m_frame_index (frame_idx), - m_unwind_frame_index (unwind_frame_index), + m_concrete_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), m_id (pc_addr.GetLoadAddress (&thread.GetProcess().GetTarget()), cfa, NULL), @@ -755,12 +755,12 @@ StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) return m_frame_base_error.Success(); } -RegisterContext * +RegisterContextSP StackFrame::GetRegisterContext () { - if (m_reg_context_sp.get() == NULL) - m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this)); - return m_reg_context_sp.get(); + if (!m_reg_context_sp) + m_reg_context_sp = m_thread.CreateRegisterContextForFrame (this); + return m_reg_context_sp; } bool @@ -916,7 +916,7 @@ StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value assert (&m_thread == &curr_frame.m_thread); m_frame_index = curr_frame.m_frame_index; - m_unwind_frame_index = curr_frame.m_unwind_frame_index; + m_concrete_frame_index = curr_frame.m_concrete_frame_index; m_reg_context_sp = curr_frame.m_reg_context_sp; m_frame_code_addr = curr_frame.m_frame_code_addr; assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp index 2dd5fb8857b..fbdad14b1bd 100644 --- a/lldb/source/Target/StackFrameList.cpp +++ b/lldb/source/Target/StackFrameList.cpp @@ -336,6 +336,27 @@ StackFrameList::GetFrameAtIndex (uint32_t idx) return frame_sp; } +StackFrameSP +StackFrameList::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx) +{ + // First try assuming the unwind index is the same as the frame index. The + // unwind index is always greater than or equal to the frame index, so it + // is a good place to start. If we have inlined frames we might have 5 + // concrete frames (frame unwind indexes go from 0-4), but we might have 15 + // frames after we make all the inlined frames. Most of the time the unwind + // frame index (or the concrete frame index) is the same as the frame index. + uint32_t frame_idx = unwind_idx; + StackFrameSP frame_sp (GetFrameAtIndex (frame_idx)); + while (frame_sp) + { + if (frame_sp->GetFrameIndex() == unwind_idx) + break; + frame_sp = GetFrameAtIndex (++frame_idx); + } + return frame_sp; +} + + bool StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) { diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index ed747646209..e9b3b6dc60b 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -877,6 +877,13 @@ Thread::GetSelectedFrameIndex () return GetStackFrameList().GetSelectedFrameIndex(); } +lldb::StackFrameSP +Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx) +{ + return GetStackFrameList().GetFrameWithConcreteFrameIndex (unwind_idx); +} + + lldb::StackFrameSP Thread::GetSelectedFrame () diff --git a/lldb/source/Target/ThreadPlan.cpp b/lldb/source/Target/ThreadPlan.cpp index 8b6aedd839f..56403ef009d 100644 --- a/lldb/source/Target/ThreadPlan.cpp +++ b/lldb/source/Target/ThreadPlan.cpp @@ -149,7 +149,7 @@ ThreadPlan::WillResume (StateType resume_state, bool current_plan) if (log) { - RegisterContext *reg_ctx = m_thread.GetRegisterContext(); + RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); addr_t pc = reg_ctx->GetPC(); addr_t sp = reg_ctx->GetSP(); addr_t fp = reg_ctx->GetFP(); diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index 165e63d1189..a662ea0589d 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -95,7 +95,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, if (log) { - RegisterContext *reg_ctx = m_thread.GetRegisterContext(); + RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); log->PutCString("Function call was set up. Register state was:"); @@ -214,7 +214,7 @@ ThreadPlanCallFunction::ShouldStop (Event *event_ptr) if (log) { - RegisterContext *reg_ctx = m_thread.GetRegisterContext(); + RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); log->PutCString("Function completed. Register state was:"); diff --git a/lldb/source/Target/ThreadPlanTracer.cpp b/lldb/source/Target/ThreadPlanTracer.cpp index 0ca2d177800..f957b804681 100644 --- a/lldb/source/Target/ThreadPlanTracer.cpp +++ b/lldb/source/Target/ThreadPlanTracer.cpp @@ -132,9 +132,10 @@ ThreadPlanAssemblyTracer::~ThreadPlanAssemblyTracer() { } -void ThreadPlanAssemblyTracer::TracingStarted () +void +ThreadPlanAssemblyTracer::TracingStarted () { - RegisterContext *reg_ctx = m_thread.GetRegisterContext(); + RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); if (m_register_values.size() == 0) { @@ -145,7 +146,8 @@ void ThreadPlanAssemblyTracer::TracingStarted () } } -void ThreadPlanAssemblyTracer::TracingEnded () +void +ThreadPlanAssemblyTracer::TracingEnded () { for (uint32_t reg_index = 0, num_registers = m_register_values.size(); reg_index < num_registers; @@ -153,51 +155,26 @@ void ThreadPlanAssemblyTracer::TracingEnded () m_register_values[reg_index] = 0; } -static const char *Padding(int length) -{ - const int padding_size = 256; - - static char* padding = NULL; - static int prev_length = 256; - - if (!padding) { - padding = new char[padding_size]; - memset(padding, ' ', padding_size); - } - - if (length > 255) - length = 255; - - if (prev_length < 256) - padding[prev_length] = ' '; - - padding[length] = '\0'; - - prev_length = length; - - return padding; -} - -static void PadOutTo(StreamString &stream, int target) +static void +PadOutTo (StreamString &stream, int target) { stream.Flush(); int length = stream.GetString().length(); if (length + 1 < target) - stream.PutCString(Padding(target - (length + 1))); - - stream.PutCString(" "); + stream.Printf("%*s", target - (length + 1) + 1, ""); } -void ThreadPlanAssemblyTracer::Log () +void +ThreadPlanAssemblyTracer::Log () { Stream *stream = GetLogStream (); if (!stream) return; - RegisterContext *reg_ctx = m_thread.GetRegisterContext(); + RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); lldb::addr_t pc = reg_ctx->GetPC(); Address pc_addr; |

