2012-01-15 24 views
11

Trong vài tháng qua, tôi đã nhận được một vài báo cáo từ QA về một trong các dịch vụ của chúng tôi bị treo. Sau khi kiểm tra một bãi chứa hang bằng cách sử dụng WinDbg, mỗi khi tôi phát hiện ra cùng một điều: Loader khóa phần quan trọng bị khóa nhưng sở hữu thread là hư không được tìm thấy. Kể từ khi thread đã biến mất và dấu vết duy nhất mà tôi có thể thấy là một phần quan trọng toàn cầu nó để lại phía sau, tôi không thấy mã chạy trên chuỗi chủ đề, hoặc thậm chí những gì mà chuỗi đó đến từ, nó có thể thậm chí không phải là một trong của chúng tôi (tức là nhà cung cấp bên thứ ba).Tìm kiếm ý tưởng gỡ lỗi một cửa sổ dịch vụ khởi động khó khăn gremlin

Vấn đề này rất lẻ tẻ, chỉ nhìn thấy nó có thể 3-4 lần trong 6 tháng qua xảy ra tự nhiên trong tự nhiên. Tất cả các lần khác, dịch vụ chạy hoàn hảo. Vì vậy, điều này làm cho tôi tin rằng đó là một số loại điều kiện thời gian/chủng tộc.

Gần đây, tôi đã quyết định tự mình thực hiện điều này. Tôi thiết lập một máy tính với kịch bản WinTask liên tục bắt đầu/dừng dịch vụ nói trên. Tin tốt là trong vòng 5-6 giờ tôi có thể tái tạo vấn đề.

Bây giờ cho phần tiếp theo: làm cách nào để cô lập?

Đây là những gì tôi đã cố gắng cho đến nay:

  1. sử dụng "gỡ rối" lĩnh vực trong cài đặt gflags ảnh để Automagically chạy dịch vụ dưới cdb bất cứ khi nào nó bắt đầu. Cho đến nay điều này đã được chạy trong hai ngày và không bao giờ treo, vì vậy tôi đang suy nghĩ gỡ lỗi giới thiệu vừa đủ của một sự thay đổi thời gian để làm cho vấn đề vô hình.

  2. Trình xác minh ứng dụng đã tải xuống và định cấu hình quy trình để chạy với điều đó. Tìm thấy một lỗi hoàn toàn không liên quan nơi chúng tôi tạo biến tạm thời CComBSTR, gán nó cho biến thể và chuyển biến thể vào một cuộc gọi hàm mặc dù CComBSTR đã xóa chuỗi được phân bổ theo điểm đó. Đừng tin rằng lỗi này là có liên quan bởi vì chuỗi là chỉ đọc và thread nó đang chạy trên không phải là một trong đó là chết.

Tôi đang tạo bài đăng này trong trường hợp các bạn có thể nghĩ về điều gì đó mà tôi không xem xét.

Tôi mặc dù có một cửa sổ tiện ích mà giả tạo đặt tải trên CPU và làm những việc khác để làm cho điều kiện chủng tộc bật lên và tôi nghĩ rằng ứng dụng xác minh đã làm một điều như vậy, nhưng dường như nó không. Có ai biết tôi đang làm gì không, hay tôi chỉ mơ ước điều đó?

Trừ khi điều gì đó xảy ra vào cuối tuần, bước tiếp theo của tôi là vô hiệu hóa tất cả các trình gỡ rối, quay lại kho và hack một trong những DllMains để ghi lại các sự kiện THREAD_ATTACH/THREAD_DETACH. Ít nhất tôi sẽ có thể chặn sợi chỉ đang chết khi nó được tạo ra. Điều đó có thể làm sáng tỏ.

+1

-1 ?? tại sao?? tôi không hiển thị đủ chi tiết? có vẻ như tôi không làm đủ nghiên cứu? làm mọi người không hỏi stackoverflow khi họ nhận được stumped bởi các vấn đề phát triển phần mềm? – DXM

+0

Vâng, đây là một câu hỏi hoàn toàn hợp lệ. Điều duy nhất sẽ làm cho nó tốt hơn sẽ được đăng một số mã. Tôi cho rằng đó là lý do tại sao một người nào đó lái xe bằng cách bỏ phiếu. –

