2012-08-15 33 views
2

我在德爾福7 Service應用程序,印第安納波利斯,突觸,Zeolibs等使用了很多組件如何處理掛在Delphi中的第三方函數或線程?

我的應用程序一般是穩定的,我用Eurekalog 6捕捉異常,但在極少數情況下,一些線程掛起,因爲它所調用的第三方功能已掛起,例如Indy在嘗試發送電子郵件時被卡住了。

在很多情況下,掛起的應用程序是我的客戶,我無法訪問他們的計算機,所以我不可能進行實時調試。我的應用程序需要高可用性,所以即使它每年掛起一次,這對我的用戶來說也是不能接受的。

我現在正在尋找處理這種情況的最佳方式,即調試不可行,但我仍然需要自行恢復應用程序。如果一個線程被調用的函數掛起,它可能會終止嗎?或者,我也可以在發生這種情況時重新啓動整個服務。看門狗如何以及實施它的最佳方式是什麼?謝謝。

+1

看看madshi的[madExcept](http://madshi.net/madExceptDescription.htm)。它將允許您的應用程序或您的用戶發送整個堆棧跟蹤並檢測掛起的主線程。任何其他掛起的線程,你應該能夠編碼。 – 2012-08-15 16:49:02

+0

有關處理線程中的異常的信息,請參見[Delphi線程異常機制](http://stackoverflow.com/q/3627743/576719)和[如何處理TThread對象中的異常](http://edn.embarcadero.com /條/ 10452)。 – 2012-08-15 16:49:52

+0

@LURD在線程中處理異常有什麼特別之處?當然,任何線程,主線程或工作線程的異常處理都是一樣的? – 2012-08-15 18:22:19

回答

10

我認爲你是相當的失敗主義者。找到並修復錯誤。這可能會很棘手,但它是正確的解決方案。

殺死你不明白的線程永遠不是解決方案。如果你開始殺死線程,你可能會讓事情變得更糟。這可能會導致其他運行時錯誤,死鎖等。一旦你開始殺死線程,你失去了控制權。

現在,殺死進程(而不是特定線程)並依靠看門狗服務重新啓動進程將是安全的。但這是一個非常可怕的解決方案。

您當然應該使用像madExcept,EurekaLog等工具來調試意外的異常。我看到你已經在使用EurekaLog--這很好。

死鎖(它聽起來像你有死鎖)可能會更棘手追逐。調試死鎖的一個好方法是讓客戶端產生崩潰轉儲(例如來自Process Explorer)。然後使用map2dbg在WinDbg中調試它以生成符號堆棧跟蹤。這將告訴你哪些線程阻塞,並揭示死鎖。然後修復這些錯誤。

有關這一僵局調試技術的更多詳情請看這裏:http://capnbry.net/blog/?p=18

我不熟悉EurekaLog因爲我用madExcept,但我希望EurekaLog有一個工具來實現生成線程的堆棧跟蹤的一個紅處理。如果是這樣,那很可能是最適合你的方法。

+0

殺死線程肯定是解決方法,而不是解決方案。然而,這種解決方法並不是沒有意義。如果第三方庫導致死機,那麼找到沒有機會調試的錯誤是相當棘手的。如果他的數據結構完全是線程本地和孤立的,那麼殺死線程並不是非常危險的。相反,根據「在存在軟件錯誤的情況下製作可靠的分佈式系統」,有時候再試一次就是一種解決方案。有時候不是。那麼在應用程序重啓之前,他會發生級聯故障。 – 2012-08-16 09:01:43

+0

@arioch如果要殺死的線程完全隔離,那麼除了堆內存泄漏之外,它是安全的。但是,無論如何,最可能的錯誤都在OP的代碼中。如果不調試libs並不難。這些庫隨源代碼提供。 – 2012-08-16 09:42:51

+0

@David Heffernan - 你說得對,我正在談論僵局。他們不經常發生,但我的應用程序有時用於關鍵任務場景。 Eurekalog已經可以捕獲所有未處理的異常,但有些情況下沒有異常但應用程序被鎖定。我正在探索如何最好地實現看門狗,因此如果有線程掛起,看門狗將重新啓動進程。爲了您的信息,我已經在服務中使用了一個看門狗定時器來重置我創建的外部看門狗服務,但這對掛起線程不起作用 - 它只在定時器(整個服務)掛起時才起作用。 – Joshua 2012-08-16 10:48:33

2

你的問題太含糊。如果你不知道你所使用的各種組件中哪一個是你想要指責的,那麼你沒有希望修復它。最有可能的是你做錯了什麼,或者你不明白這些組件是如何工作的。我非常懷疑,這純粹是組件本身的錯誤,但是,無論如何,無論是哪種方式都可以找到有什麼問題,以及解決問題的工作。

您創建的僵局或發生的深層過程損壞問題可能會阻止MadExcept向您提供任何信息,但值得嘗試。

要找出哪一個是凍結的,如果有的話,那麼madexcept的評論是最好的建議呢。它會超時(在可配置的秒數之後),併爲您提供一個人爲的例外,從而中斷您的掛起進程。這適用於用戶代碼,以及在Win32或內核函數中阻塞該線程的位置。例如,您可能已經爲Indy設置了無限超時,因爲這是Indy 10中的默認設置,並且您所遇到的是超時相關的凍結,您希望完成的網絡活動,但永遠不會將完成,導致你的程序「掛起」。這裏的治療方法是改變你的超時時間。

但是,直到你找出問題所在,我懷疑你能解決它。所以,爲此,馬庫斯是對的,你應該看看madExcept。沒有它,我無法生活。其次,你應該真的在你的程序中添加跟蹤邏輯,所以你知道它在哪裏發生了什麼,以及它在出現問題之前做了什麼。如果你確實需要幫助,你可以試試Raize的CodeSite。就我個人而言,我發現OutputDebugString與免費的微軟DebugView實用工具(以前來自SysInternals)工具相結合足以在客戶端計算機上調試這些問題。

任何程序後臺線程沒有跟蹤記錄,是一個設計不好的程序。哎呀,任何可能失敗或有問題的非平凡單線程應用程序都需要跟蹤日誌記錄。

即使MadExcept或其他異常工具沒有,日誌記錄也會幫助您。跟蹤記錄通常是一個自己的解決方案,儘管CodeSite也很受歡迎。

+0

我衷心贊同CodeSite和SmartInspect是supberb調試工具。如果OP在調試時遇到了很多麻煩,我推薦使用這些工具之一。我使用SmartInspect,但都是同樣好的IHMO。 – 2012-08-16 08:29:43

相關問題