From c9f44cd4b6e590c5884a2bc2465d4a09ac4f1c59 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 2 May 2019 23:49:56 +0000 Subject: [PATCH] RegisterContextLLDB::GetFullUnwindPlanForFrame has four verbose logging messages that are written the same, making it difficult to know for certain which code path was taken based on a logfile. Add some words to make each unique. Right now the ordering for finding a FullUnwindPlan (ignoring fallback unwind plan logic) is 1. If this is a _sigtramp like function, try eh_frame which is hand written on darwin systems to account for finding the saved register context correctly. 2. Ask the DynamicLoader if eh_frame should be preferred for this frame. Some binaries on the system may have hand-written eh_frame and the DynamicLoader is the source for this. (primarily this is for hand-written assembly in the objc runtime, and we tell lldb to trust that for functions in libobjc.dylib.) 3. if 0th frame, use GetUnwindPlanAtNonCallSite plan. 4. GetUnwindPlanAtCallSite {for 0th or any other} 5. GetUnwindPlanAtNonCallSite {now for non-0th frames, only if not from a compiler? hm.} 6. GetUnwindPlanArchitectureDefaultAtFunctionEntry if we're on the first instruction 7. Architectural default unwind plan ABI::CreateDefaultUnwindPlan I'm moving #6 -- DefaultAtFunctionEntry -- up to between #3 and #4, where we're already doing things specific to the zeroth frame. If we're on the zeroth frame and the GetUnwindPlanAtNonCallSite plan has failed for some reason, and we're on the first instruction, we should definitely use DefaultAtFunctionEntry instead of any other unwind plan. If we're trying to step out of some rando function on the system that we couldn't assembly instruction inspect, this is sufficient for us to step out of it. llvm-svn: 359847 --- .../Process/Utility/RegisterContextLLDB.cpp | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index fc37cd33bd8f88..69f4e38cc9edcb 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -883,10 +883,27 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() { m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; } } - UnwindLogMsgVerbose("frame uses %s for full UnwindPlan", + UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this " + "is the non-call site unwind plan and this is a " + "zeroth frame", unwind_plan_sp->GetSourceName().GetCString()); return unwind_plan_sp; } + + // If we're on the first instruction of a function, and we have an + // architectural default UnwindPlan for the initial instruction of a + // function, use that. + if (m_current_offset == 0) { + unwind_plan_sp = + func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry( + m_thread); + if (unwind_plan_sp) { + UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we are at " + "the first instruction of a function", + unwind_plan_sp->GetSourceName().GetCString()); + return unwind_plan_sp; + } + } } // Typically this is unwind info from an eh_frame section intended for @@ -897,7 +914,8 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() { } int valid_offset = -1; if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) { - UnwindLogMsgVerbose("frame uses %s for full UnwindPlan", + UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this " + "is the call-site unwind plan", unwind_plan_sp->GetSourceName().GetCString()); return unwind_plan_sp; } @@ -934,30 +952,18 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() { } if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) { - UnwindLogMsgVerbose("frame uses %s for full UnwindPlan", + UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we " + "failed to find a call-site unwind plan that would work", unwind_plan_sp->GetSourceName().GetCString()); return unwind_plan_sp; } - // If we're on the first instruction of a function, and we have an - // architectural default UnwindPlan for the initial instruction of a - // function, use that. - if (m_current_offset_backed_up_one == 0) { - unwind_plan_sp = - func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry( - m_thread); - if (unwind_plan_sp) { - UnwindLogMsgVerbose("frame uses %s for full UnwindPlan", - unwind_plan_sp->GetSourceName().GetCString()); - return unwind_plan_sp; - } - } - // If nothing else, use the architectural default UnwindPlan and hope that // does the job. if (arch_default_unwind_plan_sp) UnwindLogMsgVerbose( - "frame uses %s for full UnwindPlan", + "frame uses %s for full UnwindPlan because we are falling back " + "to the arch default plan", arch_default_unwind_plan_sp->GetSourceName().GetCString()); else UnwindLogMsg(