Skip to content

Conversation

@chestnykh
Copy link
Contributor

No description provided.

@chestnykh chestnykh requested a review from ldionne December 15, 2024 18:12
@chestnykh chestnykh requested a review from a team as a code owner December 15, 2024 18:12
@llvmbot
Copy link
Member

llvmbot commented Dec 15, 2024

@llvm/pr-subscribers-libunwind

Author: Dmitry Chestnykh (chestnykh)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/120013.diff

7 Files Affected:

  • (modified) libunwind/test/forceunwind.pass.cpp (-3)
  • (modified) libunwind/test/libunwind_01.pass.cpp (-3)
  • (modified) libunwind/test/libunwind_02.pass.cpp (-3)
  • (modified) libunwind/test/signal_frame.pass.cpp (-3)
  • (modified) libunwind/test/signal_unwind.pass.cpp (-3)
  • (modified) libunwind/test/unw_resume.pass.cpp (-3)
  • (modified) libunwind/test/unwind_leaffunction.pass.cpp (-3)
diff --git a/libunwind/test/forceunwind.pass.cpp b/libunwind/test/forceunwind.pass.cpp
index 344034e1ea5f5e..e8333eb74a979a 100644
--- a/libunwind/test/forceunwind.pass.cpp
+++ b/libunwind/test/forceunwind.pass.cpp
@@ -9,9 +9,6 @@
 
 // REQUIRES: linux
 
-// TODO: Figure out why this fails with Memory Sanitizer.
-// XFAIL: msan
-
 // Basic test for _Unwind_ForcedUnwind.
 // See libcxxabi/test/forced_unwind* tests too.
 
diff --git a/libunwind/test/libunwind_01.pass.cpp b/libunwind/test/libunwind_01.pass.cpp
index 838df6b5897204..82fb66d665c259 100644
--- a/libunwind/test/libunwind_01.pass.cpp
+++ b/libunwind/test/libunwind_01.pass.cpp
@@ -10,9 +10,6 @@
 // TODO: Investigate this failure on x86_64 macOS back deployment
 // XFAIL: stdlib=system && target=x86_64-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
 
-// TODO: Figure out why this fails with Memory Sanitizer.
-// XFAIL: msan
-
 #include <libunwind.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/libunwind/test/libunwind_02.pass.cpp b/libunwind/test/libunwind_02.pass.cpp
index 9fd8e5d7159c96..5f2d2b43bddc1c 100644
--- a/libunwind/test/libunwind_02.pass.cpp
+++ b/libunwind/test/libunwind_02.pass.cpp
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// TODO: Figure out why this fails with Memory Sanitizer.
-// XFAIL: msan
-
 // This test fails on older llvm, when built with picolibc.
 // XFAIL: clang-16 && LIBCXX-PICOLIBC-FIXME
 
diff --git a/libunwind/test/signal_frame.pass.cpp b/libunwind/test/signal_frame.pass.cpp
index 004029cfe1e90b..67b862c98fbfc7 100644
--- a/libunwind/test/signal_frame.pass.cpp
+++ b/libunwind/test/signal_frame.pass.cpp
@@ -12,9 +12,6 @@
 // TODO: Investigate this failure on Apple
 // XFAIL: target={{.+}}-apple-{{.+}}
 
-// TODO: Figure out why this fails with Memory Sanitizer.
-// XFAIL: msan
-
 // UNSUPPORTED: libunwind-arm-ehabi
 
 // The AIX assembler does not support CFI directives, which
diff --git a/libunwind/test/signal_unwind.pass.cpp b/libunwind/test/signal_unwind.pass.cpp
index 1c1566415a4d4b..8ba0c8b2859ac4 100644
--- a/libunwind/test/signal_unwind.pass.cpp
+++ b/libunwind/test/signal_unwind.pass.cpp
@@ -10,9 +10,6 @@
 // Ensure that the unwinder can cope with the signal handler.
 // REQUIRES: target={{(aarch64|riscv64|s390x|x86_64)-.+linux.*}}
 
-// TODO: Figure out why this fails with Memory Sanitizer.
-// XFAIL: msan
-
 // Note: this test fails on musl because:
 //
 //  (a) musl disables emission of unwind information for its build, and
diff --git a/libunwind/test/unw_resume.pass.cpp b/libunwind/test/unw_resume.pass.cpp
index 2b7470b5cad0eb..ca6068a828e0ac 100644
--- a/libunwind/test/unw_resume.pass.cpp
+++ b/libunwind/test/unw_resume.pass.cpp
@@ -10,9 +10,6 @@
 // Ensure that unw_resume() resumes execution at the stack frame identified by
 // cursor.
 
