Skip to content

[lldb/aarch64] Allow unaligned PC addresses below a trap handler #92093

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 15, 2024

Conversation

labath
Copy link
Collaborator

@labath labath commented May 14, 2024

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.

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.
@labath labath requested review from jasonmolenda and omjavaid May 14, 2024 10:06
@labath labath requested a review from JDevlieghere as a code owner May 14, 2024 10:06
@llvmbot llvmbot added the lldb label May 14, 2024
@llvmbot
Copy link
Member

llvmbot commented May 14, 2024

@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/92093.diff

3 Files Affected:

  • (modified) lldb/source/Target/UnwindLLDB.cpp (+6-1)
  • (added) lldb/test/Shell/Unwind/Inputs/unaligned-pc-sigbus.c (+21)
  • (added) lldb/test/Shell/Unwind/unaligned-pc-sigbus.test (+26)
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..f74ec1e858551
--- /dev/null
+++ b/lldb/test/Shell/Unwind/unaligned-pc-sigbus.test
@@ -0,0 +1,26 @@
+# REQUIRES: (target-aarch64 || target-arm) && native
+# UNSUPPORTED: system-windows
+
+# RUN: %clang_host %S/Inputs/unaligned-pc-sigbus.c -o %t
+# RUN: %lldb -s %s -o exit %t | FileCheck %s
+
+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
+

# CHECK: (lldb) thread backtrace
# CHECK: frame #0: {{.*}}`sigbus_handler
# Unknown number of signal trampoline frames
# CHECK: frame #{{[0-9]+}}: [[TARGET]] {{.*}}`target_function
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will currently not unwind past the target_function without the fix in #91321

# CHECK: Breakpoint 1: where = {{.*}}`sigbus_handler

run
# CHECK: thread #1, {{.*}} stop reason = signal SIGBUS
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing I'll also need to forward some mach exception to make this work. Would that be EXC_BAD_ACCESS?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes doing b sigbus_handler; r stops with an EXC_BAD_ACCESS without it being delivered to the process.
b sigbus_handler; settings set platform.plugin.darwin.ignored-exceptions EXC_BAD_ACCESS; r will stop when the SIGBUS is delivered.
b sigbus_handler; settings set platform.plugin.darwin.ignored-exceptions EXC_BAD_ACCESS; process handle -p true -s false SIGBUS; r will stop in sigbus_handler.

On macOS we hit the same failure we saw in #91321 where we don't have eh_frame details for _sigtramp so this frameless leaf function that crashed is not discovered when we do the stack walk. This will need to be xfailed on macOS for the same reason as 91321. FWIW I filed a little work item on myself to figure out Something That Can Be Done in rdar://128031075 if you want to annotate the xfail.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for checking this out. I'll xfail the test and reference the rdar, and also the llvm bug I created earlier.

Copy link
Collaborator

@jasonmolenda jasonmolenda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good change, thanks for fixing this.

@labath labath merged commit d12c48c into llvm:main May 15, 2024
4 checks passed
@labath labath deleted the sigbus branch May 15, 2024 08:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants