Skip to content

Commit 0896c19

Browse files
committed
fix arthas-boot blocking in findTcpListenProcess method. #3007
1 parent 47f7eb2 commit 0896c19

File tree

1 file changed

+61
-17
lines changed

1 file changed

+61
-17
lines changed

common/src/main/java/com/taobao/arthas/common/SocketUtils.java

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
import java.net.ServerSocket;
55
import java.util.List;
66
import java.util.Random;
7+
import java.util.concurrent.Callable;
8+
import java.util.concurrent.ExecutorService;
9+
import java.util.concurrent.Executors;
10+
import java.util.concurrent.Future;
11+
import java.util.concurrent.TimeUnit;
12+
import java.util.concurrent.TimeoutException;
713

814
import javax.net.ServerSocketFactory;
915

@@ -32,33 +38,71 @@ private SocketUtils() {
3238
}
3339

3440
public static long findTcpListenProcess(int port) {
41+
// Add a timeout of 5 seconds to prevent blocking
42+
final int TIMEOUT_SECONDS = 5;
43+
ExecutorService executor = Executors.newSingleThreadExecutor();
3544
try {
36-
if (OSUtils.isWindows()) {
37-
String[] command = { "netstat", "-ano", "-p", "TCP" };
38-
List<String> lines = ExecutingCommand.runNative(command);
39-
for (String line : lines) {
40-
if (line.contains("LISTENING")) {
41-
// TCP 0.0.0.0:49168 0.0.0.0:0 LISTENING 476
42-
String[] strings = line.trim().split("\\s+");
43-
if (strings.length == 5) {
44-
if (strings[1].endsWith(":" + port)) {
45-
return Long.parseLong(strings[4]);
46-
}
47-
}
48-
}
45+
Future<Long> future = executor.submit(new Callable<Long>() {
46+
@Override
47+
public Long call() throws Exception {
48+
return doFindTcpListenProcess(port);
4949
}
50+
});
51+
52+
try {
53+
return future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
54+
} catch (TimeoutException e) {
55+
future.cancel(true);
56+
return -1;
57+
} catch (Exception e) {
58+
return -1;
59+
}
60+
} finally {
61+
executor.shutdownNow();
62+
}
63+
}
64+
65+
private static long doFindTcpListenProcess(int port) {
66+
try {
67+
if (OSUtils.isWindows()) {
68+
return findTcpListenProcessOnWindows(port);
5069
}
5170

5271
if (OSUtils.isLinux() || OSUtils.isMac()) {
53-
String pid = ExecutingCommand.getFirstAnswer("lsof -t -s TCP:LISTEN -i TCP:" + port);
54-
if (!pid.trim().isEmpty()) {
55-
return Long.parseLong(pid);
56-
}
72+
return findTcpListenProcessOnUnix(port);
5773
}
5874
} catch (Throwable e) {
5975
// ignore
6076
}
77+
return -1;
78+
}
79+
80+
private static long findTcpListenProcessOnWindows(int port) {
81+
String[] command = { "netstat", "-ano", "-p", "TCP" };
82+
List<String> lines = ExecutingCommand.runNative(command);
83+
for (String line : lines) {
84+
if (line.contains("LISTENING")) {
85+
// TCP 0.0.0.0:49168 0.0.0.0:0 LISTENING 476
86+
String[] strings = line.trim().split("\\s+");
87+
if (strings.length == 5) {
88+
if (strings[1].endsWith(":" + port)) {
89+
return Long.parseLong(strings[4]);
90+
}
91+
}
92+
}
93+
}
94+
return -1;
95+
}
6196

97+
private static long findTcpListenProcessOnUnix(int port) {
98+
String pid = ExecutingCommand.getFirstAnswer("lsof -t -s TCP:LISTEN -i TCP:" + port);
99+
if (pid != null && !pid.trim().isEmpty()) {
100+
try {
101+
return Long.parseLong(pid.trim());
102+
} catch (NumberFormatException e) {
103+
// ignore
104+
}
105+
}
62106
return -1;
63107
}
64108

0 commit comments

Comments
 (0)