-// TODO: Figure out why this fails with Memory Sanitizer.
-// XFAIL: msan
-
 #include <libunwind.h>
 
 __attribute__((noinline)) void test_unw_resume() {
diff --git a/libunwind/test/unwind_leaffunction.pass.cpp b/libunwind/test/unwind_leaffunction.pass.cpp
index 98de7dc43260c2..4259406cc493d1 100644
--- a/libunwind/test/unwind_leaffunction.pass.cpp
+++ b/libunwind/test/unwind_leaffunction.pass.cpp
@@ -10,9 +10,6 @@
 // Ensure that leaf function can be unwund.
 // REQUIRES: target={{(aarch64|riscv64|s390x|x86_64)-.+linux.*}}
 
-// TODO: Figure out why this fails with Memory Sanitizer.
-// XFAIL: msan
-
 // Note: this test fails on musl because:
 //
 //  (a) musl disables emission of unwind information for its build, and

@chestnykh
Copy link
Contributor Author

chestnykh commented Dec 15, 2024

@ldionne i run these tests locally with msan (x86-64) and have no errors. Could you please tell on what architecture(s) the tests were failed?

@chestnykh
Copy link
Contributor Author

All CI failures look unrelated

@ldionne
Copy link
Member

ldionne commented Dec 16, 2024

Rebased onto main to re-trigger CI, which should solve the errors you were seeing.

I don't remember why these XFAILs were added, but if the CI passes with them removed, I'm happy.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if the CI is green.

@chestnykh chestnykh marked this pull request as draft December 16, 2024 18:23
@chestnykh chestnykh changed the title [Libunwind] Don't XFAIL tests with msan [Libunwind] Try to fix msan failures Dec 16, 2024
@chestnykh
Copy link
Contributor Author

chestnykh commented Dec 16, 2024

Maybe load order breaks something:
With -lunwind passed explicitly:

        linux-vdso.so.1 (0x0000700799647000)
        libunwind.so.1 => /usr/lib/libunwind.so.1 (0x00007007995fe000)
        libatomic.so.1 => /usr/lib/libatomic.so.1 (0x00007007995f3000)
        libc++.so.1 => /usr/lib/libc++.so.1 (0x00007007994ec000)
        libc++abi.so.1 => /usr/lib/libc++abi.so.1 (0x00007007949c0000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007007948d1000)
        libresolv.so.2 => /usr/lib/libresolv.so.2 (0x00007007948bf000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007007946ce000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007007946a0000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x0000700799649000)

With only -rtlib=compiler-rt -unwindlib=libunwind (without explicit -lunwind in the driver cmdline)

        linux-vdso.so.1 (0x0000751bd650e000)
        libatomic.so.1 => /usr/lib/libatomic.so.1 (0x0000751bd64fd000)
        libc++.so.1 => /usr/lib/libc++.so.1 (0x0000751bd18c5000)
        libc++abi.so.1 => /usr/lib/libc++abi.so.1 (0x0000751bd1885000)
        libunwind.so.1 => /usr/lib/libunwind.so.1 (0x0000751bd64ee000)
        libm.so.6 => /usr/lib/libm.so.6 (0x0000751bd1796000)
        libresolv.so.2 => /usr/lib/libresolv.so.2 (0x0000751bd1784000)
        libc.so.6 => /usr/lib/libc.so.6 (0x0000751bd1593000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x0000751bd1565000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x0000751bd6510000)

The possible reason why tests fail is that
MAYBE there are another libunwind on the testing host
which is loaded(?) instead of libunwind from llvm.
clang passes 'right' libunwind (-lunwind) to the linker
if -unwindlib=libunwind is passed to the driver
@chestnykh chestnykh marked this pull request as ready for review December 17, 2024 08:54
@chestnykh
Copy link
Contributor Author

I've debugged msan errors. On CI there were stack overflows caused by 'wrong' msan reports and circular calls libunwind -> libmsan -> libunwind.

For example:

#4234 0x0000555555587eb2 in __msan_warning_with_origin_noreturn () at /home/dima/work/llvm-project/compiler-rt/lib/msan/msan.cpp:422
#4235 0x00007ffff7f7828e in libunwind::Registers_x86_64::getRegister (this=0x7fffffa07cc0, regNum=-1) at /home/dima/work/llvm-project/libunwind/src/Registers.hpp:412
#4236 0x00007ffff7f72b5c in libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_x86_64>::getReg (this=0x7fffffa07cb0, regNum=-1)
    at /home/dima/work/llvm-project/libunwind/src/UnwindCursor.hpp:1353
#4237 0x00007ffff7f741a3 in libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_x86_64>::setInfoBasedOnIPRegister (this=0x7fffffa07cb0, isReturnAddress=false)
    at /home/dima/work/llvm-project/libunwind/src/UnwindCursor.hpp:2561
#4238 0x00007ffff7f6477f in __unw_init_local (cursor=0x7fffffa07cb0, context=0x7fffffa07c08) at /home/dima/work/llvm-project/libunwind/src/libunwind.cpp:91
#4239 0x00007ffff7fb2f48 in _Unwind_Backtrace (callback=0x55555561be20 <Unwind_Trace()>, ref=0x7fffffa07de8) at /home/dima/work/llvm-project/libunwind/src/UnwindLevel1-gcc-ext.c:137
#4240 0x000055555561bdcb in UnwindSlow () at /home/dima/work/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp:130
#4241 0x0000555555615455 in __sanitizer::BufferedStackTrace::Unwind(unsigned int, unsigned long, unsigned long, void*, unsigned long, unsigned long, bool) ()
    at /home/dima/work/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp:158
#4242 0x0000555555587985 in UnwindImpl () at /home/dima/work/llvm-project/compiler-rt/lib/msan/msan.cpp:342
#4243 0x0000555555587578 in Unwind () at /home/dima/work/llvm-project/compiler-rt/lib/msan/../sanitizer_common/sanitizer_stacktrace.h:130
#4244 PrintWarningWithOrigin () at /home/dima/work/llvm-project/compiler-rt/lib/msan/msan.cpp:247
#4245 0x0000555555587eb2 in __msan_warning_with_origin_noreturn () at /home/dima/work/llvm-project/compiler-rt/lib/msan/msan.cpp:422

There were also regular msan reports fixed by modifying tests srcs to add explicit initialization of unw_cursor_t and unw_context_t variables:

# .---command stderr------------
# | ==152363==WARNING: MemorySanitizer: use-of-uninitialized-value
# |     #0 0x7ffff7fa6564  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/lib/x86_64-unknown-linux-gnu/libunwind.so.1+0x6564)
# |     #1 0x7ffff7fa6bee  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/lib/x86_64-unknown-linux-gnu/libunwind.so.1+0x6bee)
# |     #2 0x7ffff7fa28f9  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/lib/x86_64-unknown-linux-gnu/libunwind.so.1+0x28f9)
# |     #3 0x55555562481d  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/unw_resume.pass.cpp.dir/t.tmp.exe+0xd081d)
# |     #4 0x5555556248a6  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/unw_resume.pass.cpp.dir/t.tmp.exe+0xd08a6)
# |     #5 0x7ffff7945e07  (/usr/lib/libc.so.6+0x25e07) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3)
# |     #6 0x7ffff7945ecb  (/usr/lib/libc.so.6+0x25ecb) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3)
# |     #7 0x555555587334  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/unw_resume.pass.cpp.dir/t.tmp.exe+0x33334)
# | 
# |   Uninitialized value was stored to memory at
# |     #0 0x55555558e52d  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/unw_resume.pass.cpp.dir/t.tmp.exe+0x3a52d)
# |     #1 0x7ffff7fa28dc  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/lib/x86_64-unknown-linux-gnu/libunwind.so.1+0x28dc)
# |     #2 0x55555562481d  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/unw_resume.pass.cpp.dir/t.tmp.exe+0xd081d)
# |     #3 0x5555556248a6  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/unw_resume.pass.cpp.dir/t.tmp.exe+0xd08a6)
# |     #4 0x7ffff7945e07  (/usr/lib/libc.so.6+0x25e07) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3)
# |     #5 0x7ffff7945ecb  (/usr/lib/libc.so.6+0x25ecb) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3)
# |     #6 0x555555587334  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/unw_resume.pass.cpp.dir/t.tmp.exe+0x33334)
# | 
# |   Uninitialized value was created by an allocation of 'context' in the stack frame
# |     #0 0x5555556247bc  (/home/dima/work/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/unw_resume.pass.cpp.dir/t.tmp.exe+0xd07bc)

Sometimes msan seems to fail proving that
variable is (un)initialized and emits false-positives.
Such false positives can lead to stack overflow (libc++ CI error)
So add explicit initialization of all variables that
msan thinks are used without initialization
Copy link
Member

@arichardson arichardson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't need to initialize these structures to silence sanitizer errors. I had a draft pr last year to fix this properly but forgot about it since other things came up: #67860

I'd prefer something like that. Alternatively I can update my change once I'm back in the office in January.

unw_cursor_t cursor;
unw_context_t uc;
#if __has_feature(memory_sanitizer)
__builtin_memset(&cursor, 0, sizeof(cursor));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not keen on working around the missing msan annotations on every call. This seems fragile.

@chestnykh chestnykh closed this Dec 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants