2013-02-06 26 views
17

Ngoại lệ hoạt động như thế nào từ quan điểm của Hệ điều hành?ai chịu trách nhiệm là nó để ném một ngoại lệ ?; Hệ điều hành hoặc quy trình?

Đến từ C++, tôi có thể hiểu ngoại lệ từ quan điểm của lập trình viên.
Khi ngoại lệ bị ném, ngăn xếp bắt đầu giãn ra và mỗi bản ghi kích hoạt có cơ hội bắt và xử lý ngoại lệ.

Nhưng ai có trách nhiệm loại bỏ ngoại lệ ngay từ đầu?

  1. Đây có phải là hệ điều hành gửi trình kích hoạt tới quy trình cho biết để nhập "trạng thái xử lý ngoại lệ" không?
  2. Quy trình có gọi và xử lý các ngoại lệ trong không gian chương trình riêng của nó không, chưa được phát hành với hệ điều hành?

Dưới đây là hai chương trình bị lỗi minh họa sự không chắc chắn của tôi.

int main(){ 

    int i = 1/0; //did the OS tell the process to end? 

    return 0; 
} 

#include <exception> 

int main(){ 

    throw 11; //did the process tell the OS it needs to end? 

    return 0; 
} 
+1

Câu trả lời nhanh: Ngoại lệ C++ hoàn toàn được xử lý. Nhưng tôi không có đủ kiến ​​thức để đi xa hơn về câu trả lời về cách chính xác các ngoại lệ hoạt động. Chỉnh sửa: Trong trường hợp đầu tiên của bạn quá trình nhận được một tín hiệu có thể được chuyển đổi thành một ngoại lệ C++ –

+0

không có tai nạn xảy ra trong một trong các ví dụ của bạn –

+1

@ BЈовић Tôi nghĩ rằng bằng sự cố, Xploit có nghĩa là thoát với mã lỗi không 0. –

Trả lời

12

Ngoại lệ C++ là một phần của ngôn ngữ, được xác định theo tiêu chuẩn ngôn ngữ và được thực hiện bởi trình biên dịch và thư viện thời gian chạy. Có khác exceptions được phát hiện bởi CPU, như chia cho số không hoặc dereferencing một con trỏ NULL, cả hai là ví dụ của Undefined Behavior trong tiêu chuẩn ngôn ngữ. Đó là faults trong thuật ngữ bộ xử lý và trên x86, ví dụ như kích hoạt fault handler, sau đó được hệ điều hành hỗ trợ. Hệ điều hành sau đó có thể chọn để báo cáo lỗi đó cho quá trình gây ra nó, trên Unix, điều này được thực hiện với signals. Nếu quá trình của bạn đã cài đặt một ví dụ signal handler cho SIGSEGV, nó có thể xử lý lỗi do CPU tạo ra khi quá trình hủy bỏ con trỏ NULL ... cơ chế đó tách biệt với ngoại lệ C++ được định nghĩa bởi ngôn ngữ.

Trong ví dụ của bạn, khi một chương trình C++ throws một ngoại lệ, nó được xử lý hoàn toàn bằng mã trình biên dịch và thư viện thời gian chạy ngôn ngữ, không cần gọi hạt nhân và không có lỗi phần cứng do bộ xử lý tạo ra.

+0

Một bổ sung nữa cho câu trả lời này sẽ là [triển khai LLVM] (http://llvm.org/docs/ExceptionHandling.html) của các ngoại lệ ngôn ngữ/chương trình chuẩn. Tóm tắt đủ và được định dạng độc đáo. –

8

Bạn đang nói về hai quá trình ngoại lệ hoàn toàn khác nhau.

Đầu tiên được hệ điều hành cung cấp. Trong Windows, bạn có thể sử dụng __try and __except để xử lý chúng.

Thứ hai được cung cấp bởi trình biên dịch C++ và không liên quan đến HĐH theo bất kỳ cách nào.

+4

+1 Tôi cũng sẽ thêm rằng các ngoại lệ C++ có triển khai nền tảng cụ thể và thường dựa trên các cơ sở được cung cấp bởi hệ điều hành. – lapk

+0

Nhận xét của @lapk dường như mâu thuẫn trực tiếp với câu trả lời: "dựa trên"! = "Không liên quan đến bất kỳ cách nào". Một số làm rõ sẽ là tốt. –

+0

@ FelixDombek ý tôi là đặc tả C++ tuyên bố cách hoạt động của ngoại lệ C++, độc lập với hệ điều hành. Nếu một trình biên dịch chọn sử dụng một số cơ sở hệ điều hành thì nó là miễn phí để làm như vậy, nhưng đó là một chi tiết thực hiện - bạn không thể dựa vào nó. –

6

Vì tôi chỉ biết một hoặc hai hệ điều hành được viết bằng C++, và cái tôi biết rõ hơn, không chính thức sử dụng ngoại lệ, có khá nhiều quy tắc ngoại lệ được hệ điều hành ném ra.

Ba hệ điều hành chính (Linux, Windows, MacOS X), cùng với tất cả các dạng Unix (AIX, Solaris, HP-UX, v.v.) được viết bằng C, cùng với hầu hết các hệ điều hành khác có sẵn trên thị trường. t viết trong assembler, vì vậy không thể ném ngoại lệ loại C++ [điều đó không nói rằng không có ngoại lệ phần mềm điều khiển, chỉ là chúng không phải là loại excepion mà bạn bắt với "try/catch" trong C++ mà không có một số loại dịch] . Trong ví dụ đầu tiên, hệ điều hành chắc chắn có liên quan [trong tất cả các hệ điều hành mà tôi biết cách chúng hoạt động], vì chia cho 0 gây ra ngoại lệ phần cứng trên tất cả các máy có phân chia như một hàm, và do đó hệ điều hành sẽ cần để được tham gia. Ngoài ra, đây sẽ biên dịch và thất bại trong việc theo cách tương tự cho dù đó là C++, C hoặc bạn viết điều tương tự trong lắp ráp. Đối với hầu hết các hệ điều hành, chúng sẽ gửi tín hiệu đến chương trình, nhưng vì bạn không có mã để xử lý tín hiệu, mã của bạn rất có thể sẽ bị hủy bỏ, cho hệ điều hành biết rằng có điều gì đó kỳ lạ đã xảy ra ngăn xếp.

Trong trường hợp thứ hai, hệ điều hành không hề liên quan. Có một "try-catch" khối xung quanh gọi to main, mà nói: "Rất tiếc, ai đó ném một cái gì đó mà không bị bắt, cho phép thoát". Phần duy nhất của điều đó có liên quan đến hệ điều hành là "thoát khỏi quá trình này", trong đó tất nhiên sẽ cần phải được thực hiện bởi hệ điều hành, mặc dù tôi tin rằng trong hầu hết các hệ điều hành, chỉ cần trở về từ 'địa chỉ bắt đầu của ứng dụng' cũng sẽ có cùng tác dụng.

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