All UnwindPlan objects are now passed around as shared pointers.

ArchDefaultUnwindPlan plug-in interfaces are now cached per architecture 
instead of being leaked for every frame.

Split the ArchDefaultUnwindPlan_x86 into ArchDefaultUnwindPlan_x86_64 and
ArchDefaultUnwindPlan_i386 interfaces.

There were sporadic crashes that were due to something leaking or being 
destroyed when doing stack crawls. This patch should clear up these issues.

llvm-svn: 125541
diff --git a/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.cpp b/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.cpp
index 289429d..6824b79 100644
--- a/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.cpp
+++ b/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.cpp
@@ -8,67 +8,29 @@
 //===----------------------------------------------------------------------===//
 
 #include "ArchDefaultUnwindPlan-x86.h"
-#include "llvm/Support/MachO.h"
-#include "lldb/lldb-private.h"
-#include "lldb/Utility/ArchDefaultUnwindPlan.h"
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/PluginManager.h"
-#include "lldb/lldb-enumerations.h"
+#include "lldb/Utility/ArchDefaultUnwindPlan.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
-lldb_private::UnwindPlan*
-ArchDefaultUnwindPlan_x86::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc)
+lldb_private::ArchDefaultUnwindPlan *
+ArchDefaultUnwindPlan_x86_64::CreateInstance (const lldb_private::ArchSpec &arch)
 {
-    if (m_cpu == llvm::MachO::CPUTypeX86_64)
-    {
-        return &m_64bit_default;
-    }
-    if (m_cpu == llvm::MachO::CPUTypeI386)
-    {
-        return &m_32bit_default;
-    }
+    if (arch.GetGenericCPUType () == ArchSpec::eCPU_x86_64)
+        return new ArchDefaultUnwindPlan_x86_64 ();
     return NULL;
 }
 
-lldb_private::ArchDefaultUnwindPlan *
-ArchDefaultUnwindPlan_x86::CreateInstance (const lldb_private::ArchSpec &arch)
-{
-   uint32_t cpu = arch.GetCPUType ();
-   if (cpu != llvm::MachO::CPUTypeX86_64 && cpu != llvm::MachO::CPUTypeI386)
-       return NULL;
-
-   return new ArchDefaultUnwindPlan_x86 (cpu);
-}
-
-ArchDefaultUnwindPlan_x86::ArchDefaultUnwindPlan_x86(int cpu) :
+ArchDefaultUnwindPlan_x86_64::ArchDefaultUnwindPlan_x86_64() :
                 lldb_private::ArchDefaultUnwindPlan(), 
-                m_cpu(cpu), 
-                m_32bit_default(), 
-                m_64bit_default() 
+                m_unwind_plan_sp (new UnwindPlan)
 { 
     UnwindPlan::Row row;
     UnwindPlan::Row::RegisterLocation regloc;
 
-    m_32bit_default.SetRegisterKind (eRegisterKindGeneric);
-    row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
-    row.SetCFAOffset (2 * 4);
-    row.SetOffset (0);
-
-    regloc.SetAtCFAPlusOffset (2 * -4);
-    row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc);
-    regloc.SetAtCFAPlusOffset (1 * -4);
-    row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc);
-    regloc.SetIsCFAPlusOffset (0);
-    row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc);
-
-    m_32bit_default.AppendRow (row);
-    m_32bit_default.SetSourceName ("architectural default");
-
-    row.Clear();
-
-    m_64bit_default.SetRegisterKind (eRegisterKindGeneric);
+    m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric);
     row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
     row.SetCFAOffset (2 * 8);
     row.SetOffset (0);
@@ -80,43 +42,40 @@
     regloc.SetIsCFAPlusOffset (0);
     row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc);
 
-    m_64bit_default.AppendRow (row);
-    m_64bit_default.SetSourceName ("architectural default");
+    m_unwind_plan_sp->AppendRow (row);
+    m_unwind_plan_sp->SetSourceName ("x86_64 architectural default");
 }
 
-
-
-
 //------------------------------------------------------------------
 // PluginInterface protocol in UnwindAssemblyParser_x86
 //------------------------------------------------------------------
 
 const char *
-ArchDefaultUnwindPlan_x86::GetPluginName()
+ArchDefaultUnwindPlan_x86_64::GetPluginName()
 {
-    return "ArchDefaultUnwindPlan_x86";
+    return "ArchDefaultUnwindPlan_x86_64";
 }
 
 const char *