+2

Đó là một ứng dụng sản xuất đã có mặt trên thị trường hơn 10 năm. Tôi thậm chí không biết những gì DLL đang gây ra vấn đề, hãy để một mình gửi mã nguồn công ty mã nguồn mở trực tuyến, ngay cả khi tôi có thể sao chép/dán 5M dòng mã nguồn. Không có ý tưởng gì thay đổi, nhưng lần đầu tiên tôi nhìn thấy vấn đề khoảng 6 tháng trước đây. – DXM

Trả lời

2

Điều tôi có thể thử đang đính kèm trình gỡ lỗi hạt nhân, sau đó chạy quy trình trong Trình xác minh ứng dụng. AV có kiểm tra để dỡ bỏ một DLL trong khi nó giữ một CS và chấm dứt chủ đề mà vẫn giữ CS. Vì vậy, những điểm ngắt nên kích hoạt trong trình gỡ lỗi hạt nhân và sau đó hy vọng bạn có thể bắt nó trong hành động. Chạy nó theo KD hy vọng sẽ không làm chậm nó giống như trình gỡ lỗi chế độ người dùng.

+0

kernel trình gỡ rối ... thú vị. Đó là một lĩnh vực mà tôi chưa bao giờ mạo hiểm. Có thể là một tùy chọn nếu mọi thứ khác không thành công. Bằng cách này tôi có thể có trình gỡ lỗi chạy và giám sát mọi thứ trong khi dịch vụ bắt đầu và dừng lại. Tôi sẽ cần một máy thứ hai cho việc này, phải không? Tôi cũng cần một cáp nối tiếp hoặc họ có phương tiện khác những ngày này? – DXM

+0

cách dễ nhất là trong một máy ảo, và sau đó VM xuất cổng COM như một đường ống được đặt tên mà windbg biết cách kết nối tới. – jcopenha

+0

Tôi đang cố gắng không thở trên chiếc máy này nhiều hơn tôi phải làm. VM có thể sợ lỗi này giống như cdb đã làm. Vì vậy, giả sử tôi để nó ở đâu, cáp nối tiếp, phải không? – DXM

0

Một số ý tưởng ngẫu nhiên: Nếu đính kèm một trình gỡ rối không giúp ích, thì thiết bị đo đạc (điểm cuối cùng của bạn) là bước tiếp theo. Nhưng làm thế nào một sợi chỉ có thể chết mà không làm giảm toàn bộ quá trình, bạn có bắt được ngoại lệ ở đâu đó không? Bạn có thể muốn đăng nhập ở đó. Bạn cũng có thể thiết lập WinDbg để phá vỡ tất cả các trường hợp ngoại lệ đầu tiên, nếu điều đó có ích. Cửa sổ đầu ra WinDbg sẽ hiển thị ngoại lệ cơ hội đầu tiên dù cho bạn không phá vỡ.

+0

nó chỉ xảy ra khi khởi động và rất không thường xuyên vì vậy tôi không thể có windbg kèm theo. Nhưng đây là chính xác những gì tôi đang cố gắng để đạt được với cdb, đó là một phiên bản giao diện điều khiển của cùng một công cụ gỡ lỗi. Chúng tôi chắc chắn đã đăng nhập vào chủ đề chúng tôi kiểm soát, nhưng tôi biết các API/DLL khác bắt đầu chủ đề của riêng mình và tôi không biết những gì đang làm. Nội dung thú vị. – DXM

0

Tôi sẽ thử một trình gỡ lỗi không xâm lấn, và xem nó như thế nào, trong khi bạn sẽ không thể dừng quá trình, bạn sẽ có thể thấy bất kỳ thông báo gỡ lỗi nào cũng như bất kỳ chủ đề nào bắt đầu và dừng, và nó sẽ có tác động tối thiểu đến hiệu suất quy trình. Tôi thường sử dụng windbg cho gỡ lỗi của tôi, nhưng tôi nghĩ rằng cbd có các tùy chọn tương tự như là tốt. Điều này rất có thể sẽ cho phép bạn xem những gì đang xảy ra trong quá trình này và ít nhất là bắt đầu giúp thu hẹp nó xuống. Một điều bạn có thể muốn đảm bảo làm là chuyển hướng đầu ra (.logopen trong windbg) để đảm bảo rằng không có gì nằm ngoài bộ đệm của bạn.

