Xử lý ngoại lệ có cấu trúc Windows (SEH) có cấu trúc hai pha. Khi ngoại lệ xảy ra, trước tiên Windows sẽ tìm một trình xử lý ngoại lệ bằng cách theo chuỗi xử lý ngoại lệ đã đăng ký (phần đầu được lưu trữ trong fs: [0] trên x86, tức là từ đầu tiên trong phân đoạn được chỉ ra bởi phân đoạn FS đăng ký - tất cả các logic phân đoạn bù đắp 16 bit xấu xí đó không biến mất trong 32 bit, nó chỉ trở nên ít liên quan hơn).
Tìm kiếm được thực hiện bằng cách gọi hàm có cờ cụ thể, con trỏ được lưu trữ trong mỗi khung ngoại lệ trên ngăn xếp. fs: [0] trỏ tới khung trên cùng. Mỗi khung trỏ đến khung trước đó. Cuối cùng, khung cuối cùng trong danh sách là một khung đã được cung cấp bởi hệ điều hành (trình xử lý này sẽ bật lên một hộp thoại ứng dụng sụp đổ nếu một ngoại lệ chưa được giải quyết đạt tới nó).
Các chức năng này thường kiểm tra loại ngoại lệ và trả lại mã để cho biết phải làm gì. Một trong những mã có thể được trả về về cơ bản là "bỏ qua ngoại lệ này và tiếp tục". Nếu Windows thấy điều này, nó sẽ thiết lập lại con trỏ lệnh đến điểm ngoại lệ và tiếp tục thực hiện. Một mã khác cho biết rằng khung ngoại lệ này sẽ xử lý ngoại lệ đã cho. Mã thứ ba là "Tôi sẽ không bắt ngoại lệ này, hãy tiếp tục tìm kiếm". Windows tiếp tục gọi các hàm bộ lọc ngoại lệ này cho đến khi nó tìm thấy một hàm xử lý ngoại lệ theo cách này hay cách khác.
Nếu Windows tìm thấy một xử lý ngoại lệ bằng cách bắt nó, nó sẽ tiến hành giải phóng ngăn xếp trở lại trình xử lý đó, bao gồm gọi lại tất cả các chức năng, chỉ chuyển sang một cờ khác. Vào thời điểm này, các hàm thực thi logic finally
, cho đến khi trình xử lý thực hiện logic except
.
Tuy nhiên, với ngoại lệ bảo vệ trang ngăn xếp, quá trình này khác. Không có trình xử lý ngoại lệ của ngôn ngữ nào sẽ chọn xử lý ngoại lệ này, bởi vì nếu không thì cơ chế tăng trưởng ngăn xếp sẽ bị phá vỡ.Thay vào đó, bộ lọc tìm kiếm lọc toàn bộ bộ xử lý ngoại lệ được cung cấp bởi hệ điều hành, tăng phân bổ stack bằng cách cam kết bộ nhớ thích hợp, và sau đó trả về mã trả về thích hợp để chỉ ra rằng hệ điều hành sẽ tiếp tục ở nơi nó bị tắt, thay vì thư giãn ngăn xếp.
Công cụ và cơ sở hạ tầng gỡ lỗi được thiết kế để cho các ngoại lệ cụ thể này phát ra chính xác, vì vậy bạn không cần phải lo lắng về việc xử lý chúng.
Bạn có thể đọc thêm về SEH theo số Matt Pietrek's excellent article in MSJ from over a decade ago.
Sao lưu một khoảnh khắc. Bạn cần gọi một trong những hàm IsBadXXXPtr để làm gì? – jmucchiello
Tôi không cần bất kỳ IsBadXXXPtr (Tôi đồng ý với Raymond - nó là tốt hơn để sụp đổ trong những trường hợp này). Tôi chỉ phát hiện ra rằng tôi không biết, tình hình này được xử lý như thế nào trong Delphi. Đó là lý do tại sao tôi hỏi - chỉ vì tò mò. – Alex
Mã nào bạn "biết" Delphi chèn để mở rộng ngăn xếp khi truy cập các mảng tĩnh lớn? Tôi chưa bao giờ thấy bất cứ thứ gì thuộc loại này. –