[Lldb-commits] [lldb] [lldb] Return *const* UnwindPlan pointers from FuncUnwinders (PR #133247)

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Thu Mar 27 06:39:15 PDT 2025


https://github.com/labath updated https://github.com/llvm/llvm-project/pull/133247

>From f4f4d06e485b5d7d28ef2a45ae53d630df5da1c1 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Thu, 27 Mar 2025 13:53:57 +0100
Subject: [PATCH] [lldb] Return *const* UnwindPlan pointers from FuncUnwinders

These plans are cached and accessed from multiple threads. Modifying
them would be a Bad Idea(tm).
---
 lldb/include/lldb/Symbol/FuncUnwinders.h      |  78 +++----
 lldb/include/lldb/Symbol/UnwindPlan.h         |   4 +-
 .../lldb/Target/RegisterContextUnwind.h       |  16 +-
 lldb/source/Commands/CommandObjectTarget.cpp  | 106 +++++----
 lldb/source/Symbol/FuncUnwinders.cpp          | 207 +++++++++---------
 lldb/source/Symbol/UnwindPlan.cpp             |   2 +-
 lldb/source/Target/RegisterContextUnwind.cpp  |  84 ++++---
 7 files changed, 247 insertions(+), 250 deletions(-)

diff --git a/lldb/include/lldb/Symbol/FuncUnwinders.h b/lldb/include/lldb/Symbol/FuncUnwinders.h
index 1d4c28324e90f..479ccf87b6e2c 100644
--- a/lldb/include/lldb/Symbol/FuncUnwinders.h
+++ b/lldb/include/lldb/Symbol/FuncUnwinders.h
@@ -36,18 +36,19 @@ class FuncUnwinders {
 
   ~FuncUnwinders();
 
-  lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target, Thread &thread);
+  std::shared_ptr<const UnwindPlan> GetUnwindPlanAtCallSite(Target &target,
+                                                            Thread &thread);
 
-  lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target,
-                                                lldb_private::Thread &thread);
+  std::shared_ptr<const UnwindPlan>
+  GetUnwindPlanAtNonCallSite(Target &target, lldb_private::Thread &thread);
 
-  lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target,
-                                             lldb_private::Thread &thread);
+  std::shared_ptr<const UnwindPlan>
+  GetUnwindPlanFastUnwind(Target &target, lldb_private::Thread &thread);
 
-  lldb::UnwindPlanSP
+  std::shared_ptr<const UnwindPlan>
   GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread);
 
-  lldb::UnwindPlanSP
+  std::shared_ptr<const UnwindPlan>
   GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread);
 
   Address &GetFirstNonPrologueInsn(Target &target);
@@ -77,32 +78,34 @@ class FuncUnwinders {
   // used. Instead, clients should ask for the *behavior* they are looking for,
   // using one of the above UnwindPlan retrieval methods.
 
-  lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread);
+  std::shared_ptr<const UnwindPlan> GetAssemblyUnwindPlan(Target &target,
+                                                          Thread &thread);
 
-  lldb::UnwindPlanSP GetObjectFileUnwindPlan(Target &target);
+  std::shared_ptr<const UnwindPlan> GetObjectFileUnwindPlan(Target &target);
 
-  lldb::UnwindPlanSP GetObjectFileAugmentedUnwindPlan(Target &target,
-                                                      Thread &thread);
+  std::shared_ptr<const UnwindPlan>
+  GetObjectFileAugmentedUnwindPlan(Target &target, Thread &thread);
 
-  lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target);
+  std::shared_ptr<const UnwindPlan> GetEHFrameUnwindPlan(Target &target);
 
-  lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target,
-                                                   Thread &thread);
+  std::shared_ptr<const UnwindPlan>
+  GetEHFrameAugmentedUnwindPlan(Target &target, Thread &thread);
 
-  lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target);
+  std::shared_ptr<const UnwindPlan> GetDebugFrameUnwindPlan(Target &target);
 
-  lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target,
-                                                      Thread &thread);
+  std::shared_ptr<const UnwindPlan>
+  GetDebugFrameAugmentedUnwindPlan(Target &target, Thread &thread);
 
-  lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target);
+  std::shared_ptr<const UnwindPlan> GetCompactUnwindUnwindPlan(Target &target);
 
-  lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target);
+  std::shared_ptr<const UnwindPlan> GetArmUnwindUnwindPlan(Target &target);
 
-  lldb::UnwindPlanSP GetSymbolFileUnwindPlan(Thread &thread);
+  std::shared_ptr<const UnwindPlan> GetSymbolFileUnwindPlan(Thread &thread);
 
-  lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread);
+  std::shared_ptr<const UnwindPlan> GetArchDefaultUnwindPlan(Thread &thread);
 
-  lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread);
+  std::shared_ptr<const UnwindPlan>
+  GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread);
 
 private:
   lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target);
@@ -113,7 +116,8 @@ class FuncUnwinders {
   // unwind rule for the pc, and LazyBoolCalculate if it was unable to
   // determine this for some reason.
   lldb_private::LazyBool CompareUnwindPlansForIdenticalInitialPCLocation(
-      Thread &thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b);
+      Thread &thread, const std::shared_ptr<const UnwindPlan> &a,
+      const std::shared_ptr<const UnwindPlan> &b);
 
   UnwindTable &m_unwind_table;
 
@@ -129,22 +133,22 @@ class FuncUnwinders {
 
   std::recursive_mutex m_mutex;
 
-  lldb::UnwindPlanSP m_unwind_plan_assembly_sp;
-  lldb::UnwindPlanSP m_unwind_plan_object_file_sp;
-  lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp;
-  lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_assembly_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_object_file_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_eh_frame_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_debug_frame_sp;
 
   // augmented by assembly inspection so it's valid everywhere
-  lldb::UnwindPlanSP m_unwind_plan_object_file_augmented_sp;
-  lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp;
-  lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp;
-
-  std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind;
-  lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp;
-  lldb::UnwindPlanSP m_unwind_plan_symbol_file_sp;
-  lldb::UnwindPlanSP m_unwind_plan_fast_sp;
-  lldb::UnwindPlanSP m_unwind_plan_arch_default_sp;
-  lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_object_file_augmented_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_eh_frame_augmented_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_debug_frame_augmented_sp;
+
+  std::vector<std::shared_ptr<const UnwindPlan>> m_unwind_plan_compact_unwind;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_arm_unwind_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_symbol_file_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_fast_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_arch_default_sp;
+  std::shared_ptr<const UnwindPlan> m_unwind_plan_arch_default_at_func_entry_sp;
 
   // Fetching the UnwindPlans can be expensive - if we've already attempted to
   // get one & failed, don't try again.
diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h
index ddc54a9fdc8ae..80517de5a7e9c 100644
--- a/lldb/include/lldb/Symbol/UnwindPlan.h
+++ b/lldb/include/lldb/Symbol/UnwindPlan.h
@@ -464,7 +464,7 @@ class UnwindPlan {
     m_return_addr_register = regnum;
   }
 
-  uint32_t GetReturnAddressRegister() { return m_return_addr_register; }
+  uint32_t GetReturnAddressRegister() const { return m_return_addr_register; }
 
   uint32_t GetInitialCFARegister() const {
     if (m_row_list.empty())
@@ -479,7 +479,7 @@ class UnwindPlan {
     m_plan_valid_ranges = std::move(ranges);
   }
 
-  bool PlanValidAtAddress(Address addr);
+  bool PlanValidAtAddress(Address addr) const;
 
   bool IsValidRowIndex(uint32_t idx) const;
 
diff --git a/lldb/include/lldb/Target/RegisterContextUnwind.h b/lldb/include/lldb/Target/RegisterContextUnwind.h
index 6cd918fedc003..98e25859d4eab 100644
--- a/lldb/include/lldb/Target/RegisterContextUnwind.h
+++ b/lldb/include/lldb/Target/RegisterContextUnwind.h
@@ -127,7 +127,8 @@ class RegisterContextUnwind : public lldb_private::RegisterContext {
 
   /// Check if the given unwind plan indicates a signal trap handler, and
   /// update frame type and symbol context if so.
-  void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan);
+  void PropagateTrapHandlerFlagFromUnwindPlan(
+      std::shared_ptr<const UnwindPlan> unwind_plan);
 
   // Provide a location for where THIS function saved the CALLER's register
   // value
@@ -194,16 +195,17 @@ class RegisterContextUnwind : public lldb_private::RegisterContext {
                         const UnwindPlan::Row::FAValue &fa,
                         lldb::addr_t &address);
 
-  lldb::UnwindPlanSP GetFastUnwindPlanForFrame();
+  std::shared_ptr<const UnwindPlan> GetFastUnwindPlanForFrame();
 
-  lldb::UnwindPlanSP GetFullUnwindPlanForFrame();
+  std::shared_ptr<const UnwindPlan> GetFullUnwindPlanForFrame();
 
   void UnwindLogMsg(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
 
   void UnwindLogMsgVerbose(const char *fmt, ...)
       __attribute__((format(printf, 2, 3)));
 
-  bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp);
+  bool IsUnwindPlanValidForCurrentPC(
+      std::shared_ptr<const UnwindPlan> unwind_plan_sp);
 
   lldb::addr_t GetReturnAddressHint(int32_t plan_offset);
 
@@ -215,9 +217,9 @@ class RegisterContextUnwind : public lldb_private::RegisterContext {
   // i.e. where THIS frame saved them
   ///
 
-  lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL
-  lldb::UnwindPlanSP m_full_unwind_plan_sp;
-  lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL
+  std::shared_ptr<const UnwindPlan> m_fast_unwind_plan_sp; // may be NULL
+  std::shared_ptr<const UnwindPlan> m_full_unwind_plan_sp;
+  std::shared_ptr<const UnwindPlan> m_fallback_unwind_plan_sp; // may be NULL
 
   bool m_all_registers_available; // Can we retrieve all regs or just
                                   // nonvolatile regs?
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index c77bddb4af061..3f7d3007ed168 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -3641,77 +3641,70 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
 
       result.GetOutputStream().Printf("\n");
 
-      UnwindPlanSP non_callsite_unwind_plan =
-          func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
-      if (non_callsite_unwind_plan) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread)) {
         result.GetOutputStream().Printf(
             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
-            non_callsite_unwind_plan->GetSourceName().AsCString());
+            plan_sp->GetSourceName().AsCString());
       }
-      UnwindPlanSP callsite_unwind_plan =
-          func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
-      if (callsite_unwind_plan) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread)) {
         result.GetOutputStream().Printf(
             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
-            callsite_unwind_plan->GetSourceName().AsCString());
+            plan_sp->GetSourceName().AsCString());
       }