-ArchDefaultUnwindPlan_x86::GetShortPluginName()
+ArchDefaultUnwindPlan_x86_64::GetShortPluginName()
 {
-    return "archdefaultunwindplan.x86";
+    return "lldb.arch-default-unwind-plan.x86-64";
 }
 
 
 uint32_t
-ArchDefaultUnwindPlan_x86::GetPluginVersion()
+ArchDefaultUnwindPlan_x86_64::GetPluginVersion()
 {
     return 1;
 }
 
 void
-ArchDefaultUnwindPlan_x86::GetPluginCommandHelp (const char *command, Stream *strm)
+ArchDefaultUnwindPlan_x86_64::GetPluginCommandHelp (const char *command, Stream *strm)
 {
 }
 
 Error
-ArchDefaultUnwindPlan_x86::ExecutePluginCommand (Args &command, Stream *strm)
+ArchDefaultUnwindPlan_x86_64::ExecutePluginCommand (Args &command, Stream *strm)
 {
     Error error;
     error.SetErrorString("No plug-in command are currently supported.");
@@ -124,13 +83,13 @@
 }
 
 Log *
-ArchDefaultUnwindPlan_x86::EnablePluginLogging (Stream *strm, Args &command)
+ArchDefaultUnwindPlan_x86_64::EnablePluginLogging (Stream *strm, Args &command)
 {
     return NULL;
 }
 
 void
-ArchDefaultUnwindPlan_x86::Initialize()
+ArchDefaultUnwindPlan_x86_64::Initialize()
 {
     PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                    GetPluginDescriptionStatic(),
@@ -138,20 +97,135 @@
 }
 
 void
-ArchDefaultUnwindPlan_x86::Terminate()
+ArchDefaultUnwindPlan_x86_64::Terminate()
 {
     PluginManager::UnregisterPlugin (CreateInstance);
 }
 
 
 const char *
-ArchDefaultUnwindPlan_x86::GetPluginNameStatic()
+ArchDefaultUnwindPlan_x86_64::GetPluginNameStatic()
 {
-    return "ArchDefaultUnwindPlan_x86";
+    return "ArchDefaultUnwindPlan_x86_64";
 }
 
 const char *
-ArchDefaultUnwindPlan_x86::GetPluginDescriptionStatic()
+ArchDefaultUnwindPlan_x86_64::GetPluginDescriptionStatic()
 {
-    return "i386 and x86_64 architecture default unwind plan assembly plugin.";
+    return "x86_64 architecture default unwind plan assembly plugin.";
 }
