2010-05-06 30 views

Trả lời

33

Chúng tương đương với các tín hiệu Unix, và cho phép bạn nắm bắt các ngoại lệ CPU như vi phạm truy cập, hướng dẫn bất hợp pháp, chia cho số không.

Với các tùy chọn trình biên dịch phù hợp (/ EHa cho Visual C++), ngoại lệ C++ sử dụng cùng cơ chế như chồng thư giãn hoạt động đúng cho cả ngoại lệ C++ (người dùng) và ngoại lệ SEH (OS).

Không giống như ngoại lệ C++, SEH không được nhập nhưng tất cả đều chia sẻ cấu trúc dữ liệu giống như mã ngoại lệ (nguyên nhân) và thông tin bổ sung về mã bị lỗi và những gì sổ đăng ký CPU được giữ tại thời điểm xảy ra lỗi. Xem GetExceptionCodeGetExceptionInformation để biết thêm chi tiết về điều này.

Ngoài ra, SEH có xử lý "cơ hội đầu tiên", cho phép bạn đăng nhập hoặc xử lý ngoại lệ trước khi hủy phá hủy tất cả biến cục bộ.

+1

Lưu ý mặc dù mặc định đã được thay đổi cách xử lý các ngoại lệ SEH như ngoại lệ C++ vì ngoại lệ SEH không an toàn để xử lý như ngoại lệ C++. SEH ngoại lệ thường là những thứ như vi phạm truy cập, và cố gắng làm C++ thư giãn trong điều kiện như vậy là không thể và có thể gây ra chương trình chấm dứt. –

+3

Không có gì vốn không an toàn khi giải quyết vi phạm quyền truy cập. Tất nhiên, nếu vi phạm truy cập do tham nhũng của cấu trúc dữ liệu nội bộ (đặc biệt là ngăn xếp tràn có ảnh hưởng đến thông tin ngăn xếp cuộc gọi) thì việc tháo gỡ có thể thất bại, nhưng nhiều, nếu không phải là đa số, ngoại lệ SEH không thực sự phản ánh tham nhũng. –

+0

Vui lòng đọc http://stackoverflow.com/questions/4414027/visual-c-unmanaged-code-use-eha-or-ehsc-for-c-exceptions về tác dụng phụ khó chịu của SEH với bỏ qua dấu ba chấm-Ngoại lệ (ví dụ catch (...) {}) –

20

Họ nên biết rằng chúng không phải là một phần của Tiêu chuẩn C++ - chúng là sáng chế của Microsoft và có thể được sử dụng bằng các ngôn ngữ khác ngoài C++.

16

A Crash Course on the Depths of Win32™ Structured Exception Handling

bài viết Đó là các tham khảo trên nhận được lên đến tốc độ với SEH. 13 năm sau, vẫn là tốt nhất có.

Có chủ đề riêng về MSDN cho SEH vs. C++ Exception Handling Differences.

Một số điều C++ phát triển nên biết nếu SEH đang được thảo luận:

Viết C/C++ SEH Exception Handlers:

__try 
{ 
    // guarded code 
} 
__except (expression) 
{ 
    // exception handler code 
} 

này được xử lý ngoại lệ không C++, là MS mở rộng cụ thể cho hooking thẳng inot SEH. Nó hoạt động rất khác với trường hợp ngoại lệ C++ chạy của bạn. Bạn cần hiểu rõ về SEH để sử dụng chúng.

Viết C/C++ SEH Termination Handlers:

__try { 
    // guarded code 
} 
__finally (expression) { 
    // termination code 
} 

Tương tự như với các handler SEH, đừng nhầm lẫn này với C ngữ nghĩa ngoại lệ ++. Bạn cần hiểu rõ về SEH.

_set_se_trasnlator: đây là chức năng dịch ngoại lệ SEH thành ngoại lệ loại C++ khi ngoại lệ không đồng bộ được sử dụng /EHa.

Và cuối cùng, ý kiến ​​cá nhân: nhà phát triển C++ có biết SEH không? Sau khi tân binh đầu tiên của bạn .ecxr bạn sẽ hiểu rằng khi đẩy đến xô đẩy ngoại lệ C++ chỉ là một ảo ảnh được cung cấp để thuận tiện cho bạn. Điều duy nhất đang diễn ra là SEH.

+7

'__finally' không có' (biểu thức) ' – Abyx

24

thời gian gần đây tôi đã có một vấn đề mà là do gián tiếp bởi SEH, đặc biệt vì một tính năng của SEH mà tôi nghĩ mỗi nhà phát triển cần phải nhận thức:

Khi SEH được sử dụng destructors không được gọi, vì vậy nếu bạn có dọn dẹp mã trong destructor của bạn nó sẽ không được làm sạch.

Vấn đề của chúng tôi là do một phần quan trọng được bao bọc bởi một đối tượng có khóa trong hàm khởi tạo và mở khóa trong trình phá hủy.

Chúng tôi đã có tình huống bế tắc và không thể hiểu tại sao, và sau khoảng một tuần đào qua mã và bãi và gỡ lỗi, cuối cùng chúng tôi đã hiểu rằng có một ngoại lệ do COM xử lý và gây ra Critical để giữ khóa. Chúng tôi đã thay đổi một cờ biên dịch trong VS trong các thuộc tính của dự án để cho nó chạy các destructors ngay cả đối với SEH và giải quyết được vấn đề.

Vì vậy, mặc dù bạn không thể sử dụng SEH trong mã của mình, bạn có thể đang sử dụng thư viện (như COM) và có thể gây ra hành vi không mong muốn.

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