2014-08-28 93 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