2013-05-08 24 views
7

Trong khi điều tra lỗi này JDK trên Mac OS, tôi chạy vào hệ thống gọi dấu vết đầu ra tôi không hiểu:Tại sao lệnh không hiển thị cho tôi cuộc gọi hệ thống được chọn trong mã JNI này?

Tomcat startup fails due to 'java.net.SocketException Invalid argument' on Mac OS X

Phiên bản ngắn: Trên Mac OS, JDK sử dụng select() thay vì poll(). Vì vậy, nếu có hơn 1024 mô tả tệp được phân bổ, chúng tôi đã suy ra rằng lệnh gọi select() trong NET_Timeout không dẫn đến một SocketException với thông báo 'Đối số không hợp lệ'. Tuy nhiên, khi tôi truy tìm các cuộc gọi hệ thống, tôi thấy không có bằng chứng về cuộc gọi hệ thống select() hoặc bất kỳ cuộc gọi nào không thành công và đặt EINVAL, vì vậy tôi đã giảm giá đó là nguyên nhân tiềm năng.

Tôi cũng không thấy cuộc gọi với các trường hợp thử nghiệm giảm tôi đã tạo ra bây giờ tôi hiểu được vấn đề:

import java.io.*; 
import java.net.*; 

public class SelectTest { 
    public static void main(String[] args) throws Exception { 
    for(int i = 0; i < 1024; i++) { 
     new FileInputStream("/dev/null"); 
    } 
    ServerSocket socket = new ServerSocket(8080); 
    socket.accept(); 
    } 
} 

Kết quả trong ngoại lệ này trên Mac OS w/JDK 1.7u5 và sau:

Exception in thread "main" java.net.SocketException: Invalid argument 
    at java.net.PlainSocketImpl.socketAccept(Native Method) 
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398) 
    at java.net.ServerSocket.implAccept(ServerSocket.java:522) 
    at java.net.ServerSocket.accept(ServerSocket.java:490) 
    at SelectTest.main(SelectTest.java:12) 

Tại sao tôi không thấy bất kỳ bằng chứng nào về cuộc gọi select() (hoặc bất kỳ lỗi nào khác) khi tôi chạy thử nghiệm bằng cách sử dụng sudo dtruss -a java SelectTest?

 PID/THRD RELATIVE ELAPSD CPU SYSCALL(args)     = return 
45563/0x63a513:  85544  6  4 bind(0x412, 0x10DFC7738, 0x1C)   = 0 0 
45563/0x63a513:  85605  6  3 listen(0x412, 0x32, 0x32)    = 0 0 
45563/0x63a513:  85619  2  0 lseek(0x4, 0x37377AD, 0x0)    = 57898925 0 
45563/0x63a513:  85622  4  2 read(0x4, "PK\003\004\n\0", 0x1E)    = 30 0 
45563/0x63a513:  85622  1  0 lseek(0x4, 0x37377E0, 0x0)    = 57898976 0 
45563/0x63a513:  85627  5  4 read(0x4, "\312\376\272\276\0", 0x3447)     = 13383 0 
45563/0x63a513:  86150  37  33 write(0x2, "Exception in thread \"main\" ble\001\0", 0x1B)    = 27 0 

Trả lời

0

Tôi mong đợi ServerSocket.accept để gọi chính xác những gì bạn đã thấy.

Các ổ cắm Berkeley cuộc gọi tương ứng với Java acceptlisten()accept()

Đáng tiếc là tôi không thể tái tạo các ngoại lệ trên Linux. Nếu tôi sử dụng tất cả các của fd trước new ServerSocket(8080) tôi nhận được:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libnet.so: /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libnet.so: cannot open shared object file: Too many open files 
    at java.lang.ClassLoader$NativeLibrary.load(Native Method) 
    at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1939) 
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1864) 
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1846) 
    at java.lang.Runtime.loadLibrary0(Runtime.java:845) 
    at java.lang.System.loadLibrary(System.java:1084) 
    at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:67) 
    at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:47) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.AbstractPlainSocketImpl.<clinit>(AbstractPlainSocketImpl.java:80) 
    at java.net.ServerSocket.setImpl(ServerSocket.java:289) 
    at java.net.ServerSocket.<init>(ServerSocket.java:230) 
    at java.net.ServerSocket.<init>(ServerSocket.java:128) 
    at SelectTest.main(SelectTest.java:15) 
+0

Trong trường hợp này vấn đề không được đánh giới hạn cd, nó sử dụng nhiều hơn 1024 với chọn cuộc gọi, mà là trong xử lý mã cho Darwin timeout mạng (bsd_close.c). Xem câu hỏi được liên kết để biết chi tiết - đó là Darwin cụ thể. –

Các vấn đề liên quan