+0

ý của bạn là gì bởi trình gỡ lỗi không xâm lấn? WinDbg và cdb về bản chất là cùng một trình gỡ lỗi. WinDbg có giao diện người dùng, cdb là giao diện điều khiển, nhưng trong tất cả các khía cạnh khác, chúng giống hệt nhau. Tôi đã có dịch vụ của tôi bắt đầu theo cdb mà đã mở một cổng tcp vì vậy tôi có thể sử dụng windbg để kết nối với nó sau này. Ngoài ra, như bạn đã đề cập, tôi đã sử dụng .logopen để đảm bảo mọi thứ cdb thấy, tôi cũng có thể xem qua tệp nhật ký. – DXM

+0

sử dụng lệnh -pv cho cdb để đính kèm không xâm lấn. Bạn sẽ không thể dừng chủ đề hoặc thực hiện bất kỳ hành động thực nào, nhưng bạn sẽ có thể xem thêm thông tin chẩn đoán và hy vọng không gây ra bất kỳ vấn đề hiệu suất nào ngăn sự cố xảy ra. Đây là liên kết về gỡ lỗi không xâm lấn http://msdn.microsoft.com/en-us/library/ff552274(v=vs.85).aspx – Zipper

1

Vì vậy, hóa ra tôi đã gần với giải pháp hơn là tôi nhận ra. Với dịch vụ chạy dưới cdb, thay đổi thời gian và sau đó chạy nó với trình kiểm tra ứng dụng, điều này làm thay đổi thời gian thậm chí còn nhiều hơn (trang heap cho phép phân bổ chậm hơn), thành phần bí mật mà tôi đã mất là prime95.exe. Chạy prime95.exe ở mức ưu tiên bình thường ở trên, thực sự làm hỏng bất kỳ thời điểm nào tôi cố gắng không thay đổi, nhưng nó đã làm cho vấn đề hiển thị trong chưa đầy 15 phút.

Nguyên nhân:

SDK bên thứ ba để lấy dữ liệu từ bảng phần cứng. Khi dịch vụ của chúng tôi khởi động, chúng tôi sẽ truy vấn các thành phần chụp khác nhau cho khả năng của chúng. Sau khi truy vấn được thực hiện, chúng tôi phát hành cá thể thành phần. Dường như một DLL này đã bắt đầu một luồng riêng biệt, mà nó có được một khóa bộ nạp và sau đó tiến hành thực hiện một loạt các khởi tạo trong chuỗi đó. Nếu trong thời gian đó, truy vấn khả năng của chúng tôi đã được thực hiện và chúng tôi đã phát hành thành phần, mã của họ sẽ gọi TerminateThread() trên chuỗi khác này để khóa trình khóa bị khóa vĩnh viễn. Prime95 chậm lại tất cả mọi thứ xuống chỉ đủ cho tôi để đón tình trạng chủng tộc này và nhận được thông báo sau xác minh stop:

======================================= 
VERIFIER STOP 00000200: pid 0x1A8C: Thread cannot own a critical section. 

0000091C : Thread ID. 
77E17340 : Critical section address. 
00000000 : Critical section debug information address. 
00000000 : Critical section initialization stack trace. 

phần vui là chủ đề này đã "biến mất" không có bất kỳ ngoại lệ dưới mọi hình thức, vì vậy sẽ không debugger thậm chí nắm bắt cơ hội đầu tiên. Ai sử dụng TerminateThread ????

Cảm ơn mọi người đã đề xuất và hỗ trợ. Tôi đã thực sự bắt đầu mong muốn lái xe đến Radioshack trong bữa trưa để mua một cáp nối tiếp và sau đó dành một vài ngày chơi với KD. Có vẻ như điều đó sẽ phải đợi đến lần sau :)

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