Description
The MachOTest.UnalignedLC
test (LLVM-Unit :: BinaryFormat/./BinaryFormatTests/11/193
) has been failing on and off in the past on Solaris/sparcv9. However, since LLVM 18 the failure has become consistent, as I've just re-discovered:
- In a 1-stage build with
clang-17
as build compiler, the testPASS
es. - However, when switching the build compiler to
clang-18
, the test consistentlyFAIL
s as I found when trying thatclang-17
toclang-18
switch on the Solaris/sparcv9 buildbot. - In a 2-stage build, the failure is consistent irrespective of build compiler.
The failure is like this:
GTEST_OUTPUT=json:/var/llvm/local-sparcv9-release-stage2-A-flang-clang18/tools/clang/stage2-bins/unittests/BinaryFormat/./BinaryFormatTests-LLVM-Unit-25980-11-193.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=193 GTEST_SHARD_INDEX=11 /var/llvm/local-sparcv9-release-stage2-A-flang-clang18/tools/clang/stage2-bins/unittests/BinaryFormat/./BinaryFormatTests
--
Note: This is test shard 12 of 193.
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from MachOTest
[ RUN ] MachOTest.UnalignedLC
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 BinaryFormatTests 0x0000000100180b4c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 36
1 BinaryFormatTests 0x00000001001814f4 SignalHandler(int) + 896
2 libc.so.1 0x00007fffff0c6410 __sighndlr + 12
3 libc.so.1 0x00007fffff0b8cb8 call_user_handler + 1024
4 libc.so.1 0x00007fffff0b9078 sigacthandler + 160
5 BinaryFormatTests 0x00000001000d1e00 MachOTest_UnalignedLC_Test::TestBody() + 48
6 BinaryFormatTests 0x00000001002383f8 testing::Test::Run() + 432
7 BinaryFormatTests 0x0000000100239ba4 testing::TestInfo::Run() + 484
8 BinaryFormatTests 0x000000010023abe4 testing::TestSuite::Run() + 1244
9 BinaryFormatTests 0x000000010024c778 testing::internal::UnitTestImpl::RunAllTests() + 2788
10 BinaryFormatTests 0x000000010024bb0c testing::UnitTest::Run() + 128
11 BinaryFormatTests 0x00000001002196dc main + 168
12 BinaryFormatTests 0x00000001000c82a4 _start + 100
--
exit: -10
With more debug info from a past build, there's
FAIL: LLVM-Unit :: BinaryFormat/./BinaryFormatTests/MachOTest.UnalignedLC (1755 of 68187)
******************** TEST 'LLVM-Unit :: BinaryFormat/./BinaryFormatTests/MachOTest.UnalignedLC' FAILED ********************
Note: Google Test filter = MachOTest.UnalignedLC
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from MachOTest
[ RUN ] MachOTest.UnalignedLC
0 BinaryFormatTests 0x0000000100269930 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 44
1 BinaryFormatTests 0x0000000100269d14 PrintStackTraceSignalHandler(void*) + 12
2 BinaryFormatTests 0x0000000100268bb4 llvm::sys::RunSignalHandlers() + 132
3 BinaryFormatTests 0x000000010026aa80 SignalHandler(int) + 216
4 libc.so.1 0xffffffff7eedc840 __sighndlr + 12
5 libc.so.1 0xffffffff7eecf27c call_user_handler + 852
6 libc.so.1 0xffffffff7eecf5d4 sigacthandler + 84
7 BinaryFormatTests 0x00000001001e228c void llvm::sys::swapByteOrder<unsigned int>(unsigned int&) + 8
8 BinaryFormatTests 0x00000001001dfdc4 llvm::MachO::swapStruct(llvm::MachO::mach_header&) + 4
9 BinaryFormatTests 0x00000001001dfc04 MachOTest_UnalignedLC_Test::TestBody() + 48
10 BinaryFormatTests 0x00000001002eeeb8 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) + 40
11 BinaryFormatTests 0x00000001002d8974 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) + 44
12 BinaryFormatTests 0x00000001002d8904 testing::Test::Run() + 164
13 BinaryFormatTests 0x00000001002d9204 testing::TestInfo::Run() + 212
14 BinaryFormatTests 0x00000001002d9a00 testing::TestCase::Run() + 216
15 BinaryFormatTests 0x00000001002de948 testing::internal::UnitTestImpl::RunAllTests() + 684
16 BinaryFormatTests 0x00000001002f0c64 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) + 40
17 BinaryFormatTests 0x00000001002de654 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) + 44
18 BinaryFormatTests 0x00000001002de58c testing::UnitTest::Run() + 148
19 BinaryFormatTests 0x00000001002d0ac4 RUN_ALL_TESTS() + 12
20 BinaryFormatTests 0x00000001002d0aa8 main + 136
21 BinaryFormatTests 0x00000001001d5fa4 _start + 100
The program dies with SIGBUS
like so:
Incurred fault #5, FLTACCESS %pc = 0x1001E228C
siginfo: SIGBUS BUS_ADRALN addr=0xFFFFFFFF7FFFE263
Received signal #10, SIGBUS [default]
siginfo: SIGBUS BUS_ADRALN addr=0xFFFFFFFF7FFFE263
i.e. the input operand isn't properly aligned:
Thread 2 received signal SIGBUS, Bus error.
[Switching to Thread 1 (LWP 1)]
0x00000001001e228c in void llvm::sys::swapByteOrder<unsigned int>(unsigned int&) ()
1: x/i $pc
=> 0x1001e228c <_ZN4llvm3sys13swapByteOrderIjEEvRT_+8>: ld [ %i0 ], %o0
(gdb) p/x $i0
$1 = 0xffffffff7fffe123
(gdb) where
#0 0x00000001001e228c in void llvm::sys::swapByteOrder<unsigned int>(unsigned int&) ()
#1 0x00000001001dfdcc in llvm::MachO::swapStruct(llvm::MachO::mach_header&) ()
#2 0x00000001001dfc0c in MachOTest_UnalignedLC_Test::TestBody() ()
SPARC being a strict-alignment target, natural alignment is required for all operands, so e.g. an unsigned int
must be at least 2-byte aligned, which isn't the case here.
I think I ultimately traced this to llvm::byteswap
being ignorant of this requirement. Considering the call chain
llvm/unittests/BinaryFormat/MachOTest.cpp (TEST(MachOTest, UnalignedLC))
-> llvm/include/llvm/BinaryFormat/MachO.h (swapStruct)
-> llvm/include/llvm/Support/SwapByteOrder.h (sys::swapByteOrder)
-> llvm/include/llvm/Support/SwapByteOrder.h (sys::getSwappedBytes)
-> llvm/include/llvm/ADT/bit.h (llvm::byteswap)
llvm::byteswap
does nothing to deal with unaligned input.
While one could force the alignment in the testcase, its name (UnalignedLC
) strongly suggests that it's exactly about the unaligned case, so that seems wrong. Besides, llvm::byteswap
needs to be robust irrespective of input IMO.