llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Jason Molenda (jasonmolenda)

<details>
<summary>Changes</summary>

For supported architectures, lldb will do a static scan of the assembly 
instructions of a function to detect stack/frame pointer changes, register 
stores and loads, so we can retrieve register values for the caller stack 
frames.  We trust that the function address range reflects the actual function 
range, but in a stripped binary or other unusual environment, we can end up 
scanning all of the text as a single "function" which is (1) incorrect and 
useless, but more importantly (2) slow.

Cap the max size we will profile to 10MB of instructions.  There will surely be 
functions longer than this with no unwind info, and we will miss the final 
epilogue or mid-function epilogues past the first 10MB, but I think this will 
be unusual, and the failure more to missing the epilogue is that the user will 
need to step out an extra time or two as the StackID is not correctly 
calculated mid-epilogue.  I think this is a good tradeoff of behaviors.

rdar://134391577

---
Full diff: https://github.com/llvm/llvm-project/pull/105890.diff


1 Files Affected:

- (modified) lldb/source/Symbol/FuncUnwinders.cpp (+11-1) 


``````````diff
diff --git a/lldb/source/Symbol/FuncUnwinders.cpp 
b/lldb/source/Symbol/FuncUnwinders.cpp
index d67c0a828eb350..228d9a1072deca 100644
--- a/lldb/source/Symbol/FuncUnwinders.cpp
+++ b/lldb/source/Symbol/FuncUnwinders.cpp
@@ -334,12 +334,22 @@ UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target 
&target,
 
   m_tried_unwind_plan_assembly = true;
 
+  // Don't analyze more than 10 megabytes of instructions,
+  // if a function is legitimately larger than that, we'll
+  // miss the epilogue instructions, but guard against a
+  // bogusly large function and analyzing large amounts of
+  // non-instruction data.
+  AddressRange range = m_range;
+  const addr_t func_size =
+      std::min(range.GetByteSize(), (addr_t)1024 * 10 * 10);
+  range.SetByteSize(func_size);
+
   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(
-            m_range, thread, *m_unwind_plan_assembly_sp)) {
+            range, thread, *m_unwind_plan_assembly_sp)) {
       m_unwind_plan_assembly_sp.reset();
     }
   }

``````````

</details>


https://github.com/llvm/llvm-project/pull/105890
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to