+
+UnwindPlanSP
+ArchDefaultUnwindPlan_x86_64::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc)
+{
+    return m_unwind_plan_sp;
+}
+
+
+
+lldb_private::ArchDefaultUnwindPlan *
+ArchDefaultUnwindPlan_i386::CreateInstance (const lldb_private::ArchSpec &arch)
+{
+    if (arch.GetGenericCPUType () == ArchSpec::eCPU_i386)
+        return new ArchDefaultUnwindPlan_i386 ();
+    return NULL;
+}
+
+ArchDefaultUnwindPlan_i386::ArchDefaultUnwindPlan_i386() :
+                lldb_private::ArchDefaultUnwindPlan(), 
+                m_unwind_plan_sp (new UnwindPlan)
+{ 
+    UnwindPlan::Row row;
+    UnwindPlan::Row::RegisterLocation regloc;
+
+    m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric);
+    row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
+    row.SetCFAOffset (2 * 4);
+    row.SetOffset (0);
+
+    regloc.SetAtCFAPlusOffset (2 * -4);
+    row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc);
+    regloc.SetAtCFAPlusOffset (1 * -4);
+    row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc);
+    regloc.SetIsCFAPlusOffset (0);
+    row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc);
+
+    m_unwind_plan_sp->AppendRow (row);
+    m_unwind_plan_sp->SetSourceName ("i386 architectural default");
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol in UnwindAssemblyParser_x86
+//------------------------------------------------------------------
+
+const char *
+ArchDefaultUnwindPlan_i386::GetPluginName()
+{
+    return "ArchDefaultUnwindPlan_i386";
+}
+
+const char *
+ArchDefaultUnwindPlan_i386::GetShortPluginName()
+{
+    return "archdefaultunwindplan.x86";
+}
+
+
+uint32_t
+ArchDefaultUnwindPlan_i386::GetPluginVersion()
+{
+    return 1;
+}
+
+void
+ArchDefaultUnwindPlan_i386::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+Error
+ArchDefaultUnwindPlan_i386::ExecutePluginCommand (Args &command, Stream *strm)
+{
+    Error error;
+    error.SetErrorString("No plug-in command are currently supported.");
+    return error;
+}
+
+Log *
+ArchDefaultUnwindPlan_i386::EnablePluginLogging (Stream *strm, Args &command)
+{
+    return NULL;
+}
+
+void
+ArchDefaultUnwindPlan_i386::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   GetPluginDescriptionStatic(),
+                                   CreateInstance);
+}
+
+void
+ArchDefaultUnwindPlan_i386::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+
+const char *
+ArchDefaultUnwindPlan_i386::GetPluginNameStatic()
+{
+    return "ArchDefaultUnwindPlan_i386";
+}
+
+const char *
+ArchDefaultUnwindPlan_i386::GetPluginDescriptionStatic()
+{
+    return "i386 architecture default unwind plan assembly plugin.";
+}
+
+UnwindPlanSP
+ArchDefaultUnwindPlan_i386::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc)
+{
+    return m_unwind_plan_sp;
+}
+
diff --git a/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.h b/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.h
index cf0cc05..d3f4b26 100644
--- a/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.h
+++ b/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.h
@@ -17,13 +17,13 @@
 
 namespace lldb_private {
     
-class ArchDefaultUnwindPlan_x86 : public lldb_private::ArchDefaultUnwindPlan
+class ArchDefaultUnwindPlan_x86_64 : public lldb_private::ArchDefaultUnwindPlan
 {
 public:
 
-    ~ArchDefaultUnwindPlan_x86 () { }
+    ~ArchDefaultUnwindPlan_x86_64 () { }
 
-    virtual lldb_private::UnwindPlan*
+    virtual lldb::UnwindPlanSP
     GetArchDefaultUnwindPlan (Thread& thread, Address current_pc);
 
     static lldb_private::ArchDefaultUnwindPlan *
@@ -63,11 +63,60 @@
     EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
 
 private:
-    ArchDefaultUnwindPlan_x86(int cpu);        // Call CreateInstance instead.
+    ArchDefaultUnwindPlan_x86_64();        // Call CreateInstance instead.
 
-    int m_cpu;
-    lldb_private::UnwindPlan m_32bit_default;
-    lldb_private::UnwindPlan m_64bit_default;
+    lldb::UnwindPlanSP m_unwind_plan_sp;
+};
+
+class ArchDefaultUnwindPlan_i386 : public lldb_private::ArchDefaultUnwindPlan
+{
+public:
+
+    ~ArchDefaultUnwindPlan_i386 () { }
+
+    virtual lldb::UnwindPlanSP
+    GetArchDefaultUnwindPlan (Thread& thread, Address current_pc);
+
+    static lldb_private::ArchDefaultUnwindPlan *
+    CreateInstance (const lldb_private::ArchSpec &arch);
+
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static const char *
+    GetPluginNameStatic();
+
+    static const char *
+    GetPluginDescriptionStatic();
+
+    virtual const char *
+    GetPluginName();
+    
+    virtual const char *
+    GetShortPluginName();
+    
+    virtual uint32_t
+    GetPluginVersion();
+    
+    virtual void
+    GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
+    
+    virtual lldb_private::Error
+    ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
+    
+    virtual lldb_private::Log *
+    EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
+
+private:
+    ArchDefaultUnwindPlan_i386();        // Call CreateInstance instead.
+
+    lldb::UnwindPlanSP m_unwind_plan_sp;
 };
 
 
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index c508b86..621d7fc 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -34,7 +34,7 @@
 RegisterContextLLDB::RegisterContextLLDB 
 (
     Thread& thread, 
-    const RegisterContextSP &next_frame,
+    const SharedPtr &next_frame,
     SymbolContext& sym_ctx,
     uint32_t frame_number
 ) :
@@ -48,8 +48,8 @@
     m_start_pc (), 
     m_current_pc (), 
     m_frame_number (frame_number),
-    m_full_unwind_plan(NULL), 
-    m_fast_unwind_plan(NULL), 
+    m_full_unwind_plan_sp (), 
+    m_fast_unwind_plan_sp (), 
     m_frame_type (-1), 
     m_current_offset (0), 
     m_current_offset_backed_up_one (0), 
@@ -68,20 +68,9 @@
     }
 
     // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet
-    bool behaves_like_zeroth_frame = false;
-    if (IsFrameZero())
-    {
-        behaves_like_zeroth_frame = true;
-    }
-    if (!IsFrameZero() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame)
-    {
-        behaves_like_zeroth_frame = true;
-    }
-    if (!IsFrameZero() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame)
-    {
-        behaves_like_zeroth_frame = true;
-    }
-    if (behaves_like_zeroth_frame)
+    if (IsFrameZero() 
+        || m_next_frame->m_frame_type == eSigtrampFrame 
+        || m_next_frame->m_frame_type == eDebuggerFrame)
     {
         m_all_registers_available = true;
     }
@@ -124,6 +113,7 @@
     if (addr_range.GetBaseAddress().IsValid())
     {
         m_start_pc = addr_range.GetBaseAddress();
+        assert (frame_sp->GetFrameCodeAddress().GetSection() == m_start_pc.GetSection());
         m_current_offset = frame_sp->GetFrameCodeAddress().GetOffset() - m_start_pc.GetOffset();
         m_current_offset_backed_up_one = m_current_offset;
     }
@@ -136,16 +126,16 @@
 
     // We've set m_frame_type and m_sym_ctx before these calls.
 
-    m_fast_unwind_plan = GetFastUnwindPlanForFrame ();
-    m_full_unwind_plan = GetFullUnwindPlanForFrame (); 
-
+    m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
+    m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); 
+    
     const UnwindPlan::Row *active_row = NULL;
     int cfa_offset = 0;
     int row_register_kind;
-    if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (m_current_pc))
+    if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
     {
-        active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
-        row_register_kind = m_full_unwind_plan->GetRegisterKind ();
+        active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
+        row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
     }
 
     if (active_row == NULL)
@@ -189,7 +179,7 @@
                     m_frame_number,
                     (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), 
                     (uint64_t) m_cfa,
-                    m_full_unwind_plan->GetSourceName().GetCString());
+                    m_full_unwind_plan_sp->GetSourceName().GetCString());
     }
 }
 
@@ -205,7 +195,8 @@
         m_frame_type = eNotAValidFrame;
         return;
     }
-    if (!((RegisterContextLLDB*)m_next_frame.get())->IsValid())
+    
+    if (!m_next_frame->IsValid())
     {
         m_frame_type = eNotAValidFrame;
         return;
@@ -244,20 +235,20 @@
             log->Printf("%*sFrame %u using architectural default unwind method",
                         m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
         }
-        ArchSpec arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
-        ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch);
-        if (arch_default)
+        const ArchSpec &arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
+        ArchDefaultUnwindPlanSP arch_default_sp (ArchDefaultUnwindPlan::FindPlugin (arch));
+        if (arch_default_sp)
         {
-            m_fast_unwind_plan = NULL;
-            m_full_unwind_plan = arch_default->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
+            m_fast_unwind_plan_sp.reset();
+            m_full_unwind_plan_sp = arch_default_sp->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
             m_frame_type = eNormalFrame;
             m_all_registers_available = false;
             m_current_offset = -1;
             m_current_offset_backed_up_one = -1;
             addr_t cfa_regval;
-            int row_register_kind = m_full_unwind_plan->GetRegisterKind ();
-            uint32_t cfa_regnum = m_full_unwind_plan->GetRowForFunctionOffset(0)->GetCFARegister();
-            int cfa_offset = m_full_unwind_plan->GetRowForFunctionOffset(0)->GetCFAOffset();
+            int row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
+            uint32_t cfa_regnum = m_full_unwind_plan_sp->GetRowForFunctionOffset(0)->GetCFARegister();
+            int cfa_offset = m_full_unwind_plan_sp->GetRowForFunctionOffset(0)->GetCFAOffset();
             if (!ReadGPRValue (row_register_kind, cfa_regnum, cfa_regval))
             {
                 if (log)
@@ -315,8 +306,8 @@
     // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp),
     // and our "current" pc is the start of a function...
     if (m_sym_ctx_valid
-        && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type != eSigtrampFrame
-        && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type != eDebuggerFrame
+        && m_next_frame->m_frame_type != eSigtrampFrame
+        && m_next_frame->m_frame_type != eDebuggerFrame
         && addr_range.GetBaseAddress().IsValid()
         && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection()
         && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset())
@@ -374,7 +365,7 @@
     }
 
     // We've set m_frame_type and m_sym_ctx before this call.
-    m_fast_unwind_plan = GetFastUnwindPlanForFrame ();
+    m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
 
     const UnwindPlan::Row *active_row = NULL;
     int cfa_offset = 0;
@@ -383,18 +374,18 @@
     // Try to get by with just the fast UnwindPlan if possible - the full UnwindPlan may be expensive to get
     // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for the first time.)
 
-    if (m_fast_unwind_plan && m_fast_unwind_plan->PlanValidAtAddress (m_current_pc))
+    if (m_fast_unwind_plan_sp && m_fast_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
     {
-        active_row = m_fast_unwind_plan->GetRowForFunctionOffset (m_current_offset);
-        row_register_kind = m_fast_unwind_plan->GetRegisterKind ();
+        active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
+        row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind ();
     }
     else 
     {
-        m_full_unwind_plan = GetFullUnwindPlanForFrame ();
-        if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (m_current_pc))
+        m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
+        if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
         {
-            active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
-            row_register_kind = m_full_unwind_plan->GetRegisterKind ();
+            active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
+            row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
         }
     }
 
@@ -460,49 +451,47 @@
 //   3. m_current_pc should have the current pc value for this frame
 //   4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
 
-UnwindPlan *
+UnwindPlanSP
 RegisterContextLLDB::GetFastUnwindPlanForFrame ()
 {
+    UnwindPlanSP unwind_plan_sp;
     if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL)
-    {
-        return NULL;
-    }
+        return unwind_plan_sp;
 
     if (IsFrameZero ())
-    {
-        return NULL;
-    }
+        return unwind_plan_sp;
 
-    FuncUnwindersSP fu;
-    fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
-    if (fu.get() == NULL)
-    {
-        return NULL;
-    }
+    FuncUnwindersSP func_unwinders_sp (m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx));
+    if (!func_unwinders_sp)
+        return unwind_plan_sp;
 
     // If we're in _sigtramp(), unwinding past this frame requires special knowledge.  
     if (m_frame_type == eSigtrampFrame || m_frame_type == eDebuggerFrame)
-    {
-        return NULL;
-    }
+        return unwind_plan_sp;
 
-    if (fu->GetUnwindPlanFastUnwind (m_thread) 
-        && fu->GetUnwindPlanFastUnwind (m_thread)->PlanValidAtAddress (m_current_pc))
+    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (m_thread);
+    if (unwind_plan_sp)
     {
-        LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-        if (log && IsLogVerbose())
+        if (unwind_plan_sp->PlanValidAtAddress (m_current_pc))
         {
-            const char *has_fast = "";
-            if (m_fast_unwind_plan)
-                has_fast = ", and has a fast UnwindPlan";
-            log->Printf("%*sFrame %u frame has a fast UnwindPlan",
-                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
+            LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+            if (log && IsLogVerbose())
+            {
+                const char *has_fast = "";
+                if (m_fast_unwind_plan_sp)
+                    has_fast = ", and has a fast UnwindPlan";
+                log->Printf("%*sFrame %u frame has a fast UnwindPlan",
+                            m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
+            }
+            m_frame_type = eNormalFrame;
+            return unwind_plan_sp;
         }
-        m_frame_type = eNormalFrame;
-        return fu->GetUnwindPlanFastUnwind (m_thread);
+        else 
+        {
+            unwind_plan_sp.reset();
+        }
     }
-
-    return NULL;
+    return unwind_plan_sp;
 }
 
 // On entry to this method, 
@@ -512,37 +501,25 @@
 //   3. m_current_pc should have the current pc value for this frame
 //   4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
 
-UnwindPlan *
+UnwindPlanSP
 RegisterContextLLDB::GetFullUnwindPlanForFrame ()
 {
+    UnwindPlanSP unwind_plan_sp;
     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-    UnwindPlan *up;
-    UnwindPlan *arch_default_up = NULL;
-    ArchSpec arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
-    ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch);
-    if (arch_default)
-    {
-        arch_default_up = arch_default->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
-    }
+    UnwindPlanSP arch_default_unwind_plan_sp;
+    const ArchSpec &arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
+    ArchDefaultUnwindPlanSP arch_default_sp (ArchDefaultUnwindPlan::FindPlugin (arch));
+    if (arch_default_sp)
+        arch_default_unwind_plan_sp = arch_default_sp->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
 
     bool behaves_like_zeroth_frame = false;
-    if (IsFrameZero ())
+    if (IsFrameZero () 
+        || m_next_frame->m_frame_type == eSigtrampFrame
+        || m_next_frame->m_frame_type == eDebuggerFrame)
     {
         behaves_like_zeroth_frame = true;
-    }
-    if (!IsFrameZero () && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame)
-    {
-        behaves_like_zeroth_frame = true;
-    }
-    if (!IsFrameZero () && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame)
-    {
-        behaves_like_zeroth_frame = true;
-    }
-
-    // If this frame behaves like a 0th frame (currently executing or interrupted asynchronously), all registers
-    // can be retrieved.
-    if (behaves_like_zeroth_frame)
-    {
+        // If this frame behaves like a 0th frame (currently executing or 
+        // interrupted asynchronously), all registers can be retrieved.
         m_all_registers_available = true;
     }
 
@@ -550,20 +527,20 @@
     if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL)
     {
         m_frame_type = eNormalFrame;
-        return arch_default_up;
+        return arch_default_unwind_plan_sp;
     }
 
