2011-03-03 34 views
13

因此,在最近發生的一些變化之後,我們發現我們最早的應用程序有時會在關機時崩潰。這會以「運行時錯誤216」消息的形式或Windows錯誤報告中的消息顯示應用程序已停止工作。該應用程序已經發出OutputDebugString-每一回合的消息和AFAICT我們自己的所有代碼正確執行完成。所有的析構函數都被調用,就像所有的終結節和類的析構函數一樣,其中沒有一個引發任何異常。如何調試僅在應用程序關閉時發生的崩潰? (Delphi)

此外,MadExcept和FastMM4的完整調試模式似乎都沒有什麼可抱怨的(儘管這可能是一個錯誤的結論,因爲即使在這些組件自己的最終代碼運行之前崩潰也可能發生)。

那麼,你會怎麼做?你會從哪裏開始?


這個問題應該是更多的一般方法這一類的問題,而不是針對我目前正面臨着這樣的特定實例,我特意留出的細節。隨意問你是否認爲它們可能與調試方法的選擇有關,我將在稍後添加它們。

+4

有一個VCL錯誤,在關機時顯示爲AV。這與'所有者'形式的破壞有關。我通過在'Application.Run'之後明確關閉.dpr文件中的表單來解決這個問題。如果讓'Application'爲你完成關閉,則可能會出現陳舊引用的問題。 – 2011-03-03 13:54:48

+0

@David:這聽起來很有趣。你有一個質量控制編號嗎?但是,除了主窗體之外,我使用各自的父窗體作爲所有者在代碼中創建了所有窗體。你所說的問題是否也適用於這種情況? – 2011-03-03 13:59:54

+0

如果你依賴破壞應用程序來將其他所有東西都關閉,那麼我正在討論的錯誤可能適用。嘗試在您的.dpr文件中放入一個'MainForm.Free'。我會看看QC編號。 – 2011-03-03 14:08:05

回答

2

您可能會遇到指針問題。某些事件或方法試圖在不再存在的對象上運行。

+0

是的,這就是「運行時錯誤216」或多或少所暗示的,但問題是如何去追蹤這個問題呢? – 2011-03-03 13:27:43

+0

如果您可以可靠地重現它,那麼您可以使用調試器(您需要調試DCU)來確定它發生的位置。不幸的是,我認爲你可能會在它提出的點上有一個非常絕望的堆棧跟蹤。 – 2011-03-03 13:56:27

+0

@David:這個問題的「可靠再現」仍然是一個問題:我認爲它發生在大約60%的時間。而且我還沒有能夠確定工作會議和非工作會議之間的區別。我實際上已經認爲我已經修復了這個問題幾次,只是爲了讓它再次發生幾個會話... – 2011-03-03 14:04:54

3

那麼Runtime error 216是內存問題(Access violation),它看起來像你引用某個對象,在那個時間點不存在。

Emarcadero寫道:使用該sysutils的類圖最運行時錯誤例外,它允許您的應用程序來解決該錯誤不終止

應用

你嘗試在定稿設置breackpoint Sysutils的一部分?

我會試一試Allocation/Memory Profiler,它不確定你會找到錯誤代碼行,但這可能會顯示你的代碼中存在內存問題的部分內容。

5

您使用的是運行時軟件包嗎?我以前見過類似的問題。如果您跨包邊界共享全局變量或接口,則必須確保在卸載該包之前,清除所有屬於某個包的類的引用;否則他們會嘗試將虛擬呼叫轉換爲不再有效的內存。

+0

哦,是的,不僅運行時包,而且COM-DLL(即插件)依賴於這些包(正如主機EXE一樣)。不要問。我今天不會再這樣做,但它已經運行了十多年了......儘管我會仔細檢查一些全球單身人士的參考資料。這確實聽起來很有希望...... – 2011-03-03 14:18:05

+2

「現在運行十多年了」已經發生了什麼變化?這可能是我如何解決這個問題。 – 2011-03-03 14:43:46

+0

Touché! ;)這對於一個被接受的答案來說已經足夠好了。 :-P – 2011-03-03 17:17:20

12

運行時錯誤216意味着您有Av(訪問衝突)並且SysUtils已經停止將這些錯誤轉換爲異常。

首先嚐試:使用調試DCU構建並查看引發錯誤的單元系統,在那裏設置一個斷點。希望你可以在調試器中捕獲它並從那裏開始工作。

你可能有一個內存錯誤(dangling指針,null引用等等,在已經完成的單元中使用s串常量),最好的訣竅是在sysutils完成後檢查最終的結果。您可以通過構建WITH debug dcu's來完成此操作,將斷點設置爲sysutils中的終結點並開始逐步執​​行代碼,直到發生錯誤。

2

「運行時錯誤216」來自Windows本身,而不是Delphi異常處理程序。我發現它是由在Delphi的異常處理程序啓動之前執行的單元的初始化和結束化部分中運行的代碼引起的。特別是。在Delphi應用程序終止後需要通過運行的終止代碼卸載的COM對象將導致此錯誤和類似的錯誤。所以檢查那些東西。

MNG

+3

不完全:在單元系統中查看:函數MapToRunError將NT錯誤代碼STATUS_ACCESS_VIOLATION映射到ErrCode:= 216。 – 2011-03-03 20:40:26

+0

感謝您的評論 - 無論如何,這發生在默認Delphi應用程序異常處理程序初始化之前或之後。單元在Delphi應用程序啓動之前基於uses子句加載,在應用程序終止後卸載 - 初始化和終止部分在單元加載和卸載時運行,因此在那裏運行的代碼不由Delphi應用程序異常處理程序處理。這就是爲什麼你得到一個神祕的'運行時錯誤216'或217,並沒有異常消息'Eaccess違反.. @'等 – user643124 2011-03-04 14:17:21

+1

這是不正確的;在異常處理機制斷開之後,216來自Delphi RTL。這是德爾福的方式告訴有一個AV。 216不是窗體。 – 2011-03-04 16:02:13

2

與其他人一樣說:216是指AV後SysUtils單元被關閉。通常,SysUtils之後關閉的唯一東西(並且有機會升級AV) - 就是系統單元。具體來說:內存管理器

因此,關機時的運行時錯誤216通常意味着內存損壞應用程序中的錯誤。

這可以很容易解決 - 只需在內存管理器中啓用完整調試模式或使用調試內存管理器。然而,有時候,它可能很難找到。但是您可以先從MM的調試模式開始。

請參閱this article

相關問題