ADDITIONAL SYSTEM INFORMATION :
Linux bik 5.4.0-37-generic #41-Ubuntu SMP Wed Jun 3 18:57:02 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
openjdk 11.0.7 2020-04-14
OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-3ubuntu1)
OpenJDK 64-Bit Server VM (build 11.0.7+10-post-Ubuntu-3ubuntu1, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
ServerSocket#accept thows SocketTimeoutException even soTimeout is not set
problem is here
https://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/linux/native/libnet/linux_close.c#l449
when thread receives interruption during poll it tries to adjust timeout for next poll attempt, but in case when timeout is negative , NET_Timeout returns 0 and it leads to SocketTimeoutException
documentation for ServerSocket.accept says:
***
SocketTimeoutException if a timeout was previously set with setSoTimeout and
the timeout has been reached.
***
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) run attached java class
2) get PID of just started process
3) attach to process with gdb " gdb -p $PID"
4) Find native thread typing info threads and lokinfg for thead which currently in poll syscall
5) send signal to the thread : call pthread_kill($FOUND_TID,12)
6) see logs and observe that SocketTimeoutException occurred
PS: i found
'12' is a SIGUSR2 signal. SIGUSR2 is used to implement, suspend, and resume on Linux and macOS
https://docs.oracle.com/javase/9/troubleshoot/handle-signals-and-exceptions.htm#JSTGD356
1
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ServerSocket#accept does'n throw SocketTmeoutException when soTimeout is not set
ACTUAL -
ServerSocket#accept throws SocketTmeoutException when soTimeout is not set
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.ServerSocket;
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket serverSocket = new ServerSocket(8022);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Started");
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Accept");
serverSocket.accept();
} catch (IOException e) {
System.out.println("Gotcha. Should never occurred");
e.printStackTrace();
}
}
}
});
thread.start();
thread.join();
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
ignore SocketTimeotException when soTimeout is not set and retry accept operation
FREQUENCY : occasionally
Linux bik 5.4.0-37-generic #41-Ubuntu SMP Wed Jun 3 18:57:02 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
openjdk 11.0.7 2020-04-14
OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-3ubuntu1)
OpenJDK 64-Bit Server VM (build 11.0.7+10-post-Ubuntu-3ubuntu1, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
ServerSocket#accept thows SocketTimeoutException even soTimeout is not set
problem is here
https://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/linux/native/libnet/linux_close.c#l449
when thread receives interruption during poll it tries to adjust timeout for next poll attempt, but in case when timeout is negative , NET_Timeout returns 0 and it leads to SocketTimeoutException
documentation for ServerSocket.accept says:
***
SocketTimeoutException if a timeout was previously set with setSoTimeout and
the timeout has been reached.
***
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) run attached java class
2) get PID of just started process
3) attach to process with gdb " gdb -p $PID"
4) Find native thread typing info threads and lokinfg for thead which currently in poll syscall
5) send signal to the thread : call pthread_kill($FOUND_TID,12)
6) see logs and observe that SocketTimeoutException occurred
PS: i found
'12' is a SIGUSR2 signal. SIGUSR2 is used to implement, suspend, and resume on Linux and macOS
https://docs.oracle.com/javase/9/troubleshoot/handle-signals-and-exceptions.htm#JSTGD356
1
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ServerSocket#accept does'n throw SocketTmeoutException when soTimeout is not set
ACTUAL -
ServerSocket#accept throws SocketTmeoutException when soTimeout is not set
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.ServerSocket;
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket serverSocket = new ServerSocket(8022);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Started");
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Accept");
serverSocket.accept();
} catch (IOException e) {
System.out.println("Gotcha. Should never occurred");
e.printStackTrace();
}
}
}
});
thread.start();
thread.join();
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
ignore SocketTimeotException when soTimeout is not set and retry accept operation
FREQUENCY : occasionally
- duplicates
-
JDK-8237858 PlainSocketImpl.socketAccept() handles EINTR incorrectly
- Resolved
- relates to
-
JDK-8237858 PlainSocketImpl.socketAccept() handles EINTR incorrectly
- Resolved
-
JDK-8179905 Remove the use of gettimeofday in Networking code
- Resolved