-      UnwindPlanSP fast_unwind_plan =
-          func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
-      if (fast_unwind_plan) {
-        result.GetOutputStream().Printf(
-            "Fast UnwindPlan is '%s'\n",
-            fast_unwind_plan->GetSourceName().AsCString());
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
+        result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n",
+                                        plan_sp->GetSourceName().AsCString());
       }
 
       result.GetOutputStream().Printf("\n");
 
-      UnwindPlanSP assembly_sp =
-          func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
-      if (assembly_sp) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread)) {
         result.GetOutputStream().Printf(
             "Assembly language inspection UnwindPlan:\n");
-        assembly_sp->Dump(result.GetOutputStream(), thread.get(),
-                          LLDB_INVALID_ADDRESS);
+        plan_sp->Dump(result.GetOutputStream(), thread.get(),
+                      LLDB_INVALID_ADDRESS);
         result.GetOutputStream().Printf("\n");
       }
 
-      UnwindPlanSP of_unwind_sp =
-          func_unwinders_sp->GetObjectFileUnwindPlan(*target);
-      if (of_unwind_sp) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetObjectFileUnwindPlan(*target)) {
         result.GetOutputStream().Printf("object file UnwindPlan:\n");
-        of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
-                           LLDB_INVALID_ADDRESS);
+        plan_sp->Dump(result.GetOutputStream(), thread.get(),
+                      LLDB_INVALID_ADDRESS);
         result.GetOutputStream().Printf("\n");
       }
 
-      UnwindPlanSP of_unwind_augmented_sp =
-          func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
-      if (of_unwind_augmented_sp) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target,
+                                                                  *thread)) {
         result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
-        of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
-                                     LLDB_INVALID_ADDRESS);
+        plan_sp->Dump(result.GetOutputStream(), thread.get(),
+                      LLDB_INVALID_ADDRESS);
         result.GetOutputStream().Printf("\n");
       }
 
-      UnwindPlanSP ehframe_sp =
-          func_unwinders_sp->GetEHFrameUnwindPlan(*target);
-      if (ehframe_sp) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetEHFrameUnwindPlan(*target)) {
         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
-        ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
-                         LLDB_INVALID_ADDRESS);
+        plan_sp->Dump(result.GetOutputStream(), thread.get(),
+                      LLDB_INVALID_ADDRESS);
         result.GetOutputStream().Printf("\n");
       }
 
-      UnwindPlanSP ehframe_augmented_sp =
-          func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
-      if (ehframe_augmented_sp) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target,
+                                                               *thread)) {
         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
-        ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
-                                   LLDB_INVALID_ADDRESS);
+        plan_sp->Dump(result.GetOutputStream(), thread.get(),
+                      LLDB_INVALID_ADDRESS);
         result.GetOutputStream().Printf("\n");
       }
 
-      if (UnwindPlanSP plan_sp =
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
               func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
         plan_sp->Dump(result.GetOutputStream(), thread.get(),
@@ -3719,7 +3712,7 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
         result.GetOutputStream().Printf("\n");
       }
 
-      if (UnwindPlanSP plan_sp =
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
                                                                   *thread)) {
         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
@@ -3728,36 +3721,35 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
         result.GetOutputStream().Printf("\n");
       }
 
-      UnwindPlanSP arm_unwind_sp =
-          func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
-      if (arm_unwind_sp) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetArmUnwindUnwindPlan(*target)) {
         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
-        arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
-                            LLDB_INVALID_ADDRESS);
+        plan_sp->Dump(result.GetOutputStream(), thread.get(),
+                      LLDB_INVALID_ADDRESS);
         result.GetOutputStream().Printf("\n");
       }
 
-      if (UnwindPlanSP symfile_plan_sp =
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
               func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
         result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
-        symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
-                              LLDB_INVALID_ADDRESS);
+        plan_sp->Dump(result.GetOutputStream(), thread.get(),
+                      LLDB_INVALID_ADDRESS);
         result.GetOutputStream().Printf("\n");
       }
 
-      UnwindPlanSP compact_unwind_sp =
-          func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
-      if (compact_unwind_sp) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetCompactUnwindUnwindPlan(*target)) {
         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
-        compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
-                                LLDB_INVALID_ADDRESS);
+        plan_sp->Dump(result.GetOutputStream(), thread.get(),
+                      LLDB_INVALID_ADDRESS);
         result.GetOutputStream().Printf("\n");
       }
 
-      if (fast_unwind_plan) {
+      if (std::shared_ptr<const UnwindPlan> plan_sp =
+              func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
         result.GetOutputStream().Printf("Fast UnwindPlan:\n");
-        fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
-                               LLDB_INVALID_ADDRESS);
+        plan_sp->Dump(result.GetOutputStream(), thread.get(),
+                      LLDB_INVALID_ADDRESS);
         result.GetOutputStream().Printf("\n");
       }
 
diff --git a/lldb/source/Symbol/FuncUnwinders.cpp b/lldb/source/Symbol/FuncUnwinders.cpp
index a5ca7b094c949..a74029d8343c7 100644
--- a/lldb/source/Symbol/FuncUnwinders.cpp
+++ b/lldb/source/Symbol/FuncUnwinders.cpp
@@ -71,40 +71,47 @@ FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, Address addr,
 
 FuncUnwinders::~FuncUnwinders() = default;
 
-UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target,
-                                                    Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetUnwindPlanAtCallSite(Target &target, Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
 
-  if (UnwindPlanSP plan_sp = GetObjectFileUnwindPlan(target))
+  if (std::shared_ptr<const UnwindPlan> plan_sp =
+          GetObjectFileUnwindPlan(target))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread))
+  if (std::shared_ptr<const UnwindPlan> plan_sp =
+          GetSymbolFileUnwindPlan(thread))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetDebugFrameUnwindPlan(target))
+  if (std::shared_ptr<const UnwindPlan> plan_sp =
+          GetDebugFrameUnwindPlan(target))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetEHFrameUnwindPlan(target))
+  if (std::shared_ptr<const UnwindPlan> plan_sp = GetEHFrameUnwindPlan(target))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetCompactUnwindUnwindPlan(target))
+  if (std::shared_ptr<const UnwindPlan> plan_sp =
+          GetCompactUnwindUnwindPlan(target))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetArmUnwindUnwindPlan(target))
+  if (std::shared_ptr<const UnwindPlan> plan_sp =
+          GetArmUnwindUnwindPlan(target))
     return plan_sp;
 
   return nullptr;
 }
 
-UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_compact_unwind.size() > 0)
     return m_unwind_plan_compact_unwind[0]; // FIXME support multiple compact
                                             // unwind plans for one func
   if (m_tried_unwind_plan_compact_unwind)
-    return UnwindPlanSP();
+    return nullptr;
 
   m_tried_unwind_plan_compact_unwind = true;
   if (m_range.GetBaseAddress().IsValid()) {
     Address current_pc(m_range.GetBaseAddress());
     CompactUnwindInfo *compact_unwind = m_unwind_table.GetCompactUnwindInfo();
     if (compact_unwind) {
-      UnwindPlanSP unwind_plan_sp(new UnwindPlan(lldb::eRegisterKindGeneric));
+      auto unwind_plan_sp =
+          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
       if (compact_unwind->GetUnwindPlan(target, current_pc, *unwind_plan_sp)) {
         m_unwind_plan_compact_unwind.push_back(unwind_plan_sp);
         return m_unwind_plan_compact_unwind[0]; // FIXME support multiple
@@ -113,10 +120,11 @@ UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) {
       }
     }
   }
-  return UnwindPlanSP();
+  return nullptr;
 }
 
-lldb::UnwindPlanSP FuncUnwinders::GetObjectFileUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetObjectFileUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_object_file_sp.get() ||
       m_tried_unwind_plan_object_file)
@@ -126,17 +134,16 @@ lldb::UnwindPlanSP FuncUnwinders::GetObjectFileUnwindPlan(Target &target) {
   if (m_range.GetBaseAddress().IsValid()) {
     CallFrameInfo *object_file_frame = m_unwind_table.GetObjectFileUnwindInfo();
     if (object_file_frame) {
-      m_unwind_plan_object_file_sp =
-          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!object_file_frame->GetUnwindPlan(m_range,
-                                            *m_unwind_plan_object_file_sp))
-        m_unwind_plan_object_file_sp.reset();
+      auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+      if (object_file_frame->GetUnwindPlan(m_range, *plan_sp))
+        m_unwind_plan_object_file_sp = std::move(plan_sp);
     }
   }
   return m_unwind_plan_object_file_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetEHFrameUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame)
     return m_unwind_plan_eh_frame_sp;
@@ -145,16 +152,16 @@ UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) {
   if (m_range.GetBaseAddress().IsValid()) {
     DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo();
     if (eh_frame) {
-      m_unwind_plan_eh_frame_sp =
-          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!eh_frame->GetUnwindPlan(m_range, *m_unwind_plan_eh_frame_sp))
-        m_unwind_plan_eh_frame_sp.reset();
+      auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+      if (eh_frame->GetUnwindPlan(m_range, *plan_sp))
+        m_unwind_plan_eh_frame_sp = std::move(plan_sp);
     }
   }
   return m_unwind_plan_eh_frame_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_debug_frame_sp || m_tried_unwind_plan_debug_frame)
     return m_unwind_plan_debug_frame_sp;
@@ -163,16 +170,16 @@ UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) {
   if (m_range.GetBaseAddress().IsValid()) {
     DWARFCallFrameInfo *debug_frame = m_unwind_table.GetDebugFrameInfo();
     if (debug_frame) {
-      m_unwind_plan_debug_frame_sp =
-          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!debug_frame->GetUnwindPlan(m_range, *m_unwind_plan_debug_frame_sp))
-        m_unwind_plan_debug_frame_sp.reset();
+      auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+      if (debug_frame->GetUnwindPlan(m_range, *plan_sp))
+        m_unwind_plan_debug_frame_sp = std::move(plan_sp);
     }
   }
   return m_unwind_plan_debug_frame_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind)
     return m_unwind_plan_arm_unwind_sp;
@@ -182,11 +189,9 @@ UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) {
     Address current_pc(m_range.GetBaseAddress());
     ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo();
     if (arm_unwind_info) {
-      m_unwind_plan_arm_unwind_sp =
-          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!arm_unwind_info->GetUnwindPlan(target, current_pc,
-                                          *m_unwind_plan_arm_unwind_sp))
-        m_unwind_plan_arm_unwind_sp.reset();
+      auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+      if (arm_unwind_info->GetUnwindPlan(target, current_pc, *plan_sp))
+        m_unwind_plan_arm_unwind_sp = std::move(plan_sp);
     }
   }
   return m_unwind_plan_arm_unwind_sp;
