Index: source/Plugins/Process/Utility/RegisterContextLLDB.cpp =================================================================== --- source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -855,12 +855,26 @@ { if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) { - // We probably have an UnwindPlan created by inspecting assembly instructions, and we probably - // don't have any eh_frame instructions available. - // The assembly profilers work really well with compiler-generated functions but hand-written - // assembly can be problematic. We'll set the architecture default UnwindPlan as our fallback - // UnwindPlan in case this doesn't work out when we try to unwind. - m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; + // We probably have an UnwindPlan created by inspecting assembly instructions. The + // assembly profilers work really well with compiler-generated functions but hand- + // written assembly can be problematic. We set the eh_frame based unwind plan as our + // fallback unwind plan if instruction emulation doesn't work out even for non call + // sites if it is available and use the architecture default unwind plan if it is + // not available. The eh_frame unwind plan is more reliable even on non call 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 eh_frame_unwind_plan = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one); + if (eh_frame_unwind_plan && + eh_frame_unwind_plan.get() != unwind_plan_sp.get() && + eh_frame_unwind_plan->GetSourceName() != unwind_plan_sp->GetSourceName()) + { + m_fallback_unwind_plan_sp = eh_frame_unwind_plan; + } + else + { + m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; + } } UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString()); return unwind_plan_sp; @@ -887,12 +901,25 @@ } if (unwind_plan_sp && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) { - // We probably have an UnwindPlan created by inspecting assembly instructions, and we probably - // don't have any eh_frame instructions available. - // The assembly profilers work really well with compiler-generated functions but hand-written - // assembly can be problematic. We'll set the architecture default UnwindPlan as our fallback - // UnwindPlan in case this doesn't work out when we try to unwind. - m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; + // We probably have an UnwindPlan created by inspecting assembly instructions. The assembly + // profilers work really well with compiler-generated functions but hand- written assembly + // can be problematic. We set the eh_frame based unwind plan as our fallback unwind plan if + // instruction emulation doesn't work out even for non call sites if it is available and use + // the architecture default unwind plan if it is not available. The eh_frame unwind plan is + // more reliable even on non call 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 eh_frame_unwind_plan = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one); + if (eh_frame_unwind_plan && + eh_frame_unwind_plan.get() != unwind_plan_sp.get() && + eh_frame_unwind_plan->GetSourceName() != unwind_plan_sp->GetSourceName()) + { + m_fallback_unwind_plan_sp = eh_frame_unwind_plan; + } + else + { + m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; + } } if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset))