2011-08-30 24 views
15

Ứng dụng Java của tôi đã bắt đầu gặp sự cố thường xuyên với SIGSEGV và một đống dữ liệu ngăn xếp và tải thông tin trong một tệp văn bản.Làm cách nào để gỡ lỗi các Segfaults xảy ra trong JVM khi nó chạy mã của tôi?

Tôi đã gỡ lỗi chương trình C trong gdb và tôi đã gỡ lỗi mã Java từ IDE của mình. Tôi không chắc chắn làm thế nào để tiếp cận C-như tai nạn trong một chương trình Java đang chạy.

Tôi giả sử tôi không xem xét lỗi JVM tại đây. Các chương trình Java khác chạy tốt, và JVM từ Sun có lẽ ổn định hơn mã của tôi. Tuy nhiên, tôi không có ý tưởng làm thế nào tôi thậm chí có thể gây ra segfaults với mã Java. Có chắc chắn là đủ bộ nhớ có sẵn, và khi tôi cuối cùng kiểm tra trong hồ sơ, sử dụng đống là khoảng 50% với đột biến thường xuyên khoảng 80%. Có bất kỳ thông số khởi động nào tôi có thể điều tra không? Danh sách kiểm tra tốt khi tiếp cận một lỗi như thế này là gì?

Mặc dù tôi không thể tái tạo lại sự kiện một cách đáng tin cậy, nhưng nó dường như không xảy ra hoàn toàn ngẫu nhiên, vì vậy việc kiểm tra không hoàn toàn là không thể.

ETA:. Một số các chi tiết đẫm máu

(Tôi đang tìm kiếm một cách tiếp cận chung, kể từ khi vấn đề thực tế có thể là rất cụ thể Tuy nhiên, có một số thông tin tôi đã thu thập và mà bạn có thể Một số giá trị.)

Cách đây không lâu, tôi gặp sự cố tương tự sau khi nâng cấp máy chủ CI (xem here để biết thêm chi tiết), nhưng khắc phục (thiết lập -XX:MaxPermSize) không giúp được. Điều tra sâu hơn cho thấy rằng trong các tệp nhật ký sự cố, chuỗi được đánh dấu là "chuỗi hiện tại" không bao giờ là một trong số của tôi, nhưng một trong hai được gọi là "VMThread" hoặc được gọi là "GCTaskThread" - tôi e nó là thứ hai. được đánh dấu bằng chú thích "(đã thoát)", nếu nó cũ, GCTaskThread không có trong danh sách. Điều này làm cho tôi giả sử rằng vấn đề có thể xảy ra ở phần cuối của một phép toán GC.

+0

Bạn có thể nhận theo dõi ngăn xếp không? Có phải SEGV ở cùng một nơi không? Chúng ta có thể có thêm thông tin để làm việc không? –

+0

Có bất kỳ mã gốc nào trong ứng dụng của bạn không? Nếu JVM cho phép bất kỳ bộ sưu tập bytecode nào, cho dù bytecode có lỗi đến mức nào, để kích hoạt một segfault, thì _ipso facto_ your're đang tìm kiếm một lỗi JVM (hoặc JRE). –

+0

@Ed - Tôi có rất nhiều dấu vết ngăn xếp, nhưng đó là một bức tường lớn của văn bản. Phần nào sẽ hữu ích nhất để đăng? Tôi chủ yếu tìm kiếm một cách chung để tiếp cận loại vấn đề này, do đó tôi do dự để đổ một tải thông tin rất cụ thể ở đây. –

Trả lời

22

Tôi giả sử tôi không xem xét lỗi JVM tại đây. Các chương trình Java khác chạy tốt, và JVM từ Sun có lẽ ổn định hơn mã số của tôi.

Tôi không nghĩ bạn nên giả định điều đó. Nếu không sử dụng JNI, bạn sẽ không thể viết mã Java gây ra SIGSEGV (mặc dù chúng tôi biết điều đó xảy ra). Quan điểm của tôi là, khi nó xảy ra, nó là một lỗi trong JVM (không phải là chưa từng nghe) hoặc một lỗi trong một số mã JNI. Nếu bạn không có bất kỳ JNI nào trong mã của riêng bạn, điều đó không có nghĩa là bạn không sử dụng một số thư viện, vì vậy hãy tìm kiếm nó. Khi tôi đã nhìn thấy loại vấn đề này trước đây, nó đã ở trong một thư viện thao tác hình ảnh. Nếu thủ phạm không có trong mã JNI của riêng bạn, có thể bạn sẽ không thể 'khắc phục' lỗi này, nhưng bạn vẫn có thể làm việc xung quanh nó.

