[Lldb-commits] [lldb] r230211 - Support evaluation of DWARF expressions setting CFA

Pavel Labath labath at google.com
Mon Feb 23 02:29:02 PST 2015


Author: labath
Date: Mon Feb 23 04:29:01 2015
New Revision: 230211

URL: http://llvm.org/viewvc/llvm-project?rev=230211&view=rev
Log:
Support evaluation of DWARF expressions setting CFA

Summary:
This patch enables evaluation of DWARF expressions setting the CFA during stack unwinding.

This makes TestSigtrampUnwind "almost" pass on linux. I am not enabling the test yet since the
symbol name for the signal trampoline does not get resolved properly due to a different bug, but
apart from that, the backtrace is sane.

I am unsure how this change affects Mac. I think it makes the unwinder prefer the DWARF unwind
plan instead of some custom platform-dependant plan. However, it does not affect the end result
- the stack unwinding works as expected.

Reviewers: jasonmolenda

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D7792

Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
    lldb/trunk/source/Symbol/UnwindPlan.cpp

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=230211&r1=230210&r2=230211&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Mon Feb 23 04:29:01 2015
@@ -1743,7 +1743,28 @@ RegisterContextLLDB::ReadCFAValueForRow
             }
             break;
         }
-    // TODO: handle isDWARFExpression
+    case UnwindPlan::Row::CFAValue::isDWARFExpression:
+        {
+            ExecutionContext exe_ctx(m_thread.shared_from_this());
+            Process *process = exe_ctx.GetProcessPtr();
+            DataExtractor dwarfdata (row->GetCFAValue().GetDWARFExpressionBytes(),
+                                     row->GetCFAValue().GetDWARFExpressionLength(),
+                                     process->GetByteOrder(), process->GetAddressByteSize());
+            ModuleSP opcode_ctx;
+            DWARFExpression dwarfexpr (opcode_ctx, dwarfdata, 0, row->GetCFAValue().GetDWARFExpressionLength());
+            dwarfexpr.SetRegisterKind (row_register_kind);
+            Value result;
+            Error error;
+            if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, this, 0, NULL, result, &error))
+            {
+                cfa_value = result.GetScalar().ULongLong();
+
+                UnwindLogMsg ("CFA value set by DWARF expression is 0x%" PRIx64, cfa_value);
+                return true;
+            }
+            UnwindLogMsg ("Failed to set CFA value via DWARF expression: %s", error.AsCString());
+            break;
+        }
     default:
         return false;
     }

Modified: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp?rev=230211&r1=230210&r2=230211&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp Mon Feb 23 04:29:01 2015
@@ -748,7 +748,9 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_
                 case DW_CFA_def_cfa_expression  : // 0xF    (CFA Definition Instruction)
                     {
                         size_t block_len = (size_t)m_cfi_data.GetULEB128(&offset);
-                        offset += (uint32_t)block_len;
+                        const uint8_t *block_data =
+                            static_cast<const uint8_t *>(m_cfi_data.GetData(&offset, block_len));
+                        row->GetCFAValue().SetIsDWARFExpression(block_data, block_len);
                     }
                     break;
 

Modified: lldb/trunk/source/Symbol/UnwindPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/UnwindPlan.cpp?rev=230211&r1=230210&r2=230211&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/UnwindPlan.cpp (original)
+++ lldb/trunk/source/Symbol/UnwindPlan.cpp Mon Feb 23 04:29:01 2015
@@ -434,10 +434,8 @@ UnwindPlan::PlanValidAtAddress (Address
 
     // If the 0th Row of unwind instructions is missing, or if it doesn't provide
     // a register to use to find the Canonical Frame Address, this is not a valid UnwindPlan.
-    // CFA set by a DWARF expression is not currently supported, so ignore that as well.
     if (GetRowAtIndex(0).get() == nullptr ||
-            GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::unspecified ||
-            GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::isDWARFExpression)
+            GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::unspecified)
     {
         Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
         if (log)





More information about the lldb-commits mailing list