Support Linux signal return trampolines in frame initialization
Summary:
Add __kernel_rt_sigreturn to the list of trap handlers for Linux (it's
used as such on aarch64 at least), and __restore_rt as well (used on
x86_64).
Skip decrement-and-recompute for trap handlers in
InitializeNonZerothFrame, as signal dispatch may point the child frame's
return address to the start of the return trampoline.
Parse the 'S' flag for signal handlers from eh_frame augmentation, and
propagate it to the unwind plan.
Reviewers: labath, jankratochvil, compnerd, jfb, jasonmolenda
Reviewed By: jasonmolenda
Subscribers: clayborg, MaskRay, wuzish, nemanjai, kbarton, jrtc27, atanasyan, jsji, javed.absar, kristof.beyls, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D63667
llvm-svn: 366580
diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h
index 2b49aca..fc3e3cc 100644
--- a/lldb/include/lldb/Symbol/UnwindPlan.h
+++ b/lldb/include/lldb/Symbol/UnwindPlan.h
@@ -370,6 +370,7 @@
m_return_addr_register(LLDB_INVALID_REGNUM), m_source_name(),
m_plan_is_sourced_from_compiler(eLazyBoolCalculate),
m_plan_is_valid_at_all_instruction_locations(eLazyBoolCalculate),
+ m_plan_is_for_signal_trap(eLazyBoolCalculate),
m_lsda_address(), m_personality_func_addr() {}
// Performs a deep copy of the plan, including all the rows (expensive).
@@ -463,6 +464,17 @@
m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn;
}
+ // Is this UnwindPlan for a signal trap frame? If so, then its saved pc
+ // may have been set manually by the signal dispatch code and therefore
+ // not follow a call to the child frame.
+ lldb_private::LazyBool GetUnwindPlanForSignalTrap() const {
+ return m_plan_is_for_signal_trap;
+ }
+
+ void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap) {
+ m_plan_is_for_signal_trap = is_for_signal_trap;
+ }
+
int GetRowCount() const;
void Clear() {
@@ -472,6 +484,7 @@
m_source_name.Clear();
m_plan_is_sourced_from_compiler = eLazyBoolCalculate;
m_plan_is_valid_at_all_instruction_locations = eLazyBoolCalculate;
+ m_plan_is_for_signal_trap = eLazyBoolCalculate;
m_lsda_address.Clear();
m_personality_func_addr.Clear();
}
@@ -502,6 +515,7 @@
m_source_name; // for logging, where this UnwindPlan originated from
lldb_private::LazyBool m_plan_is_sourced_from_compiler;
lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations;
+ lldb_private::LazyBool m_plan_is_for_signal_trap;
Address m_lsda_address; // Where the language specific data area exists in the
// module - used
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/signal/handle-abrt/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/signal/handle-abrt/Makefile
new file mode 100644
index 0000000..b09a579
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/signal/handle-abrt/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/signal/handle-abrt/TestHandleAbort.py b/lldb/packages/Python/lldbsuite/test/functionalities/signal/handle-abrt/TestHandleAbort.py
new file mode 100644
index 0000000..022ad92
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/signal/handle-abrt/TestHandleAbort.py
@@ -0,0 +1,72 @@
+"""Test that we can unwind out of a SIGABRT handler"""
+
+from __future__ import print_function
+
+
+import os
+import re
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class HandleAbortTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ @skipIfWindows # signals do not exist on Windows
+ def test_inferior_handle_sigabrt(self):
+ """Inferior calls abort() and handles the resultant SIGABRT.
+ Stopped at a breakpoint in the handler, verify that the backtrace
+ includes the function that called abort()."""
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # launch
+ process = target.LaunchSimple(
+ None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+ self.assertEqual(process.GetState(), lldb.eStateStopped)
+ signo = process.GetUnixSignals().GetSignalNumberFromName("SIGABRT")
+
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
+ self.assertTrue(
+ thread and thread.IsValid(),
+ "Thread should be stopped due to a signal")
+ self.assertTrue(
+ thread.GetStopReasonDataCount() >= 1,
+ "There should be data in the event.")
+ self.assertEqual(thread.GetStopReasonDataAtIndex(0),
+ signo, "The stop signal should be SIGABRT")
+
+ # Continue to breakpoint in abort handler
+ bkpt = target.FindBreakpointByID(
+ lldbutil.run_break_set_by_source_regexp(self, "Set a breakpoint here"))
+ threads = lldbutil.continue_to_breakpoint(process, bkpt)
+ self.assertEqual(len(threads), 1, "Expected single thread")
+ thread = threads[0]
+
+ # Expect breakpoint in 'handler'
+ frame = thread.GetFrameAtIndex(0)
+ self.assertEqual(frame.GetDisplayFunctionName(), "handler", "Unexpected break?")
+
+ # Expect that unwinding should find 'abort_caller'
+ foundFoo = False
+ for frame in thread:
+ if frame.GetDisplayFunctionName() == "abort_caller":
+ foundFoo = True
+
+ self.assertTrue(foundFoo, "Unwinding did not find func that called abort")
+
+ # Continue until we exit.
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateExited)
+ self.assertEqual(process.GetExitStatus(), 0)
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/signal/handle-abrt/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/signal/handle-abrt/main.c
new file mode 100644
index 0000000..c2daea1
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/signal/handle-abrt/main.c
@@ -0,0 +1,25 @@
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void handler(int sig)
+{
+ printf("Set a breakpoint here.\n");
+ exit(0);
+}
+
+void abort_caller() {
+ abort();
+}
+
+int main()
+{
+ if (signal(SIGABRT, handler) == SIG_ERR)
+ {
+ perror("signal");
+ return 1;
+ }
+
+ abort_caller();
+ return 2;
+}
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index 362a80b..f2d01db 100644
--- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -1846,6 +1846,7 @@
unwind_plan.SetSourceName("arm-apple-ios default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
index 368e372..fd788e7 100644
--- a/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ b/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
@@ -2011,6 +2011,7 @@
unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 67371b4..adb40cf 100644
--- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -1055,6 +1055,7 @@
unwind_plan.SetSourceName("i386 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
index dd47ac7..b074714 100644
--- a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -1960,6 +1960,7 @@
unwind_plan.SetSourceName("arm default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
index 1d54712..f9647ef 100644
--- a/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ b/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
@@ -1958,6 +1958,7 @@
unwind_plan.SetSourceName("arm64 at-func-entry default");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
@@ -1982,6 +1983,7 @@
unwind_plan.SetSourceName("arm64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
index 9364756..ae83685 100644
--- a/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
+++ b/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
@@ -1247,6 +1247,7 @@
unwind_plan.SetSourceName("hexagon default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
index 05f5dba..41148b7 100644
--- a/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
+++ b/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
@@ -785,6 +785,7 @@
unwind_plan.SetSourceName("i386 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
index 121c730..9d15cb5 100644
--- a/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
+++ b/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
@@ -997,6 +997,7 @@
unwind_plan.SetSourceName("mips default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
index 18011cf..3f3b807 100644
--- a/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
+++ b/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
@@ -1168,6 +1168,7 @@
unwind_plan.SetSourceName("mips64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index faa9950..3f2d49c 100644
--- a/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -910,6 +910,7 @@
unwind_plan.SetSourceName("ppc default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_lr);
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index aa79075..66f812d 100644
--- a/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -1017,6 +1017,7 @@
unwind_plan.SetSourceName("ppc64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(pc_reg_num);
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index 6c7b45f..255db1d 100644
--- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -1034,6 +1034,7 @@
unwind_plan.SetSourceName("x86_64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 6323889..19a987b 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -14507,6 +14507,7 @@
unwind_plan.SetSourceName("EmulateInstructionARM");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_lr);
return true;
}
diff --git a/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index d7e8e04..6ab9685 100644
--- a/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -479,6 +479,7 @@
unwind_plan.SetSourceName("EmulateInstructionARM64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(gpr_lr_arm64);
return true;
}
diff --git a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index cbf3dda..21b6296 100644
--- a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -1150,6 +1150,7 @@
unwind_plan.SetSourceName("EmulateInstructionMIPS");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
return true;
diff --git a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 69f0278..5fabbeb 100644
--- a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -1042,6 +1042,7 @@
unwind_plan.SetSourceName("EmulateInstructionMIPS64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64);
return true;
diff --git a/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
index c77fa04..4b8d8dd 100644
--- a/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
+++ b/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
@@ -135,6 +135,7 @@
unwind_plan.SetSourceName("EmulateInstructionPPC64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(gpr_lr_ppc64le);
return true;
}
diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
index d0ad2f3..52d72f5 100644
--- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -396,6 +396,8 @@
void PlatformLinux::CalculateTrapHandlerSymbolNames() {
m_trap_handlers.push_back(ConstString("_sigtramp"));
+ m_trap_handlers.push_back(ConstString("__kernel_rt_sigreturn"));
+ m_trap_handlers.push_back(ConstString("__restore_rt"));
}
MmapArgList PlatformLinux::GetMmapArgumentList(const ArchSpec &arch,
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 76646d8..786c4a5 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -472,20 +472,30 @@
m_sym_ctx_valid = false;
}
- bool decr_pc_and_recompute_addr_range = false;
+ bool decr_pc_and_recompute_addr_range;
- // If the symbol lookup failed...
- if (!m_sym_ctx_valid)
+ if (!m_sym_ctx_valid) {
+ // Always decrement and recompute if the symbol lookup failed
decr_pc_and_recompute_addr_range = true;
-
- // Or if we're in the middle of the stack (and not "above" an asynchronous
- // event like sigtramp), and our "current" pc is the start of a function...
- if (GetNextFrame()->m_frame_type != eTrapHandlerFrame &&
- GetNextFrame()->m_frame_type != eDebuggerFrame &&
- (!m_sym_ctx_valid ||
- (addr_range.GetBaseAddress().IsValid() &&
- addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() &&
- addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()))) {
+ } else if (GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
+ GetNextFrame()->m_frame_type == eDebuggerFrame) {
+ // Don't decrement if we're "above" an asynchronous event like
+ // sigtramp.
+ decr_pc_and_recompute_addr_range = false;
+ } else if (!addr_range.GetBaseAddress().IsValid() ||
+ addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() ||
+ addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) {
+ // If our "current" pc isn't the start of a function, no need
+ // to decrement and recompute.
+ decr_pc_and_recompute_addr_range = false;
+ } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
+ // Signal dispatch may set the return address of the handler it calls to
+ // point to the first byte of a return trampoline (like __kernel_rt_sigreturn),
+ // so do not decrement and recompute if the symbol we already found is a trap
+ // handler.
+ decr_pc_and_recompute_addr_range = false;
+ } else {
+ // Decrement to find the function containing the call.
decr_pc_and_recompute_addr_range = true;
}
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index d425827..5e275e3 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -495,6 +495,7 @@
auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
plan_sp->SetSourceName("breakpad STACK CFI");
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
plan_sp->SetPlanValidAddressRange(
AddressRange(base + init_record->Address, *init_record->Size,
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index 43041ca..946d99c 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -1328,6 +1328,7 @@
unwind_plan.SetSourceName("assembly insn profiling");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/lldb/source/Symbol/ArmUnwindInfo.cpp b/lldb/source/Symbol/ArmUnwindInfo.cpp
index b9fd84b..fdf4e30 100644
--- a/lldb/source/Symbol/ArmUnwindInfo.cpp
+++ b/lldb/source/Symbol/ArmUnwindInfo.cpp
@@ -344,6 +344,7 @@
unwind_plan.SetSourceName("ARM.exidx unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
return true;
diff --git a/lldb/source/Symbol/CompactUnwindInfo.cpp b/lldb/source/Symbol/CompactUnwindInfo.cpp
index 3a2a4d3..1a634f2 100644
--- a/lldb/source/Symbol/CompactUnwindInfo.cpp
+++ b/lldb/source/Symbol/CompactUnwindInfo.cpp
@@ -737,6 +737,7 @@
unwind_plan.SetSourceName("compact unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
unwind_plan.SetLSDAAddress(function_info.lsda_address);
@@ -1008,6 +1009,7 @@
unwind_plan.SetSourceName("compact unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
unwind_plan.SetLSDAAddress(function_info.lsda_address);
@@ -1304,6 +1306,7 @@
unwind_plan.SetSourceName("compact unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
unwind_plan.SetLSDAAddress(function_info.lsda_address);
@@ -1437,6 +1440,7 @@
unwind_plan.SetSourceName("compact unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
unwind_plan.SetLSDAAddress(function_info.lsda_address);
diff --git a/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/lldb/source/Symbol/DWARFCallFrameInfo.cpp
index 0ab9fa4..64bd22b 100644
--- a/lldb/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/lldb/source/Symbol/DWARFCallFrameInfo.cpp
@@ -19,6 +19,7 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
#include <list>
+#include <cstring>
using namespace lldb;
using namespace lldb_private;
@@ -601,6 +602,9 @@
}
offset += aug_data_len;
}
+ unwind_plan.SetUnwindPlanForSignalTrap(
+ strchr(cie->augmentation, 'S') ? eLazyBoolYes : eLazyBoolNo);
+
Address lsda_data;
Address personality_function_ptr;