Trước tiên, bạn sẽ nhận được một JVM thay thế trên cùng một nền tảng và cố gắng tạo lại nó. Bạn có thể thử one of these alternatives.

Nếu bạn không thể tạo lại, có thể đó là lỗi JVM. Từ đó, bạn có thể ủy thác một JVM cụ thể hoặc search the bug database, bằng cách sử dụng những gì bạn biết về cách tạo lại nó và có thể nhận được các giải pháp được đề xuất. (Ngay cả khi bạn có thể tái tạo nó, nhiều triển khai JVM chỉ là các chỉnh sửa trên triển khai Hotspot của Oracle, vì vậy nó vẫn có thể là lỗi JVM.)

Nếu bạn có thể tái tạo nó với một JVM thay thế, lỗi có thể là bạn có một số lỗi JNI. Hãy xem bạn đang sử dụng thư viện nào và họ có thể đang thực hiện những cuộc gọi nào. Đôi khi có các cấu hình "thuần Java" thay thế hoặc các tệp jar cho cùng một thư viện hoặc các thư viện thay thế gần như giống nhau.

Chúc may mắn!

+4

+1 cho "bạn có thể sẽ không thể 'khắc phục' lỗi này": vì vậy câu trả lời cho câu hỏi của người đăng "Làm thế nào để tôi gỡ lỗi Segfaults xảy ra trong JVM khi nó chạy mã của tôi?" là "* bạn * không". – Raedwald

9

Sau đây hầu như chắc chắn sẽ vô dụng trừ khi bạn có mã gốc. Tuy nhiên, ở đây đi.

  1. Bắt đầu chương trình java trong trình gỡ lỗi java, với điểm ngắt tốt trước khi có thể sigsegv.
  2. Sử dụng lệnh ps để lấy processid của java.
  3. gdb/usr/lib/jvm/CN-java6/bin/java ProcessID
  4. chắc chắn rằng gdb 'xử lý' lệnh được thiết lập để ngăn chặn trên SIGSEGV
  5. tiếp tục trong trình gỡ lỗi java từ breakpoint.
  6. chờ phát nổ.
  7. Sử dụng gdb để điều tra

Nếu bạn đã thực sự cố gắng làm cho JVM mất một SIGSEGV mà không cần bất kỳ mã nguồn gốc của riêng bạn, bạn đang rất khó có thể thực hiện bất kỳ ý nghĩa của những gì bạn sẽ thấy tiếp theo, và tốt nhất bạn có thể làm là đẩy một trường hợp thử nghiệm lên một báo cáo lỗi.

+1

Điều đó có yêu cầu phiên bản đặc biệt của JVM không? Từ C, tôi đã từng phải biên dịch lại với các biểu tượng gỡ lỗi khi tôi muốn sử dụng gdb. –

+0

JVM trong kinh nghiệm của tôi luôn có đủ ký hiệu cho backtraces. Nếu bạn thực sự có ý định gỡ lỗi chi tiết, tốt, tắt để openJDK và một bản dựng gỡ lỗi. – bmargulies

2

Tôi đã tìm thấy danh sách tốt tại http://www.oracle.com/technetwork/java/javase/crashes-137240.html. Khi tôi nhận được các sự cố trong GC, tôi sẽ thử chuyển đổi giữa các bộ thu gom rác.

Tôi đã thử chuyển đổi giữa nối tiếp và song song GC (sau này là mặc định trên máy chủ Linux 64 bit), điều này chỉ thay đổi thông báo lỗi tương ứng.

Giảm kích thước heap tối đa từ 16G xuống 10G sau khi phân tích mới trong profiler (đã cho tôi sử dụng vùng hất ra ở 8G) đã dẫn đến dấu chân "Bộ nhớ ảo" thấp hơn đáng kể (16G thay vì 60), nhưng tôi thậm chí không biết điều đó có nghĩa là gì, và Internet nói, điều đó không quan trọng.

Hiện tại, JVM đang chạy ở chế độ khách hàng (sử dụng tùy chọn khởi động -client do đó ghi đè mặc định là -server). Cho đến nay, không có sự cố, nhưng tác động hiệu suất có vẻ khá lớn.

0

Hãy thử kiểm tra xem chương trình c của ô tô nào đã gây ra sự cố java.use valgrind để biết kích thước ngăn xếp không hợp lệ cũng như kiểm tra chéo.

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