-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[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
Conversation
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.
@llvm/pr-subscribers-lldb Author: Pavel Labath (labath) ChangesThe 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:
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
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.