2014-08-28 95 views
3

我有一個Tkinter應用程序,有時在Windows下崩潰。該錯誤是一個通用的'程序已停止工作,需要關閉'。調試windows上的tcl崩潰

檢查事件日誌後,我發現tcl85.dll是導致崩潰的庫。

我的猜測是我的程序中有一個錯誤,它會濫用tcl api並導致tcl進入未定義狀態,最終導致崩潰,或者tcl85本身存在錯誤。

我的問題是,我該如何診斷這個問題的原因?哪些工具可以幫助在程序出錯的地方獲得回溯?我檢查了Windows事件日誌中的錯誤,但那裏的信息似乎不足以識別原因。

以下是事件日誌錯誤的XML:

Name="Application Error"></Provider> 
<EventID Qualifiers="0">1000</EventID> 
<Level>2</Level> 
<Task>100</Task> 
<Keywords>0x0080000000000000</Keywords> 
<TimeCreated SystemTime="2014-08-27 08:54:13"></TimeCreated> 
<EventRecordID>6173</EventRecordID> 
<Channel>Application</Channel> 
<Computer>my.windows.8.tablet.computer</Computer> 
<Security UserID=""></Security> 
</System> 
<EventData><Data><string>my_tkinter_app.exe</string> 
<string>0.0.0.0</string> 
<string>514e2c2f</string> 
<string>tcl85.dll</string> 
<string>8.5.2.15</string> 
<string>53b1e888</string> 
<string>c0000005</string> 
<string>0007697f</string> 
<string>1378</string> 
<string>01cfc1d44828ecb0</string> 
<string>C:\Users\ADMINI~1\DOWNLO~1\my_tkinter_app.exe</string> 
<string>C:\Users\ADMINI~1\AppData\Local\Temp\_MEI35042\tcl85.dll</string> 
<string>b7745a30-2dc7-11e4-9732-88124e8c7600</string> 
<string></string> 
<string></string> 
</Data> 
<Binary></Binary> 
</EventData> 
</Event> 

c0000005據我瞭解,有一個訪問衝突,但是這仍然是過於籠統,以確定原因。

不幸的是,我無法重現Linux下的崩潰,所以我正在尋找一種跟蹤此問題的特定於Windows的方法。

+0

什麼應用? – 2014-08-28 08:15:08

+0

我覺得很難說。它是你自己包裹的應用程序嗎?也許被包裝的庫不適合windows;我嘗試使用Tclkit來創建一個exe文件,並且有不同的文件用於不同的操作系統;和一個我認爲能夠在Linux和Win OS上工作的starpack。我只是說它可能有點相似。 – Jerry 2014-08-28 08:32:38

+0

它更可能是API濫用,但不保證。訪問衝突是___可能_ NULL空引用___。 – 2014-08-28 09:32:25

回答

1

如果您有涉及Tcl的PDB文件(例如,因爲您自己構建了它),最簡單的方法就是在進程崩潰時簡單地指示Windows安全地使用MiniDump。

Windows錯誤報告(WER)系統具有執行此操作所需的部分,您只需設置一些註冊表項並查找生成的.dmp文件即可。

看一看http://msdn.microsoft.com/en-us/library/windows/desktop/bb787181%28v=vs.85%29.aspx爲需要的東西:

一旦你的崩潰轉儲,你只需用你的選擇(Visual Studio或WinDBG的)的調試器中打開它,並開始調試,它指向您的PDB文件和Microsofts Symbol服務器,並獲得崩潰的不錯堆棧跟蹤。

1

我在安裝了Python 2.7.9的Windows 7桌面上出現了相同的錯誤,而這在我的程序中顯然是一個線程安全問題。我不確定您的問題是否可以通過我的解決方案解決,只需分享。

對於所有在其他(主要)線程中運行tkinter的人,tkinter是不是線程安全。在我的程序中,我必須在主線程中運行扭曲的反應堆,所以我在另一個線程中運行tkinter UI。由於我在主線程中直接調用tkinter方法(如Text.insert()),它偶爾會與c0000005錯誤一起崩潰。

讀取this bug report後,我修改Tkinter的基於UI模塊:

  1. 添加的命令隊列,以特定微件(文本窗口小部件,在我的情況)
  2. 添加了一個處理程序方法與after()queue.get_nowait()如下所示:

    def commandQueueHandler(self): 
        try: 
         while 1: 
          your_command = self.textCommandQueue.get_nowait() 
          if your_command is not None: 
           # execute the command .... 
          self.Text.update_idletasks() 
        except Queue.Empty: 
         pass 
        self.Text.after(100, self.commandQueueHandler) 
    

    此方法每100ms自觸發一次以處理隊列中的命令,但必須觸發它一旦使其工作。 (我觸發這__init__,所有的部件被初始化後)。

在主線程,所有我需要做的只是把命令/消息中的命令隊列,等待它來處理。當然,在命令執行之前會有一點延遲。

就是這樣!通過這種修改,我的程序在2周的壓力測試後沒有運行tcl c0000005錯誤。希望這可以幫助。

p.s.要小心,只有窗口小部件類提供after()方法,check this page for details

+1

@JasonMArcher,非常感謝!雖然我的具體問題(及其最終解決方案)與此不同,但您可以將我的關於線程安全和tkinter的信息放在正確的軌道上。 (基本上,我有一個可靠的工作程序 - 幾乎每次都會崩潰 - 我看不出他們之間有什麼實質性的區別來解決這個問題。根據你的答案,我追蹤了它:後者在一個單獨的線程中做了一些額外的不必要的tkinter雜技,一旦我簡化了它,它就完美了。) – JDM 2016-01-20 15:46:09