2009-12-16 35 views
6

Tôi có một ứng dụng Windows rất lớn, phức tạp (triệu + LOC) được viết bằng C++. Chúng tôi nhận được một số báo cáo mỗi ngày rằng ứng dụng đã bị khóa và phải bị đóng cửa một cách mạnh mẽ.Phát hiện ứng dụng treo

Trong khi chúng tôi có báo cáo rộng rãi về sự cố tại chỗ, tôi muốn mở rộng điều này để bao gồm các trường hợp treo này - ngay cả khi đăng nhập nặng tại chỗ, chúng tôi không thể theo dõi nguyên nhân gốc của một số trường hợp này. Chúng tôi có thể thấy rõ hoạt động dừng ở đâu - nhưng không phải là lý do tại sao nó dừng lại, ngay cả khi đánh giá đầu ra của tất cả các chuỗi.

Sự cố xảy ra khi xảy ra sự cố xảy ra. Cho đến nay, tốt nhất tôi có thể đưa ra là một chuỗi watchdog (vì chúng tôi có bằng chứng rằng các chủ đề nền tiếp tục chạy các vấn đề w/out) định kỳ ping cửa sổ chính với một thông điệp tùy chỉnh, và xác nhận rằng nó được xử lý trong một thời trang kịp thời. Điều này sẽ chỉ nắm bắt thread GUI treo, nhưng điều này dường như là nơi mà phần lớn trong số họ đang xảy ra. Nếu không nhận được thư trả lời trong khung thời gian có thể định cấu hình, chúng tôi sẽ ghi lại bộ nhớ và ngăn xếp ngăn xếp và cung cấp cho người dùng tùy chọn tiếp tục chờ hoặc khởi động lại ứng dụng.

Có ai biết cách nào tốt hơn để thực hiện việc này so với việc bỏ phiếu định kỳ của cửa sổ chính theo cách này không? Có vẻ như vụng về đau đớn, nhưng tôi đã không thấy các lựa chọn thay thế sẽ hoạt động trên nền tảng của chúng tôi - Windows XP và Windows 2003 Server. Tôi thấy rằng Vista có nhiều công cụ tốt hơn cho điều này, nhưng tiếc là điều đó sẽ không giúp ích gì cho chúng tôi.

Đủ để nói rằng chúng tôi đã thực hiện chẩn đoán rộng rãi về điều này và đã được đáp ứng với thành công chỉ có giới hạn. Lưu ý rằng việc gắn windbg trong thời gian thực không phải là một tùy chọn, vì chúng tôi không nhận được báo cáo cho đến giờ hoặc ngày sau sự cố. Chúng tôi sẽ có thể truy xuất một tệp kết xuất bộ nhớ và tệp nhật ký, nhưng không có gì khác.

Bất kỳ đề xuất nào ngoài những gì tôi đang lên kế hoạch sẽ được đánh giá cao.

+0

Khi bị treo, tất cả các chuỗi có khóa không? Ứng dụng có tiếp tục tạo tệp nhật ký không? –

+0

Bạn có muốn chính ứng dụng phát hiện ra nó đã treo hoặc đang có một quá trình riêng biệt để giám sát ứng dụng một tùy chọn không? –

+0

Ứng dụng thực hiện - trong hầu hết các trường hợp - tiếp tục tạo ghi nhật ký trong các chủ đề khác ngoài cửa sổ chính. Trong một tỷ lệ rất thấp các trường hợp, có vẻ như tất cả các lần đăng nhập đều dừng lại trên các luồng. Chúng tôi đang tìm ứng dụng tự giám sát. –

Trả lời

2

Câu trả lời rất đơn giản: SendMessageTimeout!

Sử dụng API này, bạn có thể gửi tin nhắn đến cửa sổ và đợi thời gian chờ trước khi tiếp tục; nếu ứng dụng phản hồi trước khi hết thời gian chờ thì nó sẽ bị treo.

+0

Cảm ơn tôi đã không biết về điều này - điều đó sẽ hoạt động tốt với những gì tôi đã lên kế hoạch. –

1

Một gợi ý:

Giả sử rằng vấn đề là do khóa, bạn có thể đổ mutex bạn & bang semaphore từ một sợi cơ quan giám sát. Với một chút công việc (truy tìm biểu đồ cuộc gọi của bạn), bạn có thể xác định cách bạn đã đến bế tắc, đường dẫn cuộc gọi nào đang chặn lẫn nhau, v.v.

+0

Cảm ơn, đó là một gợi ý tốt cho sau khi chúng tôi đã phát hiện ra thực tế rằng chúng tôi đang bị khóa - nhưng tôi đang tìm kiếm đầu tiên để tìm một cách đáng tin cậy để làm điều đó. –

3

Một tùy chọn là chạy chương trình của bạn trong trình gỡ rối của riêng bạn "mọi lúc. Một số chương trình, chẳng hạn như GetRight, làm điều này để bảo vệ bản sao, nhưng bạn cũng có thể làm điều đó để phát hiện treo cứng. Về cơ bản, bạn bao gồm trong chương trình của bạn một số mã để đính kèm vào một quá trình thông qua API gỡ lỗi và sau đó sử dụng API đó để kiểm tra định kỳ treo cứng. Khi chương trình đầu tiên bắt đầu, nó sẽ kiểm tra nếu có một trình gỡ rối gắn với nó và, nếu không, nó sẽ chạy một bản sao khác của chính nó và gắn vào nó - vì vậy thể hiện đầu tiên không làm gì ngoài hành động của trình gỡ lỗi và thể hiện thứ hai là "thực " một. Làm thế nào bạn thực sự kiểm tra treo là một câu hỏi khác, nhưng có quyền truy cập vào API gỡ lỗi nên có một số cách để kiểm tra hợp lý hiệu quả cho dù stack đã thay đổi hay không (nghĩa là không tải tất cả các biểu tượng). Tuy nhiên, bạn có thể chỉ cần thực hiện việc này vài phút một lần, vì vậy ngay cả khi nó không hiệu quả thì cũng có thể được.

Đó là một giải pháp hơi khắc nghiệt, nhưng sẽ có hiệu quả. Nó cũng sẽ khá dễ dàng để bật và tắt hành vi này - một công tắc dòng lệnh sẽ thực hiện hoặC#define nếu bạn muốn. Tôi chắc chắn có một số mã ra khỏi đó mà những điều như thế này đã có, vì vậy bạn có thể không phải làm điều đó từ đầu.

+0

Cảm ơn, tôi sẽ xem xét điều này. Tôi lo ngại về chi phí liên quan. Ứng dụng này đã rất lớn và do tính chất chia sẻ của môi trường dịch vụ đầu cuối, chúng tôi đã đạt đến điểm mà việc thêm bất kỳ bộ nhớ hoặc chi phí CPU đáng kể nào có thể là vấn đề. –

0

Trong khi phân tích sự cố dường như cung cấp giải pháp để xác định sự cố, trong kinh nghiệm của tôi hiếm khi mang nhiều trái cây vì nó thiếu chi tiết rõ ràng về những gì đã xảy ra trước khi xảy ra sự cố. Ngay cả với công cụ bạn đề xuất, nó sẽ cung cấp ít hơn bằng chứng về những gì đã xảy ra. Tôi đặt cược nguyên nhân là dữ liệu được chia sẻ không được bảo vệ, do đó, một dấu vết khóa sẽ không hiển thị nó.

Cách hiệu quả nhất để tìm kiếm điều này — theo kinh nghiệm của tôi — là làm chệch hướng logic của ứng dụng về bản chất của nó và xác định nơi xảy ra xung đột. Có bao nhiêu chủ đề? Có bao nhiêu GUI? Các chủ đề tương tác với bao nhiêu điểm? Vâng, đây là kiểm tra bàn cũ tốt. Tương tác nghi ngờ hàng đầu có thể được xác định trong một hoặc hai ngày, sau đó chỉ thuyết phục một nhóm nhỏ những người hoài nghi rằng sự tương tác là chính xác.

+0

Đúng, và chúng tôi chắc chắn đã thử điều này (và tiếp tục thử điều này), nhưng cho đến nay chúng tôi đã không thể tái sản xuất điều này trong các hình thức ban đầu của nó hoặc trong một hình thức "tỉa". Ngay cả sau khi xác định tương tác nghi ngờ tiềm năng, chúng tôi vẫn không thể ép buộc kịch bản xảy ra. Tôi không nghĩ rằng bãi chứa sẽ là viên đạn ma thuật, mà là một vũ khí mạnh mẽ khác trong kho vũ khí-- có dấu vết ngăn xếp có thể mang lại nhiều thông tin ngay cả khi không có bất kỳ dữ liệu nào khác. –

+0

Tôi không có ý định tạo mã chưng cất runnable. Tôi có nghĩa là chưng cất mã để lõi chức năng và tương tác của nó, giống như trên một mảnh giấy hoặc bảng trắng: 'task1: khởi tạo; vòng lặp; wait_for_signal; perform_listbox_update; cho đến khi (chấm dứt), ' – wallyk

+0

Chúng tôi cũng đã tiếp cận từ góc đó. Rất nhiều vấn đề là có nhiều con đường khác nhau dường như sẽ dẫn đến điều này - vì vậy chúng ta không phải đối mặt với một nguyên nhân gốc rễ. –

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