6

Trong mã sau, tại lần lặp đầu tiên tôi nhận được ngoại lệ và tại bước thứ hai, tôi nhận được lỗi phân đoạn không có thông báo lỗi được in. Có vẻ như ngoại lệ không bị bắt:Tôi nhận được lỗi phân đoạn thay vì một ngoại lệ

int i = 0; 
while(i++ < 10) 
{ 
    try { 
     cout << "Iteration: " << i << endl; 
     // Code... 
     cout << "OK" << endl; 
    } 
    catch(...) 
    { 
     cerr << "Error message" << endl; 
     continue; 
    } 
} 

Output: 
Iteration 1 
Error message 
Iteration 2 
Segmentation fault 

Có bình thường hay có điều gì đó thực sự sai xảy ra?

Trong trường hợp cần liên quan, trong khối mã đó tôi đặt lại kết nối MySQL và ngoại lệ được tạo khi tôi kiểm tra xem kết nối có được đóng hay không.

Cảm ơn.


Hệ điều hành:
Linux - OpenSuse 11.4
C++ - GCC 4.5.1
Intel Xeon

+2

lỗi Segmentation đang có. không bị bắt bởi 'try-catch'. Bạn nên sử dụng một trình gỡ lỗi để nắm bắt điều đó. –

+10

Tôi khá chắc chắn rằng nó phải nằm trong' // Code ... '. Không thể phát hiện các điểm segfault trong những gì bạn đã đăng. .. – kratenko

+0

Tôi quản lý để sao chép đầu ra của bạn bằng cách viết 'if (i == 1) throw 0; else i = * (int *) 0;' nhưng đó không phải là '// Code' của bạn, phải không? –

Trả lời

16

Vì các segfaults không được gây ra (trực tiếp) phần mềm, mà là do bộ xử lý phát hiện bạn đang cố gắng truy cập bộ nhớ không hợp lệ (hoặc truy cập bộ nhớ một cách không hợp lệ - ví dụ như ghi vào bộ nhớ được bảo vệ chống ghi bộ nhớ không phải là nghĩa vụ phải được thực hiện, vv), nó không phải là "dễ bắt" với try/catch, được thiết kế để bắt phần mềm ném một ngoại lệ. Chúng được gọi là ngoại lệ, nhưng chúng có nguồn gốc ở các cấp độ khác nhau của phần mềm/phần cứng của hệ thống.

Về mặt kỹ thuật, bạn có thể bắt segfaults bằng bộ xử lý tín hiệu cho SIGSEGV. Tuy nhiên, như Ivaylo giải thích, nó không phải là, thông thường, được phép chỉ "thử lại" nếu bạn nhận được một segfault. Trình xử lý tín hiệu cho SIGSEGV được phép longjmp hoặc exit, nhưng không nên chỉ trả lại.

Đọc thêm về các tín hiệu ở đây: http://www.alexonlinux.com/signal-handling-in-linux

điển hình C++ ngoại lệ (kết quả của throw) có thể được thử lại mà không có vấn đề (tất nhiên, cùng một ngoại lệ có thể được ném một lần nữa, tất nhiên

5

Bạn không thể bắt lỗi phân khúc như thế. Lỗi này thường không thể khôi phục được và không được xử lý bởi try-catch thông thường. Nó có nghĩa là một cái gì đó đã đi rất sai có thể ngăn xếp tham nhũng hoặc tương tự. Hãy thử sử dụng valgrind để phát hiện điều gì gây ra lỗi phân đoạn.

+4

Segfaults cũng xảy ra khi dereferencing một con trỏ không hợp lệ (null hoặc bằng cách khác trỏ đến một khu vực chưa được phân bổ) mà là một lỗi khá phổ biến, không có gì kịch tính như tham nhũng stack. – syam

1

catch các mệnh đề bắt ngoại lệ được đưa ra bởi các biểu thức throw. Trong tiêu chuẩn C++ (và trong bất kỳ thực hiện sane C++) họ làm không lỗi bắt được phát hiện bởi hệ điều hành hoặc phần cứng. Để làm khác sẽ làm cho nó quá khó để viết mã ngoại lệ an toàn.

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