-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
[libunwind] fix unwinding from signal handler #92291
Conversation
@llvm/pr-subscribers-libunwind Author: Azat Khuzhin (azat) ChangesIn case of this is frame of signal handler, the IP should be incremented, because the IP saved in the signal handler points to first non-executed instruction, while FDE/CIE expects IP to be after the first non-executed instruction. Refs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208 Full diff: https://github.com/llvm/llvm-project/pull/92291.diff 1 Files Affected:
diff --git a/libunwind/src/DwarfInstructions.hpp b/libunwind/src/DwarfInstructions.hpp
index bd9ece60ee588..5ea535be4b974 100644
--- a/libunwind/src/DwarfInstructions.hpp
+++ b/libunwind/src/DwarfInstructions.hpp
@@ -365,7 +365,12 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
// Return address is address after call site instruction, so setting IP to
// that does simulates a return.
- newRegisters.setIP(returnAddress);
+ //
+ // In case of this is frame of signal handler, the IP should be
+ // incremented, because the IP saved in the signal handler points to
+ // first non-executed instruction, while FDE/CIE expects IP to be after
+ // the first non-executed instruction.
+ newRegisters.setIP(returnAddress + cieInfo.isSignalFrame);
// Simulate the step by replacing the register set with the new ones.
registers = newRegisters;
|
Looks like unrelated?
|
5e3635c
to
7066c0d
Compare
In case of this is frame of signal handler, the IP should be incremented, because the IP saved in the signal handler points to first non-executed instruction, while FDE/CIE expects IP to be after the first non-executed instruction. v2: move the increment from DwarfInstructions<A, R>::stepWithDwarf() into the UnwindCursor<A, R>::setInfoBasedOnIPRegister() to avoid exposing posslibly unaligned IP (also note, that this matches with gcc implementation as well) v3: only for non _LIBUNWIND_SUPPORT_SEH_UNWIND/_WIN32 OS Refs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208
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, this seems like the right place to handle this.
@azat do you need this to be committed on your behalf? |
7066c0d
to
1f1e3d2
Compare
I would be very much appreciate that, since I don't have write access. |
In case of this is frame of signal handler, the IP should be incremented, because the IP saved in the signal handler points to first non-executed instruction, while FDE/CIE expects IP to be after the first non-executed instruction. Refs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208
Is it possible to add a test case for this? |
This is breaking a number of tests for the UBSAN on AIX, the traceback produced by the runtime are no longer correct. Before this change:
After:
|
…e added to exclude traceback based unwinding used for AIX.
…e added to exclude traceback based unwinding used for AIX.
…1069) Patch [llvm#92291](llvm#92291) causes wrong traceback from a signal handler for AIX because the AIX unwinder uses the traceback table at the end of each function instead of FDE/CIE for unwinding. This patch adds a condition to exclude traceback table based unwinding from the code added by the patch. (cherry picked from commit d90fa61)
…1069) Patch [llvm#92291](llvm#92291) causes wrong traceback from a signal handler for AIX because the AIX unwinder uses the traceback table at the end of each function instead of FDE/CIE for unwinding. This patch adds a condition to exclude traceback table based unwinding from the code added by the patch. (cherry picked from commit d90fa61)
…1069) Patch [llvm#92291](llvm#92291) causes wrong traceback from a signal handler for AIX because the AIX unwinder uses the traceback table at the end of each function instead of FDE/CIE for unwinding. This patch adds a condition to exclude traceback table based unwinding from the code added by the patch.
In case of this is frame of signal handler, the IP should be incremented, because the IP saved in the signal handler points to first non-executed instruction, while FDE/CIE expects IP to be after the first non-executed instruction.
Refs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208