@@ -210,7 +215,8 @@ class RegisterContextToInfo: public SymbolFile::RegisterInfoResolver {
 };
 } // namespace
 
-UnwindPlanSP FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_symbol_file_sp.get() || m_tried_unwind_plan_symbol_file)
     return m_unwind_plan_symbol_file_sp;
@@ -224,9 +230,9 @@ UnwindPlanSP FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) {
   return m_unwind_plan_symbol_file_sp;
 }
 
-UnwindPlanSP
+std::shared_ptr<const UnwindPlan>
 FuncUnwinders::GetObjectFileAugmentedUnwindPlan(Target &target,
-                                                     Thread &thread) {
+                                                Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_object_file_augmented_sp.get() ||
       m_tried_unwind_plan_object_file_augmented)
@@ -234,30 +240,27 @@ FuncUnwinders::GetObjectFileAugmentedUnwindPlan(Target &target,
 
   m_tried_unwind_plan_object_file_augmented = true;
 
-  UnwindPlanSP object_file_unwind_plan = GetObjectFileUnwindPlan(target);
+  std::shared_ptr<const UnwindPlan> object_file_unwind_plan =
+      GetObjectFileUnwindPlan(target);
   if (!object_file_unwind_plan)
     return m_unwind_plan_object_file_augmented_sp;
 
-  m_unwind_plan_object_file_augmented_sp =
-      std::make_shared<UnwindPlan>(*object_file_unwind_plan);
-
   // Augment the instructions with epilogue descriptions if necessary
   // so the UnwindPlan can be used at any instruction in the function.
 
   UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
   if (assembly_profiler_sp) {
-    if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite(
-            m_range, thread, *m_unwind_plan_object_file_augmented_sp)) {
-      m_unwind_plan_object_file_augmented_sp.reset();
-    }
-  } else {
-    m_unwind_plan_object_file_augmented_sp.reset();
+    auto plan_sp = std::make_shared<UnwindPlan>(*object_file_unwind_plan);
+
+    if (assembly_profiler_sp->AugmentUnwindPlanFromCallSite(m_range, thread,
+                                                            *plan_sp))
+      m_unwind_plan_object_file_augmented_sp = std::move(plan_sp);
   }
   return m_unwind_plan_object_file_augmented_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target,
-                                                          Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target, Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_eh_frame_augmented_sp.get() ||
       m_tried_unwind_plan_eh_frame_augmented)
@@ -275,30 +278,27 @@ UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target,
 
   m_tried_unwind_plan_eh_frame_augmented = true;
 
-  UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan(target);
+  std::shared_ptr<const UnwindPlan> eh_frame_plan =
+      GetEHFrameUnwindPlan(target);
   if (!eh_frame_plan)
     return m_unwind_plan_eh_frame_augmented_sp;
 
-  m_unwind_plan_eh_frame_augmented_sp =
-      std::make_shared<UnwindPlan>(*eh_frame_plan);
-
   // Augment the eh_frame instructions with epilogue descriptions if necessary
   // so the UnwindPlan can be used at any instruction in the function.
 
   UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
   if (assembly_profiler_sp) {
-    if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite(
-            m_range, thread, *m_unwind_plan_eh_frame_augmented_sp)) {
-      m_unwind_plan_eh_frame_augmented_sp.reset();
-    }
-  } else {
-    m_unwind_plan_eh_frame_augmented_sp.reset();
+    auto plan_sp = std::make_shared<UnwindPlan>(*eh_frame_plan);
+    if (assembly_profiler_sp->AugmentUnwindPlanFromCallSite(m_range, thread,
+                                                            *plan_sp))
+      m_unwind_plan_eh_frame_augmented_sp = std::move(plan_sp);
   }
   return m_unwind_plan_eh_frame_augmented_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target,
-                                                             Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target,
+                                                Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_debug_frame_augmented_sp.get() ||
       m_tried_unwind_plan_debug_frame_augmented)
@@ -316,30 +316,28 @@ UnwindPlanSP FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target,
 
   m_tried_unwind_plan_debug_frame_augmented = true;
 
-  UnwindPlanSP debug_frame_plan = GetDebugFrameUnwindPlan(target);
+  std::shared_ptr<const UnwindPlan> debug_frame_plan =
+      GetDebugFrameUnwindPlan(target);
   if (!debug_frame_plan)
     return m_unwind_plan_debug_frame_augmented_sp;
 
-  m_unwind_plan_debug_frame_augmented_sp =
-      std::make_shared<UnwindPlan>(*debug_frame_plan);
-
   // Augment the debug_frame instructions with epilogue descriptions if
   // necessary so the UnwindPlan can be used at any instruction in the
   // function.
 
   UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
   if (assembly_profiler_sp) {
-    if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite(
-            m_range, thread, *m_unwind_plan_debug_frame_augmented_sp)) {
-      m_unwind_plan_debug_frame_augmented_sp.reset();
-    }
-  } else
-    m_unwind_plan_debug_frame_augmented_sp.reset();
+    auto plan_sp = std::make_shared<UnwindPlan>(*debug_frame_plan);
+
+    if (assembly_profiler_sp->AugmentUnwindPlanFromCallSite(m_range, thread,
+                                                            *plan_sp))
+      m_unwind_plan_debug_frame_augmented_sp = std::move(plan_sp);
+  }
   return m_unwind_plan_debug_frame_augmented_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target,
-                                                  Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetAssemblyUnwindPlan(Target &target, Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly ||
       !m_unwind_table.GetAllowAssemblyEmulationUnwindPlans()) {
@@ -360,12 +358,10 @@ UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target,
 
   UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
   if (assembly_profiler_sp) {
-    m_unwind_plan_assembly_sp =
-        std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-    if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly(
-            range, thread, *m_unwind_plan_assembly_sp)) {
-      m_unwind_plan_assembly_sp.reset();
-    }
+    auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+    if (assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly(
+            range, thread, *plan_sp))
+      m_unwind_plan_assembly_sp = std::move(plan_sp);
   }
   return m_unwind_plan_assembly_sp;
 }
@@ -374,7 +370,8 @@ UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target,
 // If they have the same way of getting the pc value (e.g. "CFA - 8" + "CFA is
 // sp"), then it will return LazyBoolTrue.
 LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation(
-    Thread &thread, const UnwindPlanSP &a, const UnwindPlanSP &b) {
+    Thread &thread, const std::shared_ptr<const UnwindPlan> &a,
+    const std::shared_ptr<const UnwindPlan> &b) {
   LazyBool plans_are_identical = eLazyBoolCalculate;
 
   RegisterNumber pc_reg(thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
@@ -404,17 +401,19 @@ LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation(
   return plans_are_identical;
 }
 
-UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target,
-                                                       Thread &thread) {
-  UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan(target);
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target, Thread &thread) {
+  std::shared_ptr<const UnwindPlan> eh_frame_sp = GetEHFrameUnwindPlan(target);
   if (!eh_frame_sp)
     eh_frame_sp = GetDebugFrameUnwindPlan(target);
   if (!eh_frame_sp)
     eh_frame_sp = GetObjectFileUnwindPlan(target);
-  UnwindPlanSP arch_default_at_entry_sp =
+  std::shared_ptr<const UnwindPlan> arch_default_at_entry_sp =
       GetUnwindPlanArchitectureDefaultAtFunctionEntry(thread);
-  UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault(thread);
-  UnwindPlanSP assembly_sp = GetAssemblyUnwindPlan(target, thread);
+  std::shared_ptr<const UnwindPlan> arch_default_sp =
+      GetUnwindPlanArchitectureDefault(thread);
+  std::shared_ptr<const UnwindPlan> assembly_sp =
+      GetAssemblyUnwindPlan(target, thread);
 
   // This point of this code is to detect when a function is using a non-
   // standard ABI, and the eh_frame correctly describes that alternate ABI.
@@ -443,20 +442,24 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target,
     return eh_frame_sp;
   }
 
-  if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread))
+  if (std::shared_ptr<const UnwindPlan> plan_sp =
+          GetSymbolFileUnwindPlan(thread))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetDebugFrameAugmentedUnwindPlan(target, thread))
+  if (std::shared_ptr<const UnwindPlan> plan_sp =
+          GetDebugFrameAugmentedUnwindPlan(target, thread))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetEHFrameAugmentedUnwindPlan(target, thread))
+  if (std::shared_ptr<const UnwindPlan> plan_sp =
+          GetEHFrameAugmentedUnwindPlan(target, thread))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetObjectFileAugmentedUnwindPlan(target, thread))
+  if (std::shared_ptr<const UnwindPlan> plan_sp =
+          GetObjectFileAugmentedUnwindPlan(target, thread))
     return plan_sp;
 
   return assembly_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetUnwindPlanFastUnwind(Target &target,
-                                                    Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetUnwindPlanFastUnwind(Target &target, Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast)
     return m_unwind_plan_fast_sp;
@@ -465,17 +468,15 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanFastUnwind(Target &target,
 
   UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
   if (assembly_profiler_sp) {
-    m_unwind_plan_fast_sp =
-        std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-    if (!assembly_profiler_sp->GetFastUnwindPlan(m_range, thread,
-                                                 *m_unwind_plan_fast_sp)) {
-      m_unwind_plan_fast_sp.reset();
-    }
+    auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+    if (assembly_profiler_sp->GetFastUnwindPlan(m_range, thread, *plan_sp))
+      m_unwind_plan_fast_sp = std::move(plan_sp);
   }
   return m_unwind_plan_fast_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetUnwindPlanArchitectureDefault(Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetUnwindPlanArchitectureDefault(Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_arch_default_sp.get() || m_tried_unwind_arch_default)
     return m_unwind_plan_arch_default_sp;
@@ -491,7 +492,7 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanArchitectureDefault(Thread &thread) {
   return m_unwind_plan_arch_default_sp;
 }
 
-UnwindPlanSP
+std::shared_ptr<const UnwindPlan>
 FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry(Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_arch_default_at_func_entry_sp.get() ||
@@ -540,7 +541,8 @@ FuncUnwinders::GetUnwindAssemblyProfiler(Target &target) {
 Address FuncUnwinders::GetLSDAAddress(Target &target) {
   Address lsda_addr;
 
-  UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target);
+  std::shared_ptr<const UnwindPlan> unwind_plan_sp =
+      GetEHFrameUnwindPlan(target);
   if (unwind_plan_sp.get() == nullptr) {
     unwind_plan_sp = GetCompactUnwindUnwindPlan(target);
   }
@@ -556,7 +558,8 @@ Address FuncUnwinders::GetLSDAAddress(Target &target) {
 Address FuncUnwinders::GetPersonalityRoutinePtrAddress(Target &target) {
   Address personality_addr;
 
-  UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target);
+  std::shared_ptr<const UnwindPlan> unwind_plan_sp =
+      GetEHFrameUnwindPlan(target);
   if (unwind_plan_sp.get() == nullptr) {
     unwind_plan_sp = GetCompactUnwindUnwindPlan(target);
   }
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index 92daf29630ab6..14b2c1ce2f227 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -450,7 +450,7 @@ const UnwindPlan::Row *UnwindPlan::GetLastRow() const {
   return &m_row_list.back();
 }
 
-bool UnwindPlan::PlanValidAtAddress(Address addr) {
+bool UnwindPlan::PlanValidAtAddress(Address addr) const {
   // If this UnwindPlan has no rows, it is an invalid UnwindPlan.
   if (GetRowCount() == 0) {
     Log *log = GetLog(LLDBLog::Unwind);
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index a035c57fbfc1c..48d1c887ff430 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -84,7 +84,7 @@ RegisterContextUnwind::RegisterContextUnwind(Thread &thread,
 }
 
 bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC(
-    lldb::UnwindPlanSP unwind_plan_sp) {
+    std::shared_ptr<const UnwindPlan> unwind_plan_sp) {
   if (!unwind_plan_sp)
     return false;
 
@@ -140,8 +140,9 @@ void RegisterContextUnwind::InitializeZerothFrame() {
   if (ABISP abi_sp = process->GetABI())
     current_pc = abi_sp->FixCodeAddress(current_pc);
 
-  UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan(
-      m_thread, this, m_behaves_like_zeroth_frame);
+  std::shared_ptr<const UnwindPlan> lang_runtime_plan_sp =
+      LanguageRuntime::GetRuntimeUnwindPlan(m_thread, this,
+                                            m_behaves_like_zeroth_frame);
   if (lang_runtime_plan_sp.get()) {
     UnwindLogMsg("This is an async frame");
   }
@@ -264,7 +265,7 @@ void RegisterContextUnwind::InitializeZerothFrame() {
     // Try the fall back unwind plan since the
     // full unwind plan failed.
     FuncUnwindersSP func_unwinders_sp;
-    UnwindPlanSP call_site_unwind_plan;
+    std::shared_ptr<const UnwindPlan> call_site_unwind_plan;
     bool cfa_status = false;
 
     if (m_sym_ctx_valid) {
@@ -339,8 +340,9 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
   // A LanguageRuntime may provide an UnwindPlan that is used in this
   // stack trace base on the RegisterContext contents, intsead
   // of the normal UnwindPlans we would use for the return-pc.
-  UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan(
-      m_thread, this, m_behaves_like_zeroth_frame);
+  std::shared_ptr<const UnwindPlan> lang_runtime_plan_sp =
+      LanguageRuntime::GetRuntimeUnwindPlan(m_thread, this,
+                                            m_behaves_like_zeroth_frame);
   if (lang_runtime_plan_sp.get()) {
     UnwindLogMsg("This is an async frame");
   }
@@ -748,39 +750,37 @@ bool RegisterContextUnwind::BehavesLikeZerothFrame() const {
 //   4. m_current_offset_backed_up_one should have the current byte offset into
 //   the function, maybe backed up by 1, -1 if unknown
 
-UnwindPlanSP RegisterContextUnwind::GetFastUnwindPlanForFrame() {
-  UnwindPlanSP unwind_plan_sp;
+std::shared_ptr<const UnwindPlan>
+RegisterContextUnwind::GetFastUnwindPlanForFrame() {
   ModuleSP pc_module_sp(m_current_pc.GetModule());
 
   if (!m_current_pc.IsValid() || !pc_module_sp ||
       pc_module_sp->GetObjectFile() == nullptr)
-    return unwind_plan_sp;
+    return nullptr;
 
   if (IsFrameZero())
-    return unwind_plan_sp;
+    return nullptr;
 
   FuncUnwindersSP func_unwinders_sp(
       pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
           m_current_pc, m_sym_ctx));
   if (!func_unwinders_sp)
-    return unwind_plan_sp;
+    return nullptr;
 
   // If we're in _sigtramp(), unwinding past this frame requires special
   // knowledge.
   if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
-    return unwind_plan_sp;
+    return nullptr;
 
-  unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind(
-      *m_thread.CalculateTarget(), m_thread);
-  if (unwind_plan_sp) {
+  if (std::shared_ptr<const UnwindPlan> unwind_plan_sp =
+          func_unwinders_sp->GetUnwindPlanFastUnwind(
+              *m_thread.CalculateTarget(), m_thread)) {
     if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
       m_frame_type = eNormalFrame;
       return unwind_plan_sp;
-    } else {
-      unwind_plan_sp.reset();
     }
   }
-  return unwind_plan_sp;
+  return nullptr;
 }
 
 // On entry to this method,
@@ -792,9 +792,9 @@ UnwindPlanSP RegisterContextUnwind::GetFastUnwindPlanForFrame() {
 //   4. m_current_offset_backed_up_one should have the current byte offset into
 //   the function, maybe backed up by 1, -1 if unknown
 
-UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
-  UnwindPlanSP unwind_plan_sp;
-  UnwindPlanSP arch_default_unwind_plan_sp;
+std::shared_ptr<const UnwindPlan>
+RegisterContextUnwind::GetFullUnwindPlanForFrame() {
+  std::shared_ptr<const UnwindPlan> arch_default_unwind_plan_sp;
   ExecutionContext exe_ctx(m_thread.shared_from_this());
   Process *process = exe_ctx.GetProcessPtr();
   ABI *abi = process ? process->GetABI().get() : nullptr;
@@ -832,9 +832,8 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
          process->GetLoadAddressPermissions(current_pc_addr, permissions) &&
          (permissions & ePermissionsExecutable) == 0)) {
       if (abi) {
-        unwind_plan_sp = abi->CreateFunctionEntryUnwindPlan();
         m_frame_type = eNormalFrame;
-        return unwind_plan_sp;
+        return abi->CreateFunctionEntryUnwindPlan();
       }
     }
   }
@@ -871,32 +870,29 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
     DWARFCallFrameInfo *eh_frame =
         pc_module_sp->GetUnwindTable().GetEHFrameInfo();
     if (eh_frame) {
-      unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+      auto unwind_plan_sp =
+          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
       if (eh_frame->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
         return unwind_plan_sp;
-      else
-        unwind_plan_sp.reset();
     }
 
     ArmUnwindInfo *arm_exidx =
         pc_module_sp->GetUnwindTable().GetArmUnwindInfo();
     if (arm_exidx) {
-      unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+      auto unwind_plan_sp =
+          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
       if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc,
                                    *unwind_plan_sp))
         return unwind_plan_sp;
-      else
-        unwind_plan_sp.reset();
     }
 
     CallFrameInfo *object_file_unwind =
         pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo();
     if (object_file_unwind) {
-      unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+      auto unwind_plan_sp =
+          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
       if (object_file_unwind->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
         return unwind_plan_sp;
-      else
-        unwind_plan_sp.reset();
     }
 
     return arch_default_unwind_plan_sp;
@@ -910,15 +906,13 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
     // substitute plan. Otherwise, use eh_frame.
     if (m_sym_ctx_valid) {
       lldb::PlatformSP platform = process->GetTarget().GetPlatform();
-      unwind_plan_sp = platform->GetTrapHandlerUnwindPlan(
-          process->GetTarget().GetArchitecture().GetTriple(),
-          GetSymbolOrFunctionName(m_sym_ctx));
-
-      if (unwind_plan_sp)
+      if (auto unwind_plan_sp = platform->GetTrapHandlerUnwindPlan(
+              process->GetTarget().GetArchitecture().GetTriple(),
+              GetSymbolOrFunctionName(m_sym_ctx)))
         return unwind_plan_sp;
     }
 
-    unwind_plan_sp =
+    auto unwind_plan_sp =
         func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
     if (!unwind_plan_sp)
       unwind_plan_sp =
@@ -943,7 +937,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
     // normally we would call GetUnwindPlanAtCallSite() -- because CallSite may
     // return an unwind plan sourced from either eh_frame (that's what we
     // intend) or compact unwind (this won't work)
-    unwind_plan_sp =
+    auto unwind_plan_sp =
         func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
     if (!unwind_plan_sp)
       unwind_plan_sp =
@@ -959,7 +953,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
   // Typically the NonCallSite UnwindPlan is the unwind created by inspecting
   // the assembly language instructions
   if (m_behaves_like_zeroth_frame && process) {
-    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
+    auto unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
         process->GetTarget(), m_thread);
     if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
       if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
@@ -974,7 +968,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
         // assembly code it is often written in a way that it valid at all
         // location what helps in the most common cases when the instruction
         // emulation fails.
-        UnwindPlanSP call_site_unwind_plan =
+        std::shared_ptr<const UnwindPlan> call_site_unwind_plan =
             func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
                                                        m_thread);
         if (call_site_unwind_plan &&
@@ -1009,6 +1003,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
     }
   }
 
+  std::shared_ptr<const UnwindPlan> unwind_plan_sp;
   // Typically this is unwind info from an eh_frame section intended for
   // exception handling; only valid at call sites
   if (process) {
@@ -1041,7 +1036,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
     // sites then the architecture default plan and for hand written assembly
     // code it is often written in a way that it valid at all location what
     // helps in the most common cases when the instruction emulation fails.
-    UnwindPlanSP call_site_unwind_plan =
+    std::shared_ptr<const UnwindPlan> call_site_unwind_plan =
         func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
                                                    m_thread);
     if (call_site_unwind_plan &&
@@ -1785,7 +1780,8 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
   // Switch the full UnwindPlan to be the fallback UnwindPlan.  If we decide
   // this isn't working, we need to restore. We'll also need to save & restore
   // the value of the m_cfa ivar.  Save is down below a bit in 'old_cfa'.
-  UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
+  std::shared_ptr<const UnwindPlan> original_full_unwind_plan_sp =
+      m_full_unwind_plan_sp;
   addr_t old_cfa = m_cfa;
   addr_t old_afa = m_afa;
 
@@ -1914,7 +1910,7 @@ bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() {
 }
 
 void RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(
-    lldb::UnwindPlanSP unwind_plan) {
+    std::shared_ptr<const UnwindPlan> unwind_plan) {
   if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) {
     // Unwind plan does not indicate trap handler.  Do nothing.  We may
     // already be flagged as trap handler flag due to the symbol being



More information about the lldb-commits mailing list