Author: Pavel Labath Date: 2024-05-15T10:02:24+02:00 New Revision: d12c48cad52798f4846dd8ef882af0f854118d16
URL: https://github.com/llvm/llvm-project/commit/d12c48cad52798f4846dd8ef882af0f854118d16 DIFF: https://github.com/llvm/llvm-project/commit/d12c48cad52798f4846dd8ef882af0f854118d16.diff LOG: [lldb/aarch64] Allow unaligned PC addresses below a trap handler (#92093) The stack validation heuristic is counter-productive in this case, as the unaligned address is most likely the thing that caused the signal in the first place. Added: lldb/test/Shell/Unwind/Inputs/unaligned-pc-sigbus.c lldb/test/Shell/Unwind/unaligned-pc-sigbus.test Modified: lldb/source/Target/UnwindLLDB.cpp Removed: ################################################################################ diff --git a/lldb/source/Target/UnwindLLDB.cpp b/lldb/source/Target/UnwindLLDB.cpp index 1d8bf2f88ae67..f43e940492b09 100644 --- a/lldb/source/Target/UnwindLLDB.cpp +++ b/lldb/source/Target/UnwindLLDB.cpp @@ -261,7 +261,12 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } - if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) { + + // Invalid code addresses should not appear on the stack *unless* we're + // directly below a trap handler frame (in this case, the invalid address is + // likely the cause of the trap). + if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc) && + !prev_frame->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to // that and return true. Subsequent calls to TryFallbackUnwindPlan() will // return false. diff --git a/lldb/test/Shell/Unwind/Inputs/unaligned-pc-sigbus.c b/lldb/test/Shell/Unwind/Inputs/unaligned-pc-sigbus.c new file mode 100644 index 0000000000000..b4818de3b7fb3 --- /dev/null +++ b/lldb/test/Shell/Unwind/Inputs/unaligned-pc-sigbus.c @@ -0,0 +1,21 @@ +#include <signal.h> +#include <stdint.h> +#include <unistd.h> + +void sigbus_handler(int signo) { _exit(47); } + +int target_function() { return 47; } + +int main() { + signal(SIGBUS, sigbus_handler); + + // Generate a SIGBUS by deliverately calling through an unaligned function + // pointer. + union { + int (*t)(); + uintptr_t p; + } u; + u.t = target_function; + u.p |= 1; + return u.t(); +} diff --git a/lldb/test/Shell/Unwind/unaligned-pc-sigbus.test b/lldb/test/Shell/Unwind/unaligned-pc-sigbus.test new file mode 100644 index 0000000000000..5ebfba54301ef --- /dev/null +++ b/lldb/test/Shell/Unwind/unaligned-pc-sigbus.test @@ -0,0 +1,31 @@ +# REQUIRES: (target-aarch64 || target-arm) && native +# UNSUPPORTED: system-windows +# llvm.org/pr91610, rdar://128031075 +# XFAIL: system-darwin + +# RUN: %clang_host %S/Inputs/unaligned-pc-sigbus.c -o %t +# RUN: %lldb -s %s -o exit %t | FileCheck %s + +# Convert EXC_BAD_ACCESS into SIGBUS on darwin. +settings set platform.plugin.darwin.ignored-exceptions EXC_BAD_ACCESS + +breakpoint set -n sigbus_handler +# CHECK: Breakpoint 1: where = {{.*}}`sigbus_handler + +run +# CHECK: thread #1, {{.*}} stop reason = signal SIGBUS + +thread backtrace +# CHECK: (lldb) thread backtrace +# CHECK: frame #0: [[TARGET:0x[0-9a-fA-F]*]] {{.*}}`target_function + +continue +# CHECK: thread #1, {{.*}} stop reason = breakpoint 1 + + +thread backtrace +# CHECK: (lldb) thread backtrace +# CHECK: frame #0: {{.*}}`sigbus_handler +# Unknown number of signal trampoline frames +# CHECK: frame #{{[0-9]+}}: [[TARGET]] {{.*}}`target_function + _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits