首页  人才招聘  项目交易  BLOG  兴趣小组  图书  资讯  文章  下载  源码  网友作品  刻盘服务 

您所在位置:论坛首页 — 请教一个致命问题!
打印本页 保存页面
 请教一个致命问题!
有时保存表单,会出现:“致命错误:异常代码 C0000005”,点击对话框确定键后,系统就关闭了。这是为什么?
 回复人:addd 回复时间:2005-8-28 11:56:00
C0000005 錯誤發生的誘因主要分為四大類:
  1、獨立資料表格儲存載體的缺陷(主要體現在 VCX、VCT、SCX 和 SCT 上)。
  2、第三方監控性質的軟體。(如:防毒軟體在記憶體即時監控狀態下、詞霸軟體在全螢幕拾取模式下等);
  3、Visual Foxpro 自身程式碼的漏洞;
  4、硬體因素。
先說第一大類:
  同資料表格一樣,在 Visual Foxro 9.0 版本中,獨立資料表格也支援了異動交易機制,這並非主要是為了滿足客戶的需要,而是以穩定 VFP9 自身為主。我們都知道類別與表單的程式碼多以實體形式為獨立資料表格的 VCX、VCT、SCX 和 SCT 檔案格式儲存,在 IDE 設計模式下,程式碼被 VFP 後台以獨佔的、開放式獨立資料表格緩衝的模式存取。然而您應該敏感地注意到:獨立資料表格是不支援異動交易機制的(低於 9.0 版本的 Visual Foxro)。也就是說,遇到停電或作業系統異常時,它們同樣會面臨表頭損壞、低階鏈接錯誤、記錄指標錯誤偏移的風險。Microsoft Visual Foxpro 開發小組沒有將 VCX、SCX 設計為依賴於資料庫的資料表格的形式,原因不難理解——如果一個表單檔案中,包括表單本身在內的任何一個控制項都不依賴於使用者自定義衍生類別的話,那麼該檔案應該可以被獨立地拷貝與開啟。
  如下的常識我們都需要知道:
  無論是在設計模式還是在執行模式下,Visual Foxpro 的 Runtime 會隨時將客戶腳本讀取到記憶體中,並交由詞法分析器、語法分析器和語義分析器來分析、解釋、處理這些程式碼。(通常情況,在編輯模式下,我們的腳本程式碼已經被 Visual Foxpro 詞法分析器進行了第一遍的過濾;在編輯完一個 prg 或表單或類別檔案後,若按下 Ctrl+W 組合鍵將在儲存它之前呼叫語法分析器來試圖檢查其中的錯誤(注意「詞法」分析器與「語法」分析器的不同),然後程式界面將自動被關閉;而若按下
Ctrl+S 組合鍵儲存後,再手動退出時,這種情況下將不會呼叫語法分析程式。)
  如果你的腳本儲存在獨立資料表格形式的 SCX、SCT、VCX、VCT 檔案中,Visual Foxpro 會通過資料表格的記錄指標提取對應備註檔案裏的程式腳本(那裏或許包含了某些事件或方法程序的程式碼),Visual Foxpro 會通過呼叫 C 語言的 sizeof() 來判斷位元組的長度,根據長度提取位元組,最後將長度的傳回值與實際程式碼以參數的形式傳遞給語義分析器來解釋執行。然而在一些情況下,會發生 sizeof()
判斷的位元組長度與實際的長度不一致的情況。
  倘若 sizeof() 判斷的位元組長度與實際的長度不一致,將會發生記憶體的溢出,這個致命錯誤被Visual Foxpro 異常處理器捕獲後,將拋出「致命錯誤-C0000005」的訊息。
  「致命錯誤」是字元常量,「C0000005」是一個變數,C0000005 不是 VFP 的錯誤編碼,而是得到Windows 訊息環境所傳遞過來的錯誤訊息的半加工品。它的原始狀態是 16 進制的 0xC0000005,VFP 通過相關的轉換函數轉換成字串的形式,以便通過界面描述給使用者。
  那麼什麼情況下會出現 sizeof() 判斷的位元組長度與實際的長度不一致的情況呢?主要有兩方面的主導因素。
  1、我們前面敘述過了,VCX、VCT、SCX 和 SCT 檔案都是獨立資料表格,都有可能在設計時被無意的損壞。 倘若表頭被損壞,您會在試圖開啟它們的時候收到 VFP 系統的無法開啟該表單的訊息;但倘若低階鏈接錯誤、記錄指標錯誤偏移,您就不會得到任何 VFP 的提示,因為 VFP 系統自己也不知道這一點,就像您一樣。於是直到程式執行時,才會收到令人驚愕的致命錯誤訊息——語義分析器工作時記憶體被溢。
  在一些「致命錯誤-C0000005」的訊息框中,您會收到似乎更詳細些的訊息,指示您程式出錯的地方。那通常是包含在 SCX、SCT 或 VCX、VCT 裏某些行的程式碼。
  千萬不要被誤導,並不是您的程式碼編寫有問題,而是隱藏在標識符之外的、看起來好像是空格、歸位的空白段,那裏隱藏了低階鏈接的錯誤、或 Unicode 的錯位排序(下面馬上就會講述到),用Shift+方向鍵 將整行全選,然後按 Delete 鍵刪除之,最後老老實實地將原行程式碼重新書寫一遍即可(切記:用 Shift+方向鍵 將整行全選,然後將該整行徹底清除)。
