-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
[sanitizer_common] Fix UnwindFast on SPARC #101634
[sanitizer_common] Fix UnwindFast on SPARC #101634
Conversation
``` UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp ``` `FAIL`s on 32 and 64-bit Linux/sparc64 (and on Solaris/sparcv9, too: the test isn't Linux-specific at all). With `UBSAN_OPTIONS=fast_unwind_on_fatal=1`, the stack trace shows a duplicate innermost frame: ``` compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:31: runtime error: execution reached the end of a value-returning function without returning a value #0 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 #1 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 llvm#2 0x7003a714 in g() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:17:38 ``` which isn't seen with `fast_unwind_on_fatal=0`. This turns out to be another fallout from fixing `__builtin_return_address`/`__builtin_extract_return_addr` on SPARC. In `sanitizer_stacktrace_sparc.cpp` (`BufferedStackTrace::UnwindFast`) the `pc` arg is the return address, while `pc1` from the stack frame (`fr_savpc`) is the address of the `call` insn, leading to a double entry for the innermost frame in `trace_buffer[]`. This patch fixes this by moving the adjustment before all uses. Tested on `sparc64-unknown-linux-gnu` and `sparcv9-sun-solaris2.11` (with the `ubsan/TestCases/Misc/Linux` tests enabled).
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Rainer Orth (rorth) Changes
which isn't seen with This turns out to be another fallout from fixing This patch fixes this by moving the adjustment before all uses. Tested on Full diff: https://github.com/llvm/llvm-project/pull/101634.diff 1 Files Affected:
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cpp
index a2000798a3907..74f435287af3c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cpp
@@ -58,17 +58,16 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
// Avoid infinite loop when frame == frame[0] by using frame > prev_frame.
while (IsValidFrame(bp, stack_top, bottom) && IsAligned(bp, sizeof(uhwptr)) &&
size < max_depth) {
- uhwptr pc1 = ((uhwptr *)bp)[15];
+ // %o7 contains the address of the call instruction and not the
+ // return address, so we need to compensate.
+ uhwptr pc1 = GetNextInstructionPc(((uhwptr *)bp)[15]);
// Let's assume that any pointer in the 0th page is invalid and
// stop unwinding here. If we're adding support for a platform
// where this isn't true, we need to reconsider this check.
if (pc1 < kPageSize)
break;
- if (pc1 != pc) {
- // %o7 contains the address of the call instruction and not the
- // return address, so we need to compensate.
- trace_buffer[size++] = GetNextInstructionPc((uptr)pc1);
- }
+ if (pc1 != pc)
+ trace_buffer[size++] = pc1;
bottom = bp;
bp = (uptr)((uhwptr *)bp)[14] + STACK_BIAS;
}
|
@ebotcazou would be the natural reviewer, but for some reason I cannot select him. |
That's because he's not part of the GitHub organization. |
/cherry-pick 3368a32 |
``` UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp ``` `FAIL`s on 32 and 64-bit Linux/sparc64 (and on Solaris/sparcv9, too: the test isn't Linux-specific at all). With `UBSAN_OPTIONS=fast_unwind_on_fatal=1`, the stack trace shows a duplicate innermost frame: ``` compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:31: runtime error: execution reached the end of a value-returning function without returning a value #0 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 #1 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 #2 0x7003a714 in g() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:17:38 ``` which isn't seen with `fast_unwind_on_fatal=0`. This turns out to be another fallout from fixing `__builtin_return_address`/`__builtin_extract_return_addr` on SPARC. In `sanitizer_stacktrace_sparc.cpp` (`BufferedStackTrace::UnwindFast`) the `pc` arg is the return address, while `pc1` from the stack frame (`fr_savpc`) is the address of the `call` insn, leading to a double entry for the innermost frame in `trace_buffer[]`. This patch fixes this by moving the adjustment before all uses. Tested on `sparc64-unknown-linux-gnu` and `sparcv9-sun-solaris2.11` (with the `ubsan/TestCases/Misc/Linux` tests enabled). (cherry picked from commit 3368a32)
/pull-request #101848 |
* 'main' of https://github.com/llvm/llvm-project: [RISCV] Improve hasAllNBitUsers for users of SLLI. [RISCV] Invert if conditions in the switch in RISCVDAGToDAGISel::hasAllNBitUsers. NFC [Transforms] Construct SmallVector with ArrayRef (NFC) (llvm#101851) [RISCV] Capitalize some variable names. NFC [sanitizer_common] Fix UnwindFast on SPARC (llvm#101634) [builtins] Fix divtc3.c etc. compilation on Solaris/SPARC with gcc (llvm#101662) [NFC][asan] Track current dynamic init module (llvm#101597) [libc] enable most of the entrypoints on aarch64 (llvm#101797) [SandboxIR][Tracker] Track InsertIntoBB (llvm#101595) [SCEV] Use const SCEV * explicitly in more places. [ELF] Move outputSections into Ctx. NFC [ELF] Move ElfSym into Ctx. NFC [ELF] Move Out into Ctx. NFC [test][asan] Fix the test checks [NFC][asan] Switch from list to DynInitGlobalsByModule (llvm#101596) Signed-off-by: Edwiin Kusuma Jaya <kutemeikito0905@gmail.com>
``` UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp ``` `FAIL`s on 32 and 64-bit Linux/sparc64 (and on Solaris/sparcv9, too: the test isn't Linux-specific at all). With `UBSAN_OPTIONS=fast_unwind_on_fatal=1`, the stack trace shows a duplicate innermost frame: ``` compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:31: runtime error: execution reached the end of a value-returning function without returning a value #0 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 #1 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 #2 0x7003a714 in g() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:17:38 ``` which isn't seen with `fast_unwind_on_fatal=0`. This turns out to be another fallout from fixing `__builtin_return_address`/`__builtin_extract_return_addr` on SPARC. In `sanitizer_stacktrace_sparc.cpp` (`BufferedStackTrace::UnwindFast`) the `pc` arg is the return address, while `pc1` from the stack frame (`fr_savpc`) is the address of the `call` insn, leading to a double entry for the innermost frame in `trace_buffer[]`. This patch fixes this by moving the adjustment before all uses. Tested on `sparc64-unknown-linux-gnu` and `sparcv9-sun-solaris2.11` (with the `ubsan/TestCases/Misc/Linux` tests enabled). (cherry picked from commit 3368a32)
``` UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp ``` `FAIL`s on 32 and 64-bit Linux/sparc64 (and on Solaris/sparcv9, too: the test isn't Linux-specific at all). With `UBSAN_OPTIONS=fast_unwind_on_fatal=1`, the stack trace shows a duplicate innermost frame: ``` compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:31: runtime error: execution reached the end of a value-returning function without returning a value #0 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 llvm#1 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 llvm#2 0x7003a714 in g() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:17:38 ``` which isn't seen with `fast_unwind_on_fatal=0`. This turns out to be another fallout from fixing `__builtin_return_address`/`__builtin_extract_return_addr` on SPARC. In `sanitizer_stacktrace_sparc.cpp` (`BufferedStackTrace::UnwindFast`) the `pc` arg is the return address, while `pc1` from the stack frame (`fr_savpc`) is the address of the `call` insn, leading to a double entry for the innermost frame in `trace_buffer[]`. This patch fixes this by moving the adjustment before all uses. Tested on `sparc64-unknown-linux-gnu` and `sparcv9-sun-solaris2.11` (with the `ubsan/TestCases/Misc/Linux` tests enabled).
``` UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp ``` `FAIL`s on 32 and 64-bit Linux/sparc64 (and on Solaris/sparcv9, too: the test isn't Linux-specific at all). With `UBSAN_OPTIONS=fast_unwind_on_fatal=1`, the stack trace shows a duplicate innermost frame: ``` compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:31: runtime error: execution reached the end of a value-returning function without returning a value #0 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 #1 0x7003a708 in f() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:14:35 #2 0x7003a714 in g() compiler-rt/test/ubsan/TestCases/Misc/Linux/diag-stacktrace.cpp:17:38 ``` which isn't seen with `fast_unwind_on_fatal=0`. This turns out to be another fallout from fixing `__builtin_return_address`/`__builtin_extract_return_addr` on SPARC. In `sanitizer_stacktrace_sparc.cpp` (`BufferedStackTrace::UnwindFast`) the `pc` arg is the return address, while `pc1` from the stack frame (`fr_savpc`) is the address of the `call` insn, leading to a double entry for the innermost frame in `trace_buffer[]`. This patch fixes this by moving the adjustment before all uses. Tested on `sparc64-unknown-linux-gnu` and `sparcv9-sun-solaris2.11` (with the `ubsan/TestCases/Misc/Linux` tests enabled).
When investigating PR llvm#101634, it turned out that `UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp` isn't Linux-specific at all. In fact, none of the `ubsan/TestCases/Misc/Linux` tests are. Therefore this patch moves them to `Misc/Posix` instead. Tested on `sparc64-unknown-linux-gnu`, `sparcv9-sun-solaris2.11`, `x86_64-pc-linux-gnu`, and `amd64-pc-solaris2.11`.
When investigating PR #101634, it turned out that `UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp` isn't Linux-specific at all. In fact, none of the `ubsan/TestCases/Misc/Linux` tests are. Therefore this patch moves them to `Misc/Posix` instead. Tested on `sparc64-unknown-linux-gnu`, `sparcv9-sun-solaris2.11`, `x86_64-pc-linux-gnu`, and `amd64-pc-solaris2.11`.
When investigating PR llvm#101634, it turned out that `UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp` isn't Linux-specific at all. In fact, none of the `ubsan/TestCases/Misc/Linux` tests are. Therefore this patch moves them to `Misc/Posix` instead. Tested on `sparc64-unknown-linux-gnu`, `sparcv9-sun-solaris2.11`, `x86_64-pc-linux-gnu`, and `amd64-pc-solaris2.11`.
When investigating PR llvm#101634, it turned out that `UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp` isn't Linux-specific at all. In fact, none of the `ubsan/TestCases/Misc/Linux` tests are. Therefore this patch moves them to `Misc/Posix` instead. Tested on `sparc64-unknown-linux-gnu`, `sparcv9-sun-solaris2.11`, `x86_64-pc-linux-gnu`, and `amd64-pc-solaris2.11`.
When investigating PR llvm#101634, it turned out that `UBSan-Standalone-sparc :: TestCases/Misc/Linux/diag-stacktrace.cpp` isn't Linux-specific at all. In fact, none of the `ubsan/TestCases/Misc/Linux` tests are. Therefore this patch moves them to `Misc/Posix` instead. Tested on `sparc64-unknown-linux-gnu`, `sparcv9-sun-solaris2.11`, `x86_64-pc-linux-gnu`, and `amd64-pc-solaris2.11`.
FAIL
s on 32 and 64-bit Linux/sparc64 (and on Solaris/sparcv9, too: the test isn't Linux-specific at all). WithUBSAN_OPTIONS=fast_unwind_on_fatal=1
, the stack trace shows a duplicate innermost frame:which isn't seen with
fast_unwind_on_fatal=0
.This turns out to be another fallout from fixing
__builtin_return_address
/__builtin_extract_return_addr
on SPARC. Insanitizer_stacktrace_sparc.cpp
(BufferedStackTrace::UnwindFast
) thepc
arg is the return address, whilepc1
from the stack frame (fr_savpc
) is the address of thecall
insn, leading to a double entry for the innermost frame intrace_buffer[]
.This patch fixes this by moving the adjustment before all uses.
Tested on
sparc64-unknown-linux-gnu
andsparcv9-sun-solaris2.11
(with theubsan/TestCases/Misc/Linux
tests enabled).