2009-12-10 41 views
3

我有類似的代碼(不是我寫的)C#的try/catch惡夢

try 
{ 
    EnumerateSomeCoolHardwareDevice(); 
} 
catch (Exception ex) 
{ 

} 

UPDATE一個應用程序 - 這是.NET C#& EnumerateSomeCoolHardwareDevice()使用的SerialPort?

我知道這段代碼有多糟糕,但它的工作原理是這樣的!

我的問題你:我可以看到它在某處EnumerateSomeCoolHardwareDevice崩潰();但它不會被Catch捕獲(...) - 它只是與發送報告對話框一起崩潰!這目前也只發生在發佈版本中...是他們爲什麼我的異常不會被catch(...)捕獲的任何原因?

+5

如果您讓我們知道您使用的是哪種語言,因爲所涉及的運行時系統將對答案產生影響,這可能會有所幫助。 – 2009-12-10 09:36:50

+0

對不起,更新了問題狀態C#(.NET) – rudigrobler 2009-12-10 09:51:26

+0

它是*可能* EnumerateSomeCoolHardwareDevice()調用Environment.FailFast(http://msdn.microsoft.com/en-us/library/ms131100.aspx)這是原因。您可能需要將某些內容附加到應用程序日誌中,以將數據輸出到可用文件中以檢查是否屬於這種情況。 – RCIX 2009-12-10 09:55:24

回答

8

我的猜測是,你沒有得到你的語言/框架的一個異常,而是EnumerateSomeCoolHardwareDevice()做奇怪的事情,僅僅導致操作系統殺死你的進程。請記住,硬件細節是由像Java和.NET這樣的框架抽象出來的,因此,無論何時直接使用硬件做某些事情,您可能都依賴於非託管資源......並且無論出現什麼問題,都可能會殺死您,無論是否被捕獲。

0

EnumerateSomeCoolHardwareDevice()內可能有try..catch。

如果異常被捕獲並在那裏處理,除非異常再次拋出,否則外部異常不會被命中。

+0

但隨後如果異常被捕獲那就不是一般炸燬。 .. – RCIX 2009-12-10 09:53:21

0

(假設的Java)兩個錯誤和異常是Throwable子類。例如,如果EnumerateSomeCoolHardwareDevice()中存在斷言失敗,您將收到錯誤消息。

2

假設.NET,如果EnumerateSomeCoolHardwareDevice通過PInvoke的使用的Win32方法(訪問硬件)和發生錯誤時,大多數本機方法返回錯誤代碼。如果沒有處理該錯誤代碼,並且無論如何都調用了另一個本地方法(可能是調用失敗的參數爲空),則嚴重的本機錯誤(例如內存訪問不良或類似情況)可能導致程序崩潰,並且沒有例外拋出。

1

如果它只發生在生產機器上,而不是發生在機器上,那麼它可能會導致DLL不匹配。仔細檢查所有引用的DLL和框架是相同的版本。

其次,如果錯誤沒有被EnumerateSomeCoolHardwareDevice()拋出,那麼它將會崩潰應用程序,因爲根據我的經驗,沒有辦法讓異常返回棧(或者說我對try/catch的理解)這發生在我以前。

最後,微軟的錯誤報告通常允許你檢查什麼將被髮送到MS,這應該讓你看到那裏的錯誤發生了,爲什麼(假設它在其內具有可讀信息)。

檢查事件查看器,因爲錯誤也應記錄在那裏,並且通常會提供關於錯誤的寶貴資料來源,並且通過在列出的錯誤中挖掘一點,您應該能夠追蹤錯誤。

0

我的猜測是發生了堆棧溢出。這個。NET VM簡單地關閉遇到堆棧溢出的發佈構建過程,不會拋出CLR異常。這個函數內部可能有一個內部的try/catch函數,它以某種方式捕獲StackOverflowException,這就是爲什麼它不會傳播到Debug中的代碼。

弄清楚發生了什麼事情最簡單的方法是通過使調試版本,安裝調試和指導調試器打破拋出之前任何異常(在Visual Studio中,調試/異常,並勾選「時拋出」爲「Common Language Runtime Exceptions」以及可能還有其他問題,在cordbg.exe「catch exception」中)

0

如果它瘋狂地崩潰並且正在使用SerialPort對象,那麼可能是因爲它在某個時候跳到了背景線程和異常發生在這裏。 IIRC .DataReceived事件或者您從串口獲取信息返回後臺線程上的數據。如果在例程中拋出異常,那麼整個應用程序將保釋。

找到後臺線程並對其進行一些異常處理。

7

一個可能的原因是如果EnumerateSomeCoolHardwareDevice()函數使用線程。如果在線程中拋出異常並且未在其線程中處理異常,則可能會導致應用程序崩潰。這個簡單的應用程序可以證明我的意思:

public static void testThread() 
    { 
     throw new Exception("oh god it's broken"); 
    } 

    static void Main(string[] args) 
    { 
     try 
     { 
      Thread thread = new Thread(testThread); 
      thread.Start(); 
      Console.ReadKey(); //Just to make sure we don't get out of the try-catch too soon 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 

如果您運行的應用程序將和好如初,而不是捕捉如您所料除外。

+0

我會把錢放在這個人的錯誤是由此造成的。 – Quibblesome 2009-12-10 11:00:18

2

你有沒有嘗試過的屬性

總成:RuntimeCompatibility(WrapNonExceptionThrows =真)

這應該換任何non-.Net異常轉換成的System.Exception所以它會在你的代碼被逮住。

1

如果你在.NET版本1.1使用一個無參數趕上像

catch{ 
... 
} 

塊之前到.NET 2.0有可能是不從System.Exception派生本地例外。

還掛鉤到應用程序域unhandled exception事件,看看會發生什麼。

0

您看到哪些類型的異常以這種方式表現?你有他們的清單嗎?

一些例外情況會繼續支持調用堆棧,即使它們已被捕獲到,例如ThreadAbortException

其他基本上不可處理,例如StackOverflowExceptionExecutionEngineException

如果是這些(或其他一些我可能錯過的)之一,那麼行爲可能與預期相同。如果是其他人,那麼更深入瞭解更多信息將是必要的。