2010-11-22 32 views
5

Tôi có ứng dụng Visual C++ 9 Win32 sử dụng thư viện của bên thứ ba. Khi một hàm từ thư viện đó được gọi với một tập hợp các thông số nhất định, chương trình sẽ gặp sự cố với "mã ngoại lệ 0xC000000D".Chương trình bị lỗi với 0xC000000D và không có ngoại lệ - làm cách nào để gỡ lỗi chương trình?

Tôi đã cố gắng đính kèm trình gỡ lỗi Visual Studio - không có ngoại lệ nào được ném (không phải C++ cũng như cấu trúc như vi phạm truy cập) và terminate() không được gọi. Tuy nhiên chương trình chỉ kết thúc âm thầm.

Chương trình chỉ kết thúc bất thường như thế nào nhưng không dừng lại trong trình gỡ rối? Làm thế nào tôi có thể bản địa hóa vấn đề?

+0

là đa luồng hoặc đơn luồng? – Simone

+0

@Simone: Một chuỗi công nhân, một số chuỗi dịch vụ được sinh ra bởi RPC. Chúng tôi đã thử nghiệm đồng bộ hóa kỹ lưỡng, đa luồng có thể không phải là vấn đề. – sharptooth

+0

Bạn có đang chạy phiên bản phát hành hoặc phiên bản gỡ lỗi không? Tôi đã nhìn thấy các trường hợp lạ của các phiên bản phát hành không dừng lại trong trình gỡ lỗi. –

Trả lời

5

Đó là STATUS_INVALID_PARAMETER, sử dụng WinDbg để theo dõi người ném nó (ví dụ: đính kèm WinDbg, sxe eh rồi g.

+1

OP đã nói rằng "đính kèm VS debugger - không có ngoại lệ được ném" ... làm thế nào WinDbg sẽ thay đổi hình ảnh? –

+0

Tìm kiếm xung quanh dường như chỉ ra rằng có các chức năng mà ném điều này - nhưng cũng có các hàm sử dụng STATUS_INVALID_PARAMETER làm giá trị trả lại. Vì vậy, có lẽ không có gì được ném sau khi tất cả ... –

+0

@Martin VS sẽ ẩn một số loại ngoại lệ mà nó không biết cách xử lý (hiếm khi). Sử dụng quy tắc WinDbg 100% trong bất kỳ loại ngoại lệ nào. –

1

Nếu bạn không có thông tin về nguồn và gỡ lỗi cho thư viện của bên thứ ba, bạn sẽ không thể bước vào đó bằng trình gỡ rối. Như tôi thấy, lựa chọn của bạn là;

  • Đặt cùng một trường hợp thử nghiệm đơn giản minh họa vụ tai nạn và gửi nó vào các nhà phát triển thư viện
  • Bọc rằng chức năng thư viện trong mã của riêng bạn để kiểm tra các thông số bất hợp pháp và ném một ngoại lệ/trả lại mã lỗi khi họ đang có thông qua ứng dụng của riêng bạn
  • Viết lại các bộ phận của thư viện mà không có tác dụng hoặc sử dụng một sự thay thế

Rất khó khăn để sửa chữa mã được cung cấp như là duy nhất đối tượng

Sửa Bạn cũng có thể có thể kết thúc tốt đẹp hơn bằng cách sử __try __finally xung quanh vòng lặp thông điệp chính của bạn, một cái gì đó giống như

int CMyApp::Run() 
{ 
    __try 
    { 
     int i = CWinApp::Run(); 
     m_Exitok = MAGIC_EXIT_NO; 
     return i; 
    } 
    __finally 
    { 
     if (m_Exitok != MAGIC_EXIT_NO) 
      FaultHandler(); 
    } 
} 
+1

Tất nhiên bạn có thể bước vào nó bằng cách sử dụng trình gỡ lỗi. –

+0

@Paul, chắc chắn, nhưng chỉ trong lắp ráp mà không có PDB. Với PDB nhưng không có nguồn, bạn sẽ có được chú thích assmebler độc đáo với các nhãn từ nguồn. IMO, đây là những hiếm khi có giá trị gỡ lỗi tay, như là một sửa chữa phải được thực hiện trong lắp ráp đó là có được thời gian và gây ra một cơn ác mộng bảo trì trong tương lai. –

+0

Tôi không nghĩ rằng vấn đề của OP là bước vào mã mà đúng hơn là nắm bắt được ngoại lệ, điều mà anh ta nói không xảy ra. –

2

Câu trả lời và nhận xét khác cho câu hỏi đã giúp ích rất nhiều. Đây là những gì tôi đã làm.

Tôi nhận thấy rằng nếu tôi chạy chương trình trong trình gỡ lỗi Visual Studio, nó sẽ kết thúc âm thầm, nhưng nếu tôi chạy nó mà không có trình gỡ rối, nó sẽ đổ vỡ với hộp thư (hộp thông báo Windows thông thường nói rằng tôi mất dữ liệu chưa được lưu và mọi người đều sooo lấy làm tiếc).

Vì vậy, tôi đã bắt đầu chương trình gỡ lỗi wihtout, để cho nó sụp đổ và sau đó - trong khi hộp thư vẫn ở đó - đính kèm trình gỡ rối và nhấn "Break". Đây là ngăn xếp cuộc gọi:

[email protected]() 
[email protected]() + 0xc bytes 
[email protected]() - 0x48 bytes 
[email protected]() + 0x18 bytes 
faultrep.dll!StartDWException() + 0x5df bytes 
faultrep.dll!ReportFault() + 0x533 bytes 
[email protected]() + 0x55c bytes 
//SomeThirdPartyLibraryFunctionAddress 
//SomeThirdPartyLibraryFunctionAddress 
//SomeThirdPartyLibraryFunctionAddress 
//SomeThirdPartyLibraryFunctionAddress 
//OurCodeInvokingThirdPartyLibraryCode 

vì vậy rõ ràng đó là một số vấn đề bên trong thư viện bên thứ ba. Theo MSDN, UnhandledExceptionFilter() được gọi trong các tình huống chết người và rõ ràng cuộc gọi được thực hiện vì một số vấn đề trong mã thư viện. Vì vậy, chúng tôi sẽ cố gắng giải quyết vấn đề với nhà cung cấp thư viện trước.

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