[libunwind] [libunwind] Fix aarch64 unwinding with a debugger attached (PR #162867)
Martin Storsjö via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 10 08:20:56 PDT 2025
https://github.com/mstorsjo created https://github.com/llvm/llvm-project/pull/162867
See https://github.com/LuaJIT/LuaJIT/issues/593#issuecomment-1717728494 for the original explanation of the problem.
In short; when a debugger is attached, there's a
function KiUserExceptionDispatcher in the stack that is being unwound. The function KiUserExceptionDispatcher contains a CONTEXT, with a copy of the context from where the exception was raised. When unwinding through this function, this whole CONTEXT gets restored.
This CONTEXT is what we receive a pointer to in the callbacks, as the ms_ctx pointer.
When we unwind manually using RtlUnwindEx, the unwinding overwrites the CONTEXT that is passed to it. Thus, to avoid clobbering the CONTEXT that needs to be restored by KiUserExceptionDispatcher, we could either declare a new temporary CONTEXT on the stack before calling RtlUnwindEx, or just use disp->ContextRecord as we already have available.
Fixes: https://github.com/llvm/llvm-project/issues/161851
>From 3325101825fcf0cd35d0d03990044154e27f06bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Fri, 10 Oct 2025 10:34:39 +0300
Subject: [PATCH] [libunwind] Fix aarch64 unwinding with a debugger attached
See https://github.com/LuaJIT/LuaJIT/issues/593#issuecomment-1717728494
for the original explanation of the problem.
In short; when a debugger is attached, there's a
function KiUserExceptionDispatcher in the stack that is being
unwound. The function KiUserExceptionDispatcher contains
a CONTEXT, with a copy of the context from where the exception
was raised. When unwinding through this function, this
whole CONTEXT gets restored.
This CONTEXT is what we receive a pointer to in the callbacks,
as the ms_ctx pointer.
When we unwind manually using RtlUnwindEx, the unwinding
overwrites the CONTEXT that is passed to it. Thus, to avoid
clobbering the CONTEXT that needs to be restored by
KiUserExceptionDispatcher, we could either declare a new
temporary CONTEXT on the stack before calling RtlUnwindEx,
or just use disp->ContextRecord as we already have
available.
Fixes: https://github.com/llvm/llvm-project/issues/161851
Co-authored-by: Peter Cawley <corsix at corsix.org>
Co-authored-by: Hannes Domani <ssbssa at yahoo.de>
---
libunwind/src/Unwind-seh.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libunwind/src/Unwind-seh.cpp b/libunwind/src/Unwind-seh.cpp
index 8b83f10615f22..058369acf3360 100644
--- a/libunwind/src/Unwind-seh.cpp
+++ b/libunwind/src/Unwind-seh.cpp
@@ -174,7 +174,7 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
}
// FIXME: Indicate target frame in foreign case!
// phase 2: the clean up phase
- RtlUnwindEx(frame, (PVOID)disp->ControlPc, ms_exc, exc, ms_ctx, disp->HistoryTable);
+ RtlUnwindEx(frame, (PVOID)disp->ControlPc, ms_exc, exc, disp->ContextRecord, disp->HistoryTable);
_LIBUNWIND_ABORT("RtlUnwindEx() failed");
case _URC_INSTALL_CONTEXT: {
// If we were called by __libunwind_seh_personality(), indicate that
More information about the cfe-commits
mailing list