trycatch捕捉梦幻西游2异常捕捉器怎么用

linux 下 C 編程和make的方法 (十、C版的try catch 捕捉段錯誤和異常處理)
哇塞,C語言有try catch嗎?當然沒有。倒。。可能有人說了,那你野鬼說沒有的東西做什麼。
&&& 這裏需要重申一下,所謂正向設計下問題檢測的開發方法。正向設
哇塞,C語言有try catch嗎?當然沒有。倒。。可能有人說了,那你野鬼說沒有的東西做什麼。
&&& 這裏需要重申一下,所謂正向設計下問題檢測的開發方法。正向設計時,在錯誤檢測和問題修复的方法是指:
&&&&& 根據源碼分析,在源碼中加插檢測代碼的方式,驗證對代碼的理解和預判是否正確。
&&&& 而反向跟蹤是根據機器執行動作,反向理解邏輯的運行狀態,例如GDB。兩者很多方面都很像,但存在一個最主要的區別在於,你是在先驗的讓程序運行判斷是否符合先驗,還是在程序的運行中理解代碼的邏輯。
&&& 例如正向設計的問題判斷,如果通過try catch來處理,則表示你已經估計到這裏是個潛在可能的錯誤,而通過運行來驗證你的判斷是否成立。錯誤的理解和判斷是在對源碼的分析上,反之,通過 GDB或者其他IDE加斷點的跟蹤,屬於反向檢測運行狀態來判斷邏輯可能哪裏出錯。
&&& 可惜try catch在C標准裏面並沒有。這裏,就通過指針訪問的段錯誤,來設計一個類似try catch的小玩意。希望新手能通過這個寫出其他的try catch。
&&& 首先我們要動點C標准裏,signal和setjmp的東西,以及GNU C的 glibc函數sigsetjmp,siglongjmp。記得要注意哪些是標准裏的,哪些不是,這對以後的平台移植很用作用,哪怕你不移植,但萬一別人 要移植,因为你沒有區分好,導致別人到處找和平台相關的代碼,最後這個代碼別人用不了,你的代碼又有何價值。
&&& 先說一下signal這個函數。這函數的作用就是類似對中斷向量表的重載,其實是個重定位工作。中斷向量表是什麼意思,很簡單,就是有一個表,表裏面有一 堆函數地址,如果對應的中斷發生了,就跳轉到該中斷對應的中斷向量表的對應存儲區域的函數裏(希望看這句話你別跟着念,眼睛也別花,哈)。如果不重定位這 些函數,則會启用默認的函數。例如给打印個消息,然後讓進程停止。如果通過signal 對這個中斷向量表進行”重載“,則可以進入你指定的函數。而不會進入默認的方式。
&&& 簡單舉例吧,正常的程序,你在bash上執行 ctrl+C,會讓程序停止。實際是怎麼發生的呢?
&&& 1、鍵盤發現你按鍵了,則會發出一個信號,除了按鍵值本身。該信號是告訴CPU,我有事了,CPU的硬件如果不對這個信號視而不見的話,就會告訴OS,哦,有個硬中斷發生。
&&& 2、此時,OS就對應的發出個軟中斷,linux下就是 SIGINT。
&&& 3、如果對應你當前進程的自己的”中斷向量表“是默認情況,則會OS启動一個函數,這個函數會發出一個kill的工作,要求將你這個進程結束。
&&& 4、OS此時發現這個動作。就把你的進程给卡擦了。
&&& 而你如果用signal“重載”這個中斷,則此時原先默認函數不會執行,你會發現,你的程序該做什麼還是做什麼,除非你的新函數仍然要求kill掉你這個進程。
&&& 那麼對於段錯誤,也存在一個中斷,是由誰產生的? MMU,硬件產生的。OS獲取這個錯誤之後,就會到對應進程的“中斷向量表”找你是否重載過這個對應的中斷響應函數,當然這中間還有些其他工作比如中斷屏 蔽方面的檢查工作等,我就不展開了。由此,如果你寫了一個新的函數,則可以不用退出,可以處理些自己的想做的事情。
&&& 但是很討厭的一個問題,如果是你的進程出錯,而且出錯的理由是對一個不正確的內存空間進行讀寫操作,無論你執行多少次,這個錯誤仍然存在。因为你的代碼產 生個由MMU發出的段錯誤的中斷,此時你的代碼被強行掛起來,就是說現在輪不到你玩了,然後OS處理對應的中斷響應,就是你寫的代碼,而寫的那個函數執行 完畢後,如果不kill或者其他動作,你的代碼還會被再次執行。那麼你的進程會怎麼執行呢?在你上次錯的地方繼續執行。。。。這就鬱悶大發了。因为再次產 生個錯誤,此時又會進入你的中斷響應函數。
&&& 於是乎,你會發現,你的屏幕在不停的打印東西,如果你的那個函數內有條printf想提醒你,進入了這個函數了。
&&& 此時,我們就需要動點手段了。這裏要談一下setjmp ,和longjmp,最終會用到sigsetjmp,siglongjmp,注意,這兩玩意不是C標准的,glibc支持,其他的一些C環境也支持,我不一一列出來了。可以查資料。
&&& 先說setjmp, longjmp。上下文這個詞在OS裏,特別進程管理部分經常提到,什麼意思呢?簡單說就是現場環境,不過只是CPU裏面的,包括指令的位置(其實也是在 寄存器裏),常規寄存器裏的內容(也包括堆棧指針寄存器),和外部存儲器就是內存沒有關系。
&&& 繼續舉例吧。
&&& 假設,剧場正在上演一個話剧,還沒結束呢。結果通知,立刻清場,为什麼,領導要來開會,你別問为什麼,領導就是領導,優先級高,此時你怎麼辦,那就和觀眾 商量一下,我們把現場記錄下來,台詞說哪也記錄下來,等領導開完會咱們接着看,此時剧場的情況清點記錄完畢,並清理幹净,等領導開會,會開完了,再根據被 打斷時的場景進行恢复,則此時觀眾可以連貫的繼續看下去。
&&& 另一個例子就是香港的賭王片,賭到高潮的時候,無論是正方的叛徒還是反方的臥底,無論是用刀還是用槍,反正把男一號给搞傷了,怎麼辦?封牌局,拿個罩子, 把桌子罩起來,誰也別想改動這些牌的內容。等男二號上時在繼續賭,牌是什麼情況,肯定沒有變過,無論中間穿插了多少其他鏡頭。假設剛好這個時候有跑龍套的 要用桌子吃午飯,剧組同意了,把桌子给他用,但是桌子上面的東西則原封不動的挪到別的地方。等男二號來,再把跑龍套的趕走,恢复成前面的牌局。
&&& 這裏剧場場景的記錄並切換成領導的會議桌,以及桌子上的牌局挪動,讓给跑龍套的吃午飯,都是叫做上下文切換。setjmp的作用就是保存當前進入 setjmp函數時的環境。同時setjmp返回個值为0。以區別longjmp跳轉到當前位置。類似函數調用函數,父函數需要保存的現場工作,否則子函 數退出時,父函數也沒辦法正常繼續工作啊。是不是。當然 setjmp所保存的東西必函數調用時保存的要多一些。其實setjmp沒什麼特色。我自己都寫過對應匯編以實現特定硬件上的需求。就是一堆mov,把寄 存器的值存到指定的位置再返回0。
&&& 而longjmp的意思是,可以在你的代碼任意的位置,只要setjmp執行過以後的地方,直接跳,跳哪呢?就是跳到setjmp調用時的位置,這個跳哪 的信息從哪得來的,就是setjmp的参數指向的一個BUF,你在這個BUF裏面保存了當前地址。因此,如果多次setjmp同一個buf,則在跳到最後 一次,如果每次setjmp了不同的BUF,那麼哪個BUF作为longjmp的参數,就是跳到對應setjmp的位置。此時等同於setjmp被返回, 只不過返回值不为0,由此判斷是longjmp過來的。繼續舉例子。
&&& 導演說,第N個鏡頭。。。然後就開始演,演了一半,穿幫了,導演說,停!此時就是longjmp,longjmp去哪?和你演的這段都沒關系。直接到當前這個鏡頭的開始位置,为什麼當前鏡頭可以拍N多次,就是因为你在鏡頭開始位置做了一個setjmp。
&&& 現在說下sigsetjmp siglongjmp。
&&& sigsetjmp ,siglongjmp比setjmp ,longjmp的組合多了個中斷屏蔽信息的存儲。此時siglongjmp可以恢复到sigsetjmp出現時的中斷屏蔽情況。在後面给出的代碼的 test10函數中,特地做了一個setjmp ,longjmp的方式,你會發現,第二次出錯,並不會進入normal_longjmp函數。因此此時的中斷配置等信息並沒有對應記錄下來,屬於出錯後 的情況。
&&& &OK。現在說說setjmp longjmp有什麼好處。
&&& 前面說了。signal對SIGSEGV這個中斷的響應函數修改後,函數退出,會再次執行MMU發生錯誤的代碼位置,因此我們要確保函數跳過當前出錯的位置,執行到我們希望跳過的代碼。類似C++的try catch那样,我們希望有try catch。如下
&&& char *p = &1234&;
&&& p[2] = '1';//這顯然是錯的嘛
&&& CATCH ;//
&&& 則我們可以
if (setjmp(buf) == 0){
------分隔線----------------------------
1,用powerdesigner&進行數據建模時如果允許重复使用某一字段...
//gezidan/archive//152772.html
因 平可HC。述略
HC有HE,FE,BE,無述
4&3,3相異,異拆亦可替...
&&& HashMap是map接口的一個實現,非線程安全/速度較快...
E: 無法獲得锁 /var/lib/dpkg/lock - open (11: 資源暫時不可用)
E: 無法...
PowerDesigner大小寫轉換,不用寫vbscript,只需要選擇 菜單\Tools\M...当前位置: →
→ C#异常处理-采用trycatch语句结构来捕获和处理异常
C#异常处理-采用trycatch语句结构来捕获和处理异常
& 作者及来源: 流星落 - 博客园 &
&收藏到→_→:
摘要: C#异常处理-采用try、catch语句结构来捕获和处理异常
"C#异常处理-采用trycatch语句结构来捕获和处理异常"::
使用try...catch语法结构如下:
try{//程序代码}catch(exception e){//错误代码处理}
异常处理的语法:try{有可能产生错误的代码}catch(异常处理声明(声明此catch区段要捕获哪一种类型的异常错误,可以不用声明,这样子便会让catch去捕获任意类型的异常错误)){异常处理程序代码(当catch捕获到异常错误后,所采取对应的程序代码)}注意:利用catch来捕获try-catch中产生的异常错误,可以建立多个catch区段以捕获不同类型的异常错误。
一个除数和零的简单例子:
public class divisoriszero{private static void main(){&&& int dividend = 10;&&& int divisor1 = 0;&&& int divisor2 = 5;&&&&&& int dividevalue2;&&& try&&& {
&&&&& console.writeline("10/5=",10/5);&&&&& dividevalue = dividend / divisor1; //(1)&&&&& dividevalue2=dividend/divisor2; //(2)&&&&& console.writeline("我这里不会发生异常,我可以正常显示,我的值为{0}", dividevalue2);&&&&&&& //(3)这一行将不会被执行。&&& }&&& catch(exception e)&&& {&&&&& console.writeline("传递过来的异常值为:{0}", e);&&& }&&& finally&&& {&&&&& console.writeline("无论是否发生异常,我都会显示。");&&& }}}
注:(1)行被执行则会抛出一个异常,如果没有catch语句,程序会异常终止,使用不带参数的catch子句,则可以捕获任意类型的异常。 如果将(1)行和上面的相关变量声明注释掉,启用(2)行,这意味该程序运行时不会出现异常,从此文来自: 马开东博客
转载请注明出处 网址:
输出可知,finally代码块仍将被执行。
public class divisoriszero{private static void main(){&&& int dividend = 10;&&& //int divisor1 = 0;&&& int divisor2 = 5;&&& //&&& int dividevalue2;&&& try&&& {&&&&& //dividevalue = dividend / divisor1; //(1)&&&&& dividevalue2=dividend/divisor2; //(2)&&&&& console.writeline("我这里不会发生异常,我可以正常显示,我的值为{0}", dividevalue2);&&&&&&& //(3)这一行将被会正常执行。&&& }&&& catch(exception e)&&& {&&&&& console.writeline("传递过来的异常值为:{0}", e);&&& }&&& finally&&& {&&&&& console.writeline("无论是否发生异常,我都会显示。");&&& }}}
我们再更改一下上面的例子:
如果去掉上面的try...catch语句,直接编写程序,结果会怎样呢?
public class divisoriszero{private static void main(){&&& int dividend = 10;&&& int divisor1 = 0;&&&
&&& dividevalue = dividend / divisor1;
}}执行后发现,提示未处理异常,试图除以零的错误信息。
对比前后的结果可以发现,前面的代码由于进行了异常处理,程序不会中断执行,而是将异常作为程序的一部分来执行。后面的代码没有进行异常处理,导致代码执行期间遇到异常时,终止程序执行,提示错误信息。搜索此文相关文章:异常处理-采用trycatch语句结构来捕获和处理异常此文来自: 马开东博客
网址: 站长QQ
C#异常处理-采用trycatch语句结构来捕获和处理异常_博客园相关文章
博客园_总排行榜
博客园_最新
博客园_月排行榜
博客园_周排行榜
博客园_日排行榜您现在的位置: &
使用try/catch捕获异常
使用try/catch捕获异常
  在C++中,提供了语句try/catch来捕获异常,其中,try和catch分别用于定义异常和定义异常处理。定义异常是将可能产生错误的语句放在try语句块中。其格式是:try
  可能产生错误的语句
  定义异常处理是将异常处理的语句放在catch语句块中,以便异常被传递来时处理。通常,异常处理是放在try语句块后的由若干个catch语句组成的程序,其格式是:
  catch(异常类型声明1)
  异常处理语句块1
  catch(异常类型声明2)
  异常处理语句块2
  catch(异常类型声明n)
  异常处理语句块n
  例如,下列语句使用try/catch捕获异常,并定义捕获后对异常的处理。
  string str = null; //定义字符串对象
  ProcessString(str); //执行某个函数
  catch (Exception e) //定义对异常的处理
  cout&&“Process is error”;
  exit(1); //异常退出程序
  提示:在使用catch语句定义对异常的处理时,其中
&&&主编推荐
&&&热门试卷
&&&最新视频
&&&热门阅读
&&&最新问答
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&&&湘教QS2-164&&增值电信业务经营许可证湘B2-加了try catch还是捕获不到异常? Java技术方案解决区 北风网
国内最权威的IT培训、技术网站,专注于为企业提供优秀IT人才 - powered by phpwind.net
查看完整版本: [--
。。。&&&&&&&&&&&&&&&if (toMappingName.ToUpper() == fromMappingName.ToUpper())&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&if (toProperty.GetSetMethod() != null &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& fromProperty.CanRead&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& toProperty.CanWrite)&&&&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&var fromValue = fromProperty.GetValue(fromEntity, null);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if (fromValue == null)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&try { toProperty.SetValue(toEntity, null, null); } //这句内部引发异常&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&catch { }&&&&&&&&&&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&toProperty.SetValue(toEntity, fromValue, null);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&}&。。。&&&&这句是上面引发异常那句的内部代码:&/// &summary&&&&&&&&&&/// 没有元数据文档可用。&&&&&&&&&/// &/summary&&&&&&&&&&[XmlIgnoreAttribute()]&&&&&&&&&[SoapIgnoreAttribute()]&&&&&&&&&[DataMemberAttribute()]&&&&&&&&&[EdmRelationshipNavigationPropertyAttribute(&ContentManagementModel&, &FK_CM_AdminUser_CM_AdminAnswer1&, &CM_AdminAnswer&)]&&&&&&&&&public CM_AdminAnswer CM_AdminAnswer&&&&&&&&&{&&&&&&&&&&&&&get&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference&CM_AdminAnswer&(&ContentManagementModel.FK_CM_AdminUser_CM_AdminAnswer1&, &CM_AdminAnswer&).V&&&&&&&&&&&&&}&&&&&&&&&&&&&set&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference&CM_AdminAnswer&(&ContentManagementModel.FK_CM_AdminUser_CM_AdminAnswer1&, &CM_AdminAnswer&).Value = //虽然上面那句加了try..catch,但异常还是在这里被直接抛出来了&&&&&&&&&&&&&}&&&&&&&&&&&}&异常详细信息如下:&用户代码未处理 System.ArgumentException&&&HResult=-&&&Message=无法检索关系“ContentManagementModel.FK_CM_AdminUser_CM_AdminAnswer1”的元数据信息。如果使用映射特性,请确保已在程序集中定义了关系的 EdmRelationshipAttribute。使用基于约定的映射时,无法确定分离的实体之间关系的元数据信息。&参数名: relationshipName&&&Source=System.Data.Entity&&&ParamName=relationshipName&&&StackTrace:&&&&&&& 在 System.Data.Objects.DataClasses.RelationshipManager.GetRelatedEndInternal(String relationshipName, String targetRoleName)&&&&&&& 在 System.Data.Objects.DataClasses.RelationshipManager.GetRelatedReference[TTargetEntity](String relationshipName, String targetRoleName)&&&&&&& 在 ContentManagement.Entity.EF.CM_AdminUser.set_CM_AdminAnswer(CM_AdminAnswer value) 位置 C:\Users\knife\Desktop\programbak\ContenManagement\ContentManagement.Entity\EF\ContentManagement.Designer.cs:行号 3362&&&InnerException:
试试在SetValue()方法加个异常处理
你不提供上下文,这是要怎么看?&看你的这个错误信息,你试着把SetValue的第二个参数设置为不为null看看呢!
这个问题最郁闷的一点是加了try..catch竟然挡不住这个异常,连捕获到捕获不到。我最终自己定义了一个attribute, 自己判断要复制的属性有没有attribute,如果有,这个属性值就是可以被复制,否则只有基元类型,值类型和string可以被复制,其它类型一律不复制,否则会有不可预知的错误,竟然try catch都失去了作用,难道这段属于非托管代码?
查看完整版本: [--
Powered by
Code & 2003-08
Time 2.958983 second(s),query:3 Gzip disabledYou can

我要回帖

更多关于 c 捕捉异常 的文章

 

随机推荐