2、Unicode。
  從 Windows 98 升級過來的 VFP 程式人員似乎都曾有過這樣的困惑:為什麼 Windows 2000 以上版本的 VFP 程式會如此的不穩定,以至於頻繁出現「致命錯誤——C0000005」? 您現在上網用的電腦的作業系統是 WIN2000 或 Windows XP 嗎?如果是,不妨親自做這樣一個試驗:
  開啟記事本程式,輸入「聯通」,然後儲存後關閉該文字,再重新開打,看到什麼了?
  是的,當年 WIN2000 作業系統的流行時,Visual Foxpro 開發小組並沒有徹底改正語義分析器程式碼的漏洞。
  好的,第一大類我就闡述完了。如何避免它呢?
  總的應該說很麻煩,有兩種途徑供您選擇:1、修改 VCX、SCX 資料表格國際字碼頁的編碼,將簡體中文編碼改為英文編碼;
  2、我所推薦的方法是盡量用 prg。你可能會認為這樣做很麻煩,但作為程式人員,您應該更加專業一些。您可以備份可視化的表單或類別檔案,但在程式正式發佈前,最好最大限度地轉化為 prg 程式。倘若以後需要修改程式,通過備份的表單或類別檔案進行可視化編輯,然後再次轉化為 prg 發佈之。
順便告訴您一個小竅門:
  在 IDE 設計模式下,我們或許會突然遇到「致命錯誤-C0000005」襲擊,因為表單是以獨佔的、開放式獨立資料表格緩衝的模式交互的,所以此前未經儲存的訊息都將被丟失,這您是知道的,通過剛才的講述,您還知道了這或許會面臨資料表格被損壞的風險,從而進入了一個「致命錯誤-C0000005」潛在引發今後「致命錯誤-C0000005」故障的惡性循環。

 
 回复人:addd 回复时间:2005-8-28 11:57:00
小竅門就是,您千萬不要條件反射地去觸擊那個「確定」按鈕!那不過只是 Visual Foxpro 系統所捕獲的異常罷了,它不是真「致命」的,Visual Foxpro 系統仍在運轉中,也就是說,它還在正常地接收著 Windows 作業系統不斷發送來的訊息。這時,請您點開 Windows 桌面最左下角的「開始」按鈕,選擇「重新啟動電腦」或「關閉電腦」,Windows 在試圖關閉電腦前,會先檢查是否有尚在執行中的應用程式,它會發現一個叫 Fox 的先生尚未退場,於是便發送清場的訊息給 Foxpro,Visual Foxpro 其實還在正常的運轉中,它接收到這條訊息後,會呼叫自身的退出機制試圖退出,而自身的退出機制會發現尚有正在編輯的表單,便會發出「需要儲存修改嗎?」的詢問訊息,這時候,您選擇儲存,就可以了!
千萬注意了!這段過程大概只有 5 秒鐘的時間!因為為了防止死循環的情況出現,Windows 會在等待幾秒鐘對方不回應的情況下強行終止程式,那時候,就真正退出整個 Windows 系統了。所以您一定要眼疾快!
  (說到異常處理,便自然地想到了 Vfp9 新加的異常處理 TRY 機制(事實上是 8.0 開始有),事實上倘若不是開發 OLE 遠程服務的 DLL,您就沒有必要就使用它。因為 VFP 為您提供的 ON ERROR 命令或 ERROR 事件,其腳本解釋程式碼實質上就是 C++ 的異常處理機制,在您熟練地使用 VFP 錯誤處理程式時,實際上就等於在使用 C++ 的異常處理程式了。)
  第二大類是第三方監控性質的軟體。如:防毒軟體在記憶體即時監控狀態下、詞霸軟體在全螢幕拾取模式下等。其實防毒軟體本身並不與 VFP 產生衝突,但有一個例外,就是記憶體即時監控(請注意:
防毒有許多即時監控,唯有記憶體即時監控才會與有時候與 VFP 發生衝突)。
  所謂記憶體即時監控並不是去讀取記憶體中的資料,誰也沒這麼大的本事,它的原理就是專門關注於 Windows 系統目錄下的 system32 子目錄中的程式檔案在執行中的狀態。
  我們知道,在Visual Foxpro 8.0 版本以前,其執行時期檔案是安裝在 system32 目錄中的;而向最終客戶發佈你的應用程式時,預設情況下,無論是 VFP 什麼版本,其執行時期檔案均會被拷貝到system32 目錄中去。
  防毒軟體的記憶體即時監控的工作原理是這樣的(這是瑞星公司首創的,瑞星軟體也是狐友受害最深的):1、它會在 Windows 後台執行一個類似於 Windows 的模擬機(這有點像任天堂遊戲模擬機和一些手機模擬機,還有現在時髦的 Linux 下的 Windows 模擬機);2、它執行一個循環,逐個監視system32 目錄下的 exe 及 dll 檔案是否被呼叫;3、倘若被呼叫,就拷貝一份到瑞星自己建立的隱藏、系統目錄中去,然後在那個模擬機中執行之,以便模擬其在 Windows 實際執行中的狀態;4、在
