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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lldb/source/Target/UnwindLLDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
21 changes: 21 additions & 0 deletions lldb/test/Shell/Unwind/Inputs/unaligned-pc-sigbus.c
Original file line number Diff line number Diff line change
@@ -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();
}
31 changes: 31 additions & 0 deletions lldb/test/Shell/Unwind/unaligned-pc-sigbus.test
Original file line number Diff line number Diff line change
@@ -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
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.


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
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


Loading