Cách xử lý AccessViolationException


183

Tôi đang sử dụng một đối tượng COM (MODI) từ trong ứng dụng .net của mình. Phương thức tôi đang gọi ném System.AccessViolationException, bị Visual Studio chặn lại. Điều kỳ lạ là tôi đã thực hiện cuộc gọi của mình trong một lần thử, có trình xử lý cho AccessViolationException, COMException và mọi thứ khác, nhưng khi Visual Studio (2010) chặn AccessViolationException, trình gỡ lỗi sẽ phá vỡ lệnh gọi phương thức (doc.OCR), và nếu tôi bước qua, nó sẽ tiếp tục đến dòng tiếp theo thay vì vào khối bắt. Ngoài ra, nếu tôi chạy cái này bên ngoài phòng thu trực quan thì ứng dụng của tôi gặp sự cố. Làm cách nào tôi có thể xử lý ngoại lệ này được ném trong đối tượng COM?

MODI.Document doc = new MODI.Document();
try
{
    doc.Create(sFileName);
    try
    {
        doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, false, false);
        sText = doc.Images[0].Layout.Text;
    }
    catch (System.AccessViolationException ex)
    {
        //MODI seems to get access violations for some reason, but is still able to return the OCR text.
        sText = doc.Images[0].Layout.Text;
    }
    catch (System.Runtime.InteropServices.COMException ex)
    {
        //if no text exists, the engine throws an exception.
        sText = "";
    }
    catch
    {
        sText = "";
    }

    if (sText != null)
    {
        sText = sText.Trim();
    }
}
finally
{
    doc.Close(false);

    //Cleanup routine, this is how we are able to delete files used by MODI.
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(doc);
    doc = null;
    GC.WaitForPendingFinalizers();
    GC.Collect();
    GC.WaitForPendingFinalizers();

}

Bạn đã thử đặt một Exceptiontrình xử lý (tạm thời!) Để bẫy tất cả các ngoại lệ và xem ngoại lệ thực sự là gì?
ChrisF

3
@ChrisF - vâng, xem xử lý bắt cuối cùng? Điều đó sẽ nắm bắt mọi thứ, bao gồm Ngoại lệ và bất kỳ phân lớp Ngoại lệ nào. Đồng thời, Visual studio báo cáo rằng ngoại lệ là System.AccessViolationException
Jeremy

Câu trả lời:


298

Trong .NET 4.0, bộ thực thi xử lý các trường hợp ngoại lệ nhất định được nêu là lỗi Xử lý lỗi cấu trúc Windows (SEH) dưới dạng các chỉ báo của Trạng thái bị hỏng. Các ngoại lệ trạng thái bị hỏng (CSE) này không được phép bắt bởi mã được quản lý tiêu chuẩn của bạn. Tôi sẽ không hiểu tại sao hay tại sao. Đọc bài viết này về CSE trong .NET 4.0 Framework:

http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035

Nhưng có hy vọng. Có một vài cách để khắc phục điều này:

  1. Biên dịch lại dưới dạng lắp ráp .NET 3.5 và chạy nó trong .NET 4.0.

  2. Thêm một dòng vào tệp cấu hình của ứng dụng của bạn trong phần tử cấu hình / thời gian chạy: <legacyCorruptedStateExceptionsPolicy enabled="true|false"/>

  3. Trang trí các phương thức bạn muốn nắm bắt các ngoại lệ này bằng HandleProcessCorruptedStateExceptionsthuộc tính. Xem http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035 để biết chi tiết.


BIÊN TẬP

Trước đây, tôi đã tham khảo một bài đăng trên diễn đàn để biết thêm chi tiết. Nhưng vì Microsoft Connect đã ngừng hoạt động, đây là các chi tiết bổ sung trong trường hợp bạn quan tâm:

Từ Gaurav Khanna, một nhà phát triển từ Nhóm CLR của Microsoft

Hành vi này là do thiết kế do một tính năng của CLR 4.0 có tên Corrupted State Exceptions. Nói một cách đơn giản, mã được quản lý không nên cố gắng bắt các ngoại lệ chỉ ra trạng thái quá trình bị hỏng và AV là một trong số đó.

Sau đó, anh tiếp tục tham khảo tài liệu về HandProcessCorruptedStateExceptionsAttribution và bài viết trên. Có thể nói, nó chắc chắn đáng để đọc nếu bạn đang xem xét nắm bắt các loại ngoại lệ này.


10
HandleProcessCorruptedStateExceptionslàm việc cho tôi trong .Net 4.5.
Deerchao

2
Cảm ơn Villecoder, bạn là một viên ngọc quý! Tôi đã giải quyết vấn đề này trong nhiều tuần, cố gắng giải quyết vấn đề gốc rễ và cuối cùng đã cam chịu điều trị triệu chứng này. Giải pháp của bạn là hoàn hảo.
gadildafissh

19
! Cần lưu ý: rất khuyến khích kết thúc quá trình sau AccessViolationException là Ngoại lệ trạng thái bị hỏng (CSE). Nếu không, nó có thể dẫn đến các lỗi nghiêm trọng hơn.
Zbigniew Wiadro

6
Cảm ơn, điều này thực sự hữu ích, mặc dù lúc đầu tôi có ấn tượng rằng tôi cần phải thực hiện cả 3 bước để có thể nắm bắt được các ngoại lệ này, trong khi đó thực sự là "logic OR" trong các cách thực hiện. :)
Lou

@deerchao Tôi hy vọng bạn đã đọc liên kết đầu tiên được cung cấp trong câu trả lời. Xử lý các trường hợp ngoại lệ CSE là một ý tưởng tồi.
pixel

17

Thêm phần sau vào tệp cấu hình, và nó sẽ bị bắt trong khối thử. Lời cảnh báo ... hãy cố gắng tránh tình trạng này, vì điều này có nghĩa là một số loại vi phạm đang xảy ra.

<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
   </runtime>
</configuration>

2
Đối với những người sử dụng c ++ / cli làm dll, mã nên được thêm vào dự án .exe hàng đầu.
Felix

9

Tổng hợp từ các câu trả lời trên, làm việc cho tôi, đã làm theo các bước để bắt nó.

Bước # 1 - Thêm đoạn mã sau vào tệp cấu hình

<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
   </runtime>
</configuration>

Bước 2

Thêm vào -

[HandleProcessCorruptedStateExceptions]

[SecurityCritical]

trên đỉnh của chức năng bạn đang buộc bắt ngoại lệ

nguồn: http://www.gisremotesensing.com/2017/03/catch-exception-atteemed-to-read-or.html


Theo msdn.microsoft.com/en-us/l Library / Google , SecurityCriticalAttribution tương đương với nhu cầu liên kết để có sự tin tưởng hoàn toàn. Tôi không nghĩ rằng vấn đề được mô tả đòi hỏi phải có sự tin tưởng hoàn toàn.
Jeremy

0

Bạn có thể thử sử dụng AppDomain.UnhandledException và xem nếu điều đó cho phép bạn bắt được nó.

**BIÊN TẬP*

Dưới đây là một số thông tin có thể hữu ích (đó là một bài đọc dài).


2
Câu trả lời này không còn hoàn toàn chính xác do những thay đổi trong khung .NET. Trước 4.0 thì đúng. Mỗi phần của AccessViolationException và thử / bắt các khối trong msdn.microsoft.com/en-us/l
Library
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.