日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
淺析C++編譯器怎樣實(shí)現(xiàn)異常處理問題

在介紹C++編譯器如何實(shí)現(xiàn)異常處理的問題之前,先讓大家了解下什么是C++編譯器?其實(shí)C++編譯器是一個(gè)與標(biāo)準(zhǔn)化C++高度兼容的編譯環(huán)境,不同的編譯器也會(huì)對(duì)不同的CPU進(jìn)行不同的優(yōu)化。

本文討論了C++編譯器如何實(shí)現(xiàn)異常處理。我將假定你已經(jīng)熟悉異常處理的語法和機(jī)制,用于VC++的異常處理庫,要用庫中的處理程序替換掉VC++提供的那個(gè),你只需要調(diào)用下面這個(gè)函數(shù):

 
 
 
  1. install_my_handler();

之后,程序中的所有異常,從它們被拋出到堆棧展開(stack unwinding),再到調(diào)用catch塊,***到程序恢復(fù)正常運(yùn)行,都將由我的異常處理庫來管理。

與其它C++特性一樣,C++標(biāo)準(zhǔn)并沒有規(guī)定編譯器應(yīng)該如何來實(shí)現(xiàn)異常處理。這意味著每一個(gè)編譯器的提供商都可以用它們認(rèn)為恰當(dāng)?shù)姆绞絹韺?shí)現(xiàn)它。下面我會(huì) 描述一下VC++是怎么做的,但即使你使用其它的編譯器或操作系統(tǒng)①,本文也應(yīng)該會(huì)是一篇很好的學(xué)習(xí)材料。VC++的實(shí)現(xiàn)方式是以windows系統(tǒng)的結(jié) 構(gòu)化異常處理(SEH)②為基礎(chǔ)的。

我認(rèn)為C++編譯器異?;蛘呤潜幻鞔_的拋出的,或者是由于除零溢出、空指針訪問等引起的。當(dāng)它發(fā)生時(shí)會(huì)產(chǎn)生一個(gè)中斷,接下來控制權(quán)就會(huì)傳遞到操作系統(tǒng) 的手中。操作系統(tǒng)將調(diào)用異常處理程序,檢查從異常發(fā)生位置開始的函數(shù)調(diào)用序列,進(jìn)行堆棧展開和控制權(quán)轉(zhuǎn)移。Windows定義了結(jié)構(gòu) "EXCEPTION_REGISTRATION",使我們能夠向操作系統(tǒng)注冊自己的異常處理程序。

 
 
 
  1. struct EXCEPTION_REGISTRATION
  2. {
  3.     EXCEPTION_REGISTRATION* prev;
  4.     DWORD handler;
  5. }; 

注冊時(shí),只需要?jiǎng)?chuàng)建這樣一個(gè)結(jié)構(gòu),然后把它的地址放到FS段偏移0的位置上去就行了。下面這句匯編代碼演示了這一操作:

 
 
 
  1. mov FS:[0], exc_regp

prev字段用于建立一個(gè)EXCEPTION_REGISTRATION結(jié)構(gòu)的鏈表,每次注冊新的EXCEPTION_REGISTRATION時(shí),我們都要把原來注冊的那個(gè)的地址存到prev中。那么,那個(gè)異?;卣{(diào)函數(shù)長什么樣呢?在excpt.h中,windows定義了它的原形:

 
 
 
  1. EXCEPTION_DISPOSITION (*handler)( 
  2. _EXCEPTION_RECORD *ExcRecord, 
  3. void* EstablisherFrame, 
  4. _CONTEXT *ContextRecord, 
  5. void* DispatcherContext); 

不要管它的參數(shù)和返回值,我們先來看一個(gè)簡單的例子。下面的程序注冊了一個(gè)C++編譯器異常處理程序,然后通過除以零產(chǎn)生了一個(gè)異常。異常處理程序捕獲了它,打印了一條消息就完事大吉并退出了。

 
 
 
  1. #include 
  2. #include 
  3. using std::cout; 
  4. using std::endl; 
  5. struct EXCEPTION_REGISTRATION 
  6. EXCEPTION_REGISTRATION* prev; 
  7. DWORD handler; 
  8. }; 
  9. EXCEPTION_DISPOSITION myHandler( 
  10. _EXCEPTION_RECORD *ExcRecord, 
  11. void * EstablisherFrame, 
  12. _CONTEXT *ContextRecord, 
  13. void * DispatcherContext) 
  14. cout << "In the exception handler" << endl
  15. cout << "Just a demo. exiting..." << endl
  16. exit(0); 
  17. return ExceptionContinueExecution; //不會(huì)運(yùn)行到這 
  18. int  g_div = 0; 
  19. void bar() 
  20. //初始化一個(gè)EXCEPTION_REGISTRATION結(jié)構(gòu) 
  21. EXCEPTION_REGISTRATION reg, *preg = ?  
  22. reg.handler = (DWORD)myHandler; 
  23. //取得當(dāng)前異常處理鏈的"頭" 
  24. DWORD prev; 
  25. _asm 
  26. mov EAX, FS:[0] 
  27. mov prev, EAX 
  28. reg.prev = (EXCEPTION_REGISTRATION*) prev; 
  29. //注冊! 
  30. _asm 
  31. mov EAX, preg 
  32. mov FS:[0], EAX 
  33. //產(chǎn)生一個(gè)異常 
  34. int  j = 10 / g_div;  //異常,除零溢出 
  35. int  main() 
  36. bar(); 
  37. return 0; 

注意EXCEPTION_REGISTRATION必須定義在棧上,并且必須位于比上一個(gè)結(jié)點(diǎn)更低的內(nèi)存地址上,windows對(duì)此有嚴(yán)格要求,達(dá)不到的話,它就會(huì)立刻終止進(jìn)程。


網(wǎng)站欄目:淺析C++編譯器怎樣實(shí)現(xiàn)異常處理問題
網(wǎng)站鏈接:http://m.5511xx.com/article/dpdsgph.html