kohlschutter / junixsocket

Unix Domain Sockets in Java 7 and newer (AF_UNIX), AF_TIPC, AF_VSOCK, and more
Apache License 2.0
438 stars 114 forks source link

junixsocket 2.3.3 can't bind on glibc-Linux-aarch64 #89

Closed AGSaidi closed 3 years ago

AGSaidi commented 3 years ago

Describe the bug junixsocket 2.3.3 fails to run selftests on Linux-aarch64

To Reproduce Steps to reproduce the behavior:

$ java -jar junixsocket-selftest-2.3.3-jar-with-dependencies.jar junixsocket selftest

...
Failures (29):
  JUnit Jupiter:AcceptTimeoutTest:testCatchTimeout()
    MethodSource [className = 'org.newsclub.net.unix.AcceptTimeoutTest', methodName = 'testCatchTimeout', methodParameterTypes = '']
    => java.net.SocketException:
       org.newsclub.net.unix.NativeUnixSocket.bind(Native Method)
       org.newsclub.net.unix.AFUNIXSocketImpl.bind(AFUNIXSocketImpl.java:179)
       org.newsclub.net.unix.AFUNIXServerSocket.bind(AFUNIXServerSocket.java:107)
       java.base/java.net.ServerSocket.bind(ServerSocket.java:349)
       org.newsclub.net.unix.SocketTestBase.startServer(SocketTestBase.java:88)
       org.newsclub.net.unix.AcceptTimeoutTest.lambda$testCatchTimeout$0(AcceptTimeoutTest.java:48)
       org.junit.jupiter.api.AssertTimeout.lambda$assertTimeoutPreemptively$2(AssertTimeout.java:102)
       org.junit.jupiter.api.AssertTimeout.lambda$assertTimeoutPreemptively$4(AssertTimeout.java:138)
       java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
       java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
       [...]
  JUnit Jupiter:AcceptTimeoutTest:testTimeoutAfterDelay()
    MethodSource [className = 'org.newsclub.net.unix.AcceptTimeoutTest', methodName = 'testTimeoutAfterDelay', methodParameterTypes = '']
    => java.net.SocketException:
       org.newsclub.net.unix.NativeUnixSocket.bind(Native Method)
       org.newsclub.net.unix.AFUNIXSocketImpl.bind(AFUNIXSocketImpl.java:179)
       org.newsclub.net.unix.AFUNIXServerSocket.bind(AFUNIXServerSocket.java:107)
       java.base/java.net.ServerSocket.bind(ServerSocket.java:349)
       org.newsclub.net.unix.SocketTestBase.startServer(SocketTestBase.java:88)
       org.newsclub.net.unix.AcceptTimeoutTest.lambda$testTimeoutAfterDelay$1(AcceptTimeoutTest.java:73)
       org.junit.jupiter.api.AssertTimeout.lambda$assertTimeoutPreemptively$2(AssertTimeout.java:102)
       org.junit.jupiter.api.AssertTimeout.lambda$assertTimeoutPreemptively$4(AssertTimeout.java:138)
       java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
       java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
       [...]
Selftest results:
FAIL    junixsocket-common  8/39 (2 skipped)
DONE    junixsocket-rmi 0/5

Expected behavior Self tests should pass as they do on 2.3.2

Output/Screenshots See above

Environment (please complete the following information):

Notes

kohlschuetter commented 3 years ago

In 2.3.3, we're calling __xstat with a hardcoded _STAT_VER of 1, which works on x86_64, but may fail on other platforms (like aarch64).

AGSaidi commented 3 years ago

Given that LSB 1.3 predates the 64b Arm architecture and says version 3 is required, what is the reason for choosing 0?

kohlschuetter commented 3 years ago

This is straight from the Linux SDK (/usr/include/aarch64-linux-gnu/sys/stat.h).

I've actually simplified this further by just using _STAT_VER directly from the SDKs that I'm using to crosscompile (commit a57b246cf82460482802422e72c363b6f300ad08).

We will have to make sure this doesn't again break some obscure old glibc from two decades ago, so this would need further testing.

kohlschuetter commented 3 years ago

I think the man page in https://refspecs.linuxfoundation.org/LSB_1.3.0/gLSB/gLSB/baselib-xstat-1.html is just outdated (3 seems to apply to 31/32-bit systems and S390x?), and "version" as in "increasing over time" apparently is not what the authors had in mind here. In reality, _STAT_VER is just a platform-dependent marker that indicates the format of the struct stat that is returned by the kernel.

All in all, it looks like "stat" has had quite the tumultuous history (different formats on different platforms, sometimes not defined as function but a macro, etc.).

kohlschuetter commented 3 years ago

Please verify with this build (version 2.3.4 currently in staging only).

AGSaidi commented 3 years ago

Tested on Arm versions of Ubuntu 18.04, CentOS7, and Amazon Linux2 successfully:

Selftest results:
PASS    junixsocket-common  37/39 (2 skipped)
PASS    junixsocket-rmi 5/5

Supported capabilities:   [CAPABILITY_PEER_CREDENTIALS, CAPABILITY_ANCILLARY_MESSAGES, CAPABILITY_FILE_DESCRIPTORS, CAPABILITY_ABSTRACT_NAMESPACE]
Unsupported capabilities: []
kohlschuetter commented 3 years ago

Thanks for verifying, @AGSaidi!

junixsocket 2.3.4 has been released to Maven central and GitHub.