模擬執行中,看它是否有病毒發作的特徵;5、如果有,就尋找病毒特徵碼資料庫;6、若在資料庫中,找到了對應的特徵碼,便確定特徵碼所對應的病毒名稱,否則,就按未知名的新病毒處理(這就是為什麼有的 VFP 加密軟體會被防毒軟體誤報病毒)。
  由於 VFP 應用程式與執行時期 DLL 函式庫交互的太頻繁了,使防毒軟體的那個循環程式不斷捕捉到 VFP 執行時期函式庫在進行新的資料回應,防毒軟體便不斷地試圖拷貝它,以便進行新一輪的模擬。但你知道,無論是 DBF 還是 SCX 等等,只要是獨佔方式開啟的(SCX 與 VCX 總是被獨佔的,而DBF 取決於你的設計),就不能被其它的程式所存取。但在 Windows 作業系統中,防毒軟體所呼叫拷貝程式的系統優先等級要高於你的程式的優先等級,所以你的 VFP 程式會最終產生致命錯誤。
  如何避免它呢?你可以簡單地關閉防毒軟體,但如果讓客戶也像你這樣做的話,就顯得太不專業了!
  聰明的你恐怕現在已經想到了:只要在發佈你的應用程式時,將那些執行時期庫放到應用程式目錄下就可以了!
  同樣,詞霸軟體本身也不會與你的程式發生衝動,只是在全螢幕取詞的模式下才會如此。不過你的使用者幾乎不會遇到,因為你的程式幾乎不會讓他們在程式界面狀態下直接開啟某個資料表——僅在詞霸的全螢幕取詞程式試圖通過獨佔模式下的資料表的視窗控制碼,來存取裏面的文字屬性時,才會與其獨佔模式發生衝突。
  第三大類是 Visual Foxpro 自身的程式碼漏洞。比如 VFP6.0 版本的 Textbox 控制項等等。現在版本的 VFP,這樣的錯誤少多了,我們的話題就不再展開。
  第四大類是硬體因素。
有些細節問題是最不被人所注意的。但其足以鑄成大過。
  「致命錯誤 C0000005」是記憶體洩漏的症狀,而不僅僅是記憶體溢出,還有一個原因就是申請到的堆疊意外不足。
  在用電高峰期(例如夏季、或晚間的黃金時段),電壓的突然不穩定,或許會非常微小,不至於迫使電腦意外重啟,但或許會導致 VFP 系統在通過 Windows 訊息機制向記憶體體申請堆疊時,得到 Windows 意外的反饋。
  除了說服您的客戶使用UPS外,您應該檢查用電的負荷情況,比如檢查印表機或檯燈是否與電腦電源線一起接在一個多功能插座上,應該盡量避免這樣,一些老式的印表機,在列印作業時會消耗很大的電流。
 
 回复人:labxj0769 回复时间:2005-8-28 14:42:00
我使用VFP只知道VFP9.0最稳定,以前有楼主错误的程序在VFP9.0中重编EXE就解决了
不知其所以然,楼上的说得明白,楼主可要记得给他加30分
 
 回复人:ljp727579 回复时间:2005-8-30 20:44:00
可是我不知怎么为各位楼兄加分!请赐教!
 
广告
 

关于本站 - 网站导航 - 联系站长 - BUG报告 - 友情链接 - 赞助本站
Copyright© 1999-2012 Programfan.com. All Rights Reserved
论坛制作&维护:Hannibal    Email: webmaster@pfan.cn
-