2012-02-12 32 views
10

Có mã này:Exception handler

char text[] = "zim"; 
int x = 777; 

Nếu tôi nhìn vào ngăn xếp trong đó x và văn bản được đặt ở đó đầu ra là:

09 03 00 00 7a 69 6d 00 

đâu:

  • 09 03 00 00 = 0x309 = 777 < - int x = 777
  • 7a 69 6d 00 = văn bản char [] = "zim" (mã ASCII)

Hiện nay là mã với try..catch:

char text[] = "zim"; 
try{ 
    int x = 777; 
} 
catch(int){ 
} 

Stack:

09 03 00 00 **97 85 04 08** 7a 69 6d 00 

Bây giờ giữa văn bảnx được đặt giá trị 4 byte mới. Nếu tôi thêm một lượt đánh bắt khác, thì sẽ có một cái gì đó như:

09 03 00 00 **97 85 04 08** **xx xx xx xx** 7a 69 6d 00 

v.v. Tôi nghĩ rằng đây là một số giá trị được kết nối với xử lý ngoại lệ và nó được sử dụng trong quá trình xếp thư giãn để tìm thấy bắt thích hợp khi ngoại lệ được ném vào khối thử. Tuy nhiên, câu hỏi là, chính xác giá trị 4 byte này là gì (có thể một số địa chỉ cho cấu trúc xử lý ngoại lệ hoặc một số id)?

Tôi sử dụng g ++ 4.6 trên máy Linux 32 bit.

+0

Xem [C++ try/throw/catch => machine code] (http://stackoverflow.com/questions/1331220/c-try-throw-catch-machine-code), trỏ đến http: // www .codeproject.com/Articles/2126/How-aC-compiler-thực hiện-ngoại lệ-xử lý –

+3

Tại sao bạn muốn biết. Ngay cả khi chúng tôi đã cho bạn một câu trả lời nó sẽ được cụ thể cho trình biên dịch và phiên bản cụ thể của trình biên dịch. Vì vậy, về mặt kỹ thuật nó không phải là một câu hỏi C++. Đó là một câu hỏi về g ++ và cách nó hoạt động. Mà trừ khi bạn đang thực sự vào viết phần mở rộng cho g ++ là hoàn toàn vô dụng kiến ​​thức. –

+4

@LokiAstari: g ++ và các trình biên dịch C++ khác cho * nix sử dụng [Itanium ABI] (http://sourcery.mentor.com/public/cxx-abi/abi-eh.html) trên hầu hết các plaforms (với một số sửa đổi tùy thuộc vào nền tảng), vì vậy nó không * mà * nền tảng/trình biên dịch cụ thể. Và vẫn còn, nó thú vị để biết làm thế nào các máy móc xử lý ngoại lệ có thể được thực hiện. –

Trả lời

5

AFAICT, đó là con trỏ đến "bảng thư giãn". Mỗi the Itanium ABI implementation suggestions, quá trình "[sử dụng] một bảng thư giãn, [để] tìm thông tin về cách xử lý các ngoại lệ xảy ra tại PC đó và đặc biệt, lấy địa chỉ của thói quen cá tính cho dải địa chỉ đó."

Ý tưởng đằng sau các bảng thư giãn là các dữ liệu cần thiết cho việc tháo bỏ ngăn xếp hiếm khi được sử dụng. Do đó, việc đặt một con trỏ lên ngăn xếp và lưu trữ dữ liệu trong một trang khác sẽ hiệu quả hơn. Trong trường hợp tốt nhất, trang đó có thể vẫn còn trên đĩa và thậm chí không cần phải được nạp trong RAM. Trong khi đó, xử lý lỗi kiểu C thường kết thúc trong bộ nhớ cache L1 vì nó là tất cả nội dòng.

0

Không cần phải nói tất cả điều này phụ thuộc vào nền tảng và v.v.

Đây có thể là địa chỉ. Nó có thể trỏ đến một phần mã (một số địa chỉ xử lý), hoặc phần dữ liệu (con trỏ đến một cấu trúc được xây dựng theo thời gian tạo với thông tin khung), hoặc ngăn xếp của cùng một luồng (trỏ đến bảng được tạo thời gian chạy) thông tin khung). Hoặc cũng có thể là rác, còn lại do yêu cầu căn chỉnh mà EH có thể yêu cầu.

Ví dụ trên Win32/x86 không có khoảng cách như vậy. Đối với mọi chức năng sử dụng xử lý ngoại lệ (có hoặc là try/catch hoặc __try/__except/__finally hoặc đối tượng có d'tors) - trình biên dịch tạo cấu trúc EXCEPTION_RECORD được phân bổ trên ngăn xếp (theo mã prolog chức năng). Sau đó, bất cứ khi nào một cái gì đó thay đổi trong chức năng (đối tượng được tạo ra/bị phá hủy, try/catch khối đã nhập/thoát) - trình biên dịch thêm một lệnh thay đổi cấu trúc này (chính xác hơn - sửa đổi phần mở rộng của nó). Nhưng không có gì hơn được phân bổ trên ngăn xếp.