-    FuncUnwindersSP fu;
+    FuncUnwindersSP func_unwinders_sp;
     if (m_sym_ctx_valid)
     {
-        fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
+        func_unwinders_sp = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
     }
 
     // No FuncUnwinders available for this pc, try using architectural default unwind.
-    if (fu.get() == NULL)
+    if (!func_unwinders_sp)
     {
         m_frame_type = eNormalFrame;
-        return arch_default_up;
+        return arch_default_unwind_plan_sp;
     }
 
     // If we're in _sigtramp(), unwinding past this frame requires special knowledge.  On Mac OS X this knowledge
@@ -572,53 +549,54 @@
     // how to unwind out of sigtramp.
     if (m_frame_type == eSigtrampFrame)
     {
-        m_fast_unwind_plan = NULL;
-        up = fu->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
-        if (up && up->PlanValidAtAddress (m_current_pc))
-        {
-            return up;
-        }
+        m_fast_unwind_plan_sp.reset();
+        unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
+        if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
+            return unwind_plan_sp;
     }
 
     
     // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions
-    up = fu->GetUnwindPlanAtNonCallSite (m_thread);
-    if (behaves_like_zeroth_frame && up && up->PlanValidAtAddress (m_current_pc))
+    if (behaves_like_zeroth_frame)
     {
-        if (log && IsLogVerbose())
+        unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread);
+        if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
         {
-            log->Printf("%*sFrame %u frame uses %s for full UnwindPlan",
-                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                        up->GetSourceName().GetCString());
+            if (log && IsLogVerbose())
+            {
+                log->Printf("%*sFrame %u frame uses %s for full UnwindPlan",
+                            m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                            unwind_plan_sp->GetSourceName().GetCString());
+            }
+            return unwind_plan_sp;
         }
-        return up;
     }
 
     // Typically this is unwind info from an eh_frame section intended for exception handling; only valid at call sites
-    up = fu->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
-    if (up && up->PlanValidAtAddress (m_current_pc))
+    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
+    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
     {
         if (log && IsLogVerbose())
         {
             log->Printf("%*sFrame %u frame uses %s for full UnwindPlan",
                         m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                        up->GetSourceName().GetCString());
+                        unwind_plan_sp->GetSourceName().GetCString());
         }
-        return up;
+        return unwind_plan_sp;
     }
     
     // We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've
     // struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible.
-    up = fu->GetUnwindPlanAtNonCallSite (m_thread);
-    if (up && up->PlanValidAtAddress (m_current_pc))
+    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread);
+    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
     {
         if (log && IsLogVerbose())
         {
             log->Printf("%*sFrame %u frame uses %s for full UnwindPlan",
                         m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                        up->GetSourceName().GetCString());
+                        unwind_plan_sp->GetSourceName().GetCString());
         }
-        return up;
+        return unwind_plan_sp;
     }
 
     // If nothing else, use the architectural default UnwindPlan and hope that does the job.
@@ -626,9 +604,9 @@
     {
         log->Printf("%*sFrame %u frame uses %s for full UnwindPlan",
                     m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                    arch_default_up->GetSourceName().GetCString());
+                    arch_default_unwind_plan_sp->GetSourceName().GetCString());
     }
-    return arch_default_up;
+    return arch_default_unwind_plan_sp;
 }
 
 
@@ -812,9 +790,9 @@
     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
 
     // Have we already found this register location?
