summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-01-06 22:15:06 +0000
committerGreg Clayton <gclayton@apple.com>2011-01-06 22:15:06 +0000
commit5ccbd294b25d2666c42b28c7031c8e0eff197f25 (patch)
tree12e30d9acc1bdacd6c8d60f1e2bbb305c29683f3 /lldb/source/Target
parent842a9bac486c5be187472044d2a8d7f93e140df3 (diff)
downloadbcm5719-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.cpp4
-rw-r--r--lldb/source/Target/Process.cpp2
-rw-r--r--lldb/source/Target/RegisterContext.cpp34
-rw-r--r--lldb/source/Target/StackFrame.cpp16
-rw-r--r--lldb/source/Target/StackFrameList.cpp21
-rw-r--r--lldb/source/Target/Thread.cpp7
-rw-r--r--lldb/source/Target/ThreadPlan.cpp2
-rw-r--r--lldb/source/Target/ThreadPlanCallFunction.cpp4
-rw-r--r--lldb/source/Target/ThreadPlanTracer.cpp45
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;
OpenPOWER on IntegriCloud