-    std::map<uint32_t, RegisterLocation>::const_iterator iterator;
-    if (m_registers.size() > 0)
+    if (!m_registers.empty())
     {
+        std::map<uint32_t, RegisterLocation>::const_iterator iterator;
         iterator = m_registers.find (lldb_regnum);
         if (iterator != m_registers.end())
         {
@@ -843,10 +821,10 @@
     bool have_unwindplan_regloc = false;
     int unwindplan_registerkind = -1;
 
-    if (m_fast_unwind_plan)
+    if (m_fast_unwind_plan_sp)
     {
-        const UnwindPlan::Row *active_row = m_fast_unwind_plan->GetRowForFunctionOffset (m_current_offset);
-        unwindplan_registerkind = m_fast_unwind_plan->GetRegisterKind ();
+        const UnwindPlan::Row *active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
+        unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind ();
         uint32_t row_regnum;
         if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
         {
@@ -872,15 +850,14 @@
 
     if (!have_unwindplan_regloc)
     {
-        // m_full_unwind_plan being NULL means that we haven't tried to find a full UnwindPlan yet
-        if (m_full_unwind_plan == NULL)
+        // m_full_unwind_plan_sp being NULL means that we haven't tried to find a full UnwindPlan yet
+        if (!m_full_unwind_plan_sp)
+            m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
+
+        if (m_full_unwind_plan_sp)
         {
-            m_full_unwind_plan = GetFullUnwindPlanForFrame ();
-        }
-        if (m_full_unwind_plan)
-        {
-            const UnwindPlan::Row *active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
-            unwindplan_registerkind = m_full_unwind_plan->GetRegisterKind ();
+            const UnwindPlan::Row *active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
+            unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
             uint32_t row_regnum;
             if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
             {
@@ -905,7 +882,7 @@
                 {                
                     log->Printf("%*sFrame %u supplying caller's saved reg %d's location using %s UnwindPlan",
                                 m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                                lldb_regnum, m_full_unwind_plan->GetSourceName().GetCString());
+                                lldb_regnum, m_full_unwind_plan_sp->GetSourceName().GetCString());
                 }
             }
         }
@@ -915,7 +892,7 @@
     {
         // If a volatile register is being requested, we don't want to forward m_next_frame's register contents 
         // up the stack -- the register is not retrievable at this frame.
-        ArchSpec arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
+        const ArchSpec &arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
         ArchVolatileRegs *volatile_regs = ArchVolatileRegs::FindPlugin (arch);
         if (volatile_regs && volatile_regs->RegisterIsVolatile (m_thread, lldb_regnum))
         {
@@ -928,11 +905,7 @@
             return false;
         }  
 
-        if (!IsFrameZero ())
-        {
-            return ((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc);
-        }
-        else
+        if (IsFrameZero ())
         {
             // This is frame 0 - we should return the actual live register context value
             RegisterLocation new_regloc;
@@ -942,6 +915,10 @@
             regloc = new_regloc;
             return true;
         }
+        else
+        {
+            return m_next_frame->SavedLocationForRegister (lldb_regnum, regloc);
+        }
         if (log)
         {
             log->Printf("%*sFrame %u could not supply caller's reg %d location",
@@ -968,11 +945,7 @@
 
     if (unwindplan_regloc.IsSame())
     {
-        if (!IsFrameZero ())
-        {
-            return ((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc);
-        }
-        else
+        if (IsFrameZero ())
         {
             if (log)
             {
@@ -982,6 +955,10 @@
             }
             return false;
         }
+        else
+        {
+            return m_next_frame->SavedLocationForRegister (lldb_regnum, regloc);
+        }
     }
 
     if (unwindplan_regloc.IsCFAPlusOffset())
@@ -1116,14 +1093,11 @@
             value = data.GetAddress (&offset);
             return true;
         }
-        else
-        {
-            return false;
-        }
+        return false;
     }
 
     RegisterLocation regloc;
-    if (!((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc))
+    if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc))
     {
         return false;
     }
@@ -1166,7 +1140,7 @@
 
     RegisterLocation regloc;
     // Find out where the NEXT frame saved THIS frame's register contents
-    if (!((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_reg, regloc))
+    if (!m_next_frame->SavedLocationForRegister (lldb_reg, regloc))
         return false;
 
     return ReadRegisterBytesFromRegisterLocation (lldb_reg, regloc, data);
@@ -1200,7 +1174,7 @@
 
     RegisterLocation regloc;
     // Find out where the NEXT frame saved THIS frame's register contents
-    if (!((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_reg, regloc))
+    if (!m_next_frame->SavedLocationForRegister (lldb_reg, regloc))
         return false;
 
     return WriteRegisterBytesToRegisterLocation (lldb_reg, regloc, data, data_offset);
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
index ba0e052..f75a9b8 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -20,8 +20,10 @@
 class RegisterContextLLDB : public lldb_private::RegisterContext
 {
 public:
+    typedef lldb::SharedPtr<RegisterContextLLDB>::Type SharedPtr;
+
     RegisterContextLLDB (lldb_private::Thread &thread,
-                         const lldb::RegisterContextSP& next_frame,
+                         const SharedPtr& next_frame,
                          lldb_private::SymbolContext& sym_ctx,
                          uint32_t frame_number);
 
@@ -147,22 +149,23 @@
     bool
     ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value);
 
-    lldb_private::UnwindPlan *
+    lldb::UnwindPlanSP
     GetFastUnwindPlanForFrame ();
 
-    lldb_private::UnwindPlan *
+    lldb::UnwindPlanSP
     GetFullUnwindPlanForFrame ();
 
     lldb_private::Thread& m_thread;
-    lldb::RegisterContextSP m_next_frame;
+    
+    SharedPtr m_next_frame;
 
     ///
     // The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above)
     // i.e. where THIS frame saved them
     ///
 
-    lldb_private::UnwindPlan *m_fast_unwind_plan;  // may be NULL
-    lldb_private::UnwindPlan *m_full_unwind_plan;
+    lldb::UnwindPlanSP m_fast_unwind_plan_sp;  // may be NULL
+    lldb::UnwindPlanSP m_full_unwind_plan_sp;
     bool m_all_registers_available;               // Can we retrieve all regs or just nonvolatile regs?
     int m_frame_type;                             // enum FrameType
 
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 533c21c..e972c84 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -15,10 +15,12 @@
 #include "lldb/Symbol/FuncUnwinders.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Utility/ArchDefaultUnwindPlan.h"
-#include "UnwindLLDB.h"
 #include "lldb/Symbol/UnwindPlan.h"
 #include "lldb/Core/Log.h"
 
+#include "UnwindLLDB.h"
+#include "RegisterContextLLDB.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -65,8 +67,10 @@
 {
     // First, set up the 0th (initial) frame
     CursorSP first_cursor_sp(new Cursor ());
-    RegisterContextSP no_frame; 
-    std::auto_ptr<RegisterContextLLDB> first_register_ctx_ap (new RegisterContextLLDB(m_thread, no_frame, first_cursor_sp->sctx, 0));
+    std::auto_ptr<RegisterContextLLDB> first_register_ctx_ap (new RegisterContextLLDB (m_thread, 
+                                                                                       RegisterContextLLDB::SharedPtr(), 
+                                                                                       first_cursor_sp->sctx, 
+                                                                                       0));
     if (first_register_ctx_ap.get() == NULL)
         return false;
     
@@ -150,8 +154,8 @@
             return false;
         }
     }
-    RegisterContextSP register_ctx_sp(register_ctx_ap.release());
-    cursor_sp->reg_ctx = register_ctx_sp;
+    RegisterContextLLDB::SharedPtr reg_ctx_sp(register_ctx_ap.release());
+    cursor_sp->reg_ctx = reg_ctx_sp;
     m_frames.push_back (cursor_sp);
     return true;
 }
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
index 7d1f070..1c01a3d 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -10,15 +10,15 @@
 #ifndef lldb_UnwindLLDB_h_
 #define lldb_UnwindLLDB_h_
 
-#include "lldb/lldb-private.h"
-#include "lldb/lldb-types.h"
-#include "lldb/Target/Unwind.h"
-#include "lldb/Symbol/FuncUnwinders.h"
-#include "lldb/Symbol/UnwindPlan.h"
-#include "RegisterContextLLDB.h"
-#include "lldb/Target/RegisterContext.h"
 #include <vector>
 
+#include "lldb/lldb-include.h"
+#include "lldb/Symbol/FuncUnwinders.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Unwind.h"
+
+#include "RegisterContextLLDB.h"
 
 namespace lldb_private {
 
@@ -53,7 +53,7 @@
         lldb::addr_t start_pc;  // The start address of the function/symbol for this frame - current pc if unknown
         lldb::addr_t cfa;       // The canonical frame address for this stack frame
         lldb_private::SymbolContext sctx;  // A symbol context we'll contribute to & provide to the StackFrame creation
-        lldb::RegisterContextSP reg_ctx; // These are all RegisterContextLLDB's
+        RegisterContextLLDB::SharedPtr reg_ctx; // These are all RegisterContextLLDB's
 
         